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.
This commit is contained in:
Eric House 2013-05-21 19:35:34 -07:00
parent 2a2157b504
commit 9b5607d829

View file

@ -32,6 +32,7 @@ g_con = None
g_sent = None g_sent = None
g_debug = False g_debug = False
g_skipSend = False # for debugging g_skipSend = False # for debugging
g_columns = [ 'id', 'devid', 'connname', 'hid', 'msg64' ]
DEVTYPE_GCM = 3 # 3 == GCM DEVTYPE_GCM = 3 # 3 == GCM
LINE_LEN = 76 LINE_LEN = 76
@ -55,19 +56,41 @@ def init():
def getPendingMsgs( con, typ ): def getPendingMsgs( con, typ ):
cur = con.cursor() 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) WHERE devid IN (SELECT id FROM devices WHERE devtype=%d and NOT unreg)
AND NOT connname IN (SELECT connname FROM games WHERE dead); """ AND NOT connname IN (SELECT connname FROM games WHERE dead); """
cur.execute(query % typ) cur.execute(query % (",".join( g_columns ), typ))
result = cur.fetchall()
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 if g_debug: print "getPendingMsgs=>", result
return 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 ): def unregister( gcmid ):
global g_con global g_con
print "unregister(", gcmid, ")" print "unregister(", gcmid, ")"
query = "UPDATE devices SET unreg=TRUE WHERE devid = '%s' and devtype = 3" % gcmid query = "UPDATE devices SET unreg=TRUE WHERE devid = '%s' and devtype = 3" % gcmid
g_con.cursor().execute( query ) g_con.cursor().execute( query )
g_con.commit()
def asGCMIds(con, devids, typ): def asGCMIds(con, devids, typ):
cur = con.cursor() cur = con.cursor()
@ -76,10 +99,15 @@ def asGCMIds(con, devids, typ):
cur.execute( query ) cur.execute( query )
return [elem[0] for elem in cur.fetchall()] 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: if typ == DEVTYPE_GCM:
connname = "%s/%d" % (connname, hid)
values = { values = {
'data' : { 'getMoves': True, }, 'data' : { 'getMoves': True,
'msg64': msg,
'connname': connname,
},
'registration_ids': devids, 'registration_ids': devids,
} }
params = json.dumps( values ) 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']: if 'success' in asJson and 'failure' in asJson and len(devids) == asJson['success'] and 0 == asJson['failure']:
print "OK" print "OK"
success = True
else: else:
print "Errors: " print "Errors: "
print response print response
else: else:
print "not sending to", len(devids), "devices because typ ==", typ print "not sending to", len(devids), "devices because typ ==", typ
return success
def shouldSend(val): def shouldSend(val):
return val == 1 return val == 1
@ -113,14 +143,14 @@ def targetsAfterBackoff( msgs ):
global g_sent global g_sent
targets = {} targets = {}
for row in msgs: for row in msgs:
msgid = row[0] msgid = row['id']
devid = row[1] devid = row['devid']
if not msgid in g_sent: if not msgid in g_sent:
g_sent[msgid] = 0 g_sent[msgid] = 0
g_sent[msgid] += 1 g_sent[msgid] += 1
if shouldSend( g_sent[msgid] ): if shouldSend( g_sent[msgid] ):
targets[devid] = True targets[devid] = row
return targets.keys() return targets
# devids is an array of (msgid, devid) tuples # devids is an array of (msgid, devid) tuples
def pruneSent( devids ): def pruneSent( devids ):
@ -129,7 +159,7 @@ def pruneSent( devids ):
lenBefore = len(g_sent) lenBefore = len(g_sent)
msgids = [] msgids = []
for row in devids: for row in devids:
msgids.append(row[0]) msgids.append(row['id'])
for msgid in g_sent.keys(): for msgid in g_sent.keys():
if not msgid in msgids: if not msgid in msgids:
del g_sent[msgid] del g_sent[msgid]
@ -187,8 +217,16 @@ def main():
emptyCount = 0 emptyCount = 0
print strftime("%Y-%m-%d %H:%M:%S", time.localtime()), print strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
print "devices needing notification:", targets, '=>', 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 ) pruneSent( devids )
deleteMsgs( g_con, toDelete )
elif g_debug: print "no targets after backoff" elif g_debug: print "no targets after backoff"
else: else:
emptyCount += 1 emptyCount += 1