def message_updates(env,start_response):
  """
  handles clients long polling,wait for updates and return them or timeout
  """
  #parse request,looks like ?client_id=....&client_id=....&callback=...
  qs = parse_qs(env['QUERY_STRING'])
  #client_id is client_id;key
  client_ids = [id.decode('utf8') for id in qs["client_id"]]
  callback = qs["callback"][0]
  try:
    cursors = []
    clients = [get_client_with_key(client_id_key) for client_id_key in client_ids]
    #get the updates,blocks if no updates found
    updates = get_updates(clients)
    #if updates found update the clients cursors
    for client in clients:
      client.update_cursors(updates)
    start_response('200 OK', [('Content-Type', 'application/x-javascript'),('Cache-Control','no-cache'),('Access-Control-Allow-Origin','*')])
    #generates the response like: callback({"channel_1":[[message],[message]],"channel_2":[[message]]})
    return "".join([callback,"(",dumps(dict((channel_name,[[message.id,message.message,message.client_id] for message in messages]) 
                                                                                  for channel_name,messages in updates.iteritems())),");"])
  except __HOLE__:#one of the clients doesn't exists
    start_response('404 Not Found', [('Content-Type', 'text/plain')])
    return "Not Found\r\n"
dataset/ETHPy150Open urielka/shaveet/shaveet/api.py/message_updates