Untested code for polling instances.

This commit is contained in:
Ian Gulliver
2015-06-12 19:57:55 -07:00
parent d94b3d08ae
commit 33579856c8
2 changed files with 68 additions and 9 deletions

35
api.py
View File

@@ -28,7 +28,11 @@ import config
def CreateChannel(google_user, client, client_address, instance_id, args):
models.Instance.FindOrCreate(instance_id)
instance = models.Instance.FindOrCreate(instance_id)
if instance.polling:
instance.polling = False
instance.save()
token = channel.create_channel(
client_id=instance_id,
@@ -50,6 +54,32 @@ def CreateChannel(google_user, client, client_address, instance_id, args):
}
def Poll(google_user, client, client_address, instance_id, args):
instance = models.Instance.FindOrCreate(instance_id)
if not instance.polling:
instance.polling = True
instance.save()
events = []
if google_user:
events.append({
'event_type': 'login',
'google_user': google_user.email(),
})
else:
events.append({
'event_type': 'logout',
})
for subscription in instance.GetSubscriptions():
events.extend(subscription.GetMessages())
return {
'events': events,
}
def Pin(google_user, client, client_address, instance_id, args):
instance = models.Instance.FromID(instance_id)
if not instance or not instance.active:
@@ -143,7 +173,7 @@ def Subscribe(google_user, client, client_address, instance_id, args):
return {
'result': 'ok',
'events': models.Subscription.FindOrCreate(
subject, client, instance, args['subject'], messages, last_id),
subject, client, instance, args['subject'], messages, last_id, instance.polling),
}
@@ -181,6 +211,7 @@ class APIWrapper(webapp2.RequestHandler):
_COMMANDS = {
'createChannel': CreateChannel,
'pin': Pin,
'poll': Poll,
'sendMessage': SendMessage,
'subscribe': Subscribe,
'unpin': Unpin,

View File

@@ -36,6 +36,7 @@ import utils
# ↳ Message
# ↳ Pin (⤴︎ Instance)
# ↳ Subscription (⤴︎ Instance)
# ↳ Event
class DuplicateMessage(Exception):
@@ -92,6 +93,7 @@ class Client(db.Model):
class Instance(db.Model):
# key_name=instance_id
active = db.BooleanProperty(required=True, default=False)
polling = db.BooleanProperty(required=True, default=False)
@classmethod
def FromID(cls, instance_id):
@@ -99,9 +101,14 @@ class Instance(db.Model):
return cls.get_by_key_name(instance_id)
@classmethod
def FindOrCreate(cls, instance_id):
def FindOrCreate(cls, instance_id, polling=False):
logging.info('Instance: %s', instance_id)
return cls.get_or_insert(instance_id)
return cls.get_or_insert(instance_id, polling=polling)
def GetSubscriptions(self):
return (
Subscription.all()
.filter('instance=', self))
class Subject(db.Model):
@@ -386,11 +393,12 @@ class Subscription(db.Model):
instance = db.ReferenceProperty(reference_class=Instance, required=True)
readable_only_by_me = db.BooleanProperty(required=True, default=False)
writable_only_by_me = db.BooleanProperty(required=True, default=False)
polling = db.BooleanProperty(required=True, default=False)
@classmethod
@db.transactional()
def FindOrCreate(cls, subject, client, instance, request,
messages=0, last_id=None):
messages=0, last_id=None, polling=False):
readable_only_by_me = (request.get('readable_only_by') == 'me')
writable_only_by_me = (request.get('writable_only_by') == 'me')
subscriptions = (
@@ -422,10 +430,30 @@ class Subscription(db.Model):
subscription.delete()
def SendMessage(self, msg):
instance_key = Subscription.instance.get_value_for_datastore(self)
channel.send_message(
str(instance_key.name()),
json.dumps(msg, default=utils.EncodeJSON))
encoded = json.dumps(msg, default=utils.EncodeJSON)
if self.polling:
Event(parent=this,
json=encoded).save()
else:
instance_key = Subscription.instance.get_value_for_datastore(self)
channel.send_message(str(instance_key.name()), encoded)
def GetMessages(self):
events = (
Event.all()
.ancestor(self))
return [e.ToEvent() for e in events]
class Event(db.Model):
# parent=Subscription
json = db.StringProperty(required=True)
def ToEvent(self):
ret = json.loads(self.json)
ret['event_id'] = str(self.key())
return ret
class Message(db.Model):