From 9b5607d8295ffcfcef9ad2470b0def83b59fab7f Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 21 May 2013 19:35:34 -0700 Subject: [PATCH] send message along with GCM notification that ... there's a message. Should eventually allow GCM-aware clients to skip connecting on launch, and for now to make them a tiny bit snappier. --- xwords4/relay/scripts/gcm_loop.py | 60 +++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/xwords4/relay/scripts/gcm_loop.py b/xwords4/relay/scripts/gcm_loop.py index 11b9b59de..1914d6367 100755 --- a/xwords4/relay/scripts/gcm_loop.py +++ b/xwords4/relay/scripts/gcm_loop.py @@ -32,6 +32,7 @@ g_con = None g_sent = None g_debug = False g_skipSend = False # for debugging +g_columns = [ 'id', 'devid', 'connname', 'hid', 'msg64' ] DEVTYPE_GCM = 3 # 3 == GCM LINE_LEN = 76 @@ -55,19 +56,41 @@ def init(): def getPendingMsgs( con, typ ): cur = con.cursor() - query = """SELECT id, devid FROM msgs + query = """SELECT %s FROM msgs WHERE devid IN (SELECT id FROM devices WHERE devtype=%d and NOT unreg) AND NOT connname IN (SELECT connname FROM games WHERE dead); """ - cur.execute(query % typ) - result = cur.fetchall() + cur.execute(query % (",".join( g_columns ), typ)) + + result = [] + for row in cur: + rowObj = {} + for ii in range( len( g_columns ) ): + rowObj[g_columns[ii]] = row[ii] + result.append( rowObj ) if g_debug: print "getPendingMsgs=>", result return result +def deleteMsgs( con, msgIDs ): + if 0 < len( msgIDs ): + query = "DELETE from msgs where id in (%s);" % ",".join(msgIDs) + try: + cur = con.cursor() + cur.execute(query) + con.commit() + except psycopg2.DatabaseError, e: + print 'Error %s' % e + except Exception as inst: + print "failed to execute", query + print type(inst) + print inst.args + print inst + def unregister( gcmid ): global g_con print "unregister(", gcmid, ")" query = "UPDATE devices SET unreg=TRUE WHERE devid = '%s' and devtype = 3" % gcmid g_con.cursor().execute( query ) + g_con.commit() def asGCMIds(con, devids, typ): cur = con.cursor() @@ -76,10 +99,15 @@ def asGCMIds(con, devids, typ): cur.execute( query ) return [elem[0] for elem in cur.fetchall()] -def notifyGCM( devids, typ ): +def notifyGCM( devids, typ, msg, connname, hid ): + success = False if typ == DEVTYPE_GCM: + connname = "%s/%d" % (connname, hid) values = { - 'data' : { 'getMoves': True, }, + 'data' : { 'getMoves': True, + 'msg64': msg, + 'connname': connname, + }, 'registration_ids': devids, } params = json.dumps( values ) @@ -92,11 +120,13 @@ def notifyGCM( devids, typ ): if 'success' in asJson and 'failure' in asJson and len(devids) == asJson['success'] and 0 == asJson['failure']: print "OK" + success = True else: print "Errors: " print response else: print "not sending to", len(devids), "devices because typ ==", typ + return success def shouldSend(val): return val == 1 @@ -113,14 +143,14 @@ def targetsAfterBackoff( msgs ): global g_sent targets = {} for row in msgs: - msgid = row[0] - devid = row[1] + msgid = row['id'] + devid = row['devid'] if not msgid in g_sent: g_sent[msgid] = 0 g_sent[msgid] += 1 if shouldSend( g_sent[msgid] ): - targets[devid] = True - return targets.keys() + targets[devid] = row + return targets # devids is an array of (msgid, devid) tuples def pruneSent( devids ): @@ -129,7 +159,7 @@ def pruneSent( devids ): lenBefore = len(g_sent) msgids = [] for row in devids: - msgids.append(row[0]) + msgids.append(row['id']) for msgid in g_sent.keys(): if not msgid in msgids: del g_sent[msgid] @@ -187,8 +217,16 @@ def main(): emptyCount = 0 print strftime("%Y-%m-%d %H:%M:%S", time.localtime()), print "devices needing notification:", targets, '=>', - notifyGCM( asGCMIds( g_con, targets, typ ), typ ) + toDelete = [] + for devid in targets.keys(): + target = targets[devid] + connname = target['connname'] + hid = target['hid'] + msg = target['msg64'] + if notifyGCM( asGCMIds( g_con, [devid], typ ), typ, msg, connname, hid ): + toDelete.append( str(target['id']) ) pruneSent( devids ) + deleteMsgs( g_con, toDelete ) elif g_debug: print "no targets after backoff" else: emptyCount += 1