From 5079aac9a69599d4f317d0932c9efd1e757a59d3 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 1 Jun 2014 21:14:58 -0700 Subject: [PATCH] Allow subscribe to return events from a subject even when not creating a subscription --- api.py | 9 +++++---- lib/models.py | 16 ++++++++++------ static/test.js | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/api.py b/api.py index 4477f7e..a945605 100644 --- a/api.py +++ b/api.py @@ -114,16 +114,17 @@ def SendMessage(google_user, client, instance_id, args): def Subscribe(google_user, client, instance_id, args): instance = models.Instance.FromID(instance_id) + subject = models.Subject.FindOrCreate(args['subject']) + messages = args.get('messages', 0) + last_id = args.get('last_id', None) + if not instance or not instance.active: # Probably a race with the channel opening return { 'result': 'retry', + 'events': subject.GetEvents(messages, last_id), } - subject = models.Subject.FindOrCreate(args['subject']) - messages = args.get('messages', 0) - last_id = args.get('last_id', None) - try: return { 'result': 'ok', diff --git a/lib/models.py b/lib/models.py index eabc249..36aa347 100644 --- a/lib/models.py +++ b/lib/models.py @@ -297,6 +297,15 @@ class Subject(db.Model): ret['writable_only_by'] = str(writable_only_by) return ret + @db.transactional() + def GetEvents(self, messages, last_id): + events = [m.ToEvent() for m in self.GetPins()] + if messages: + events.extend(m.ToEvent() for m in self.GetRecentMessages(messages)) + if last_id is not None: + events.extend(m.ToEvent() for m in self.GetMessagesSince(last_id)) + return events + class Subscription(db.Model): # parent=Subject @@ -319,12 +328,7 @@ class Subscription(db.Model): .fetch(1)) if not subscriptions: cls(parent=subject, instance=instance).put() - events = [m.ToEvent() for m in subject.GetPins()] - if messages: - events.extend(m.ToEvent() for m in subject.GetRecentMessages(messages)) - if last_id is not None: - events.extend(m.ToEvent() for m in subject.GetMessagesSince(last_id)) - return events + return subject.GetEvents(messages, last_id) @classmethod @db.transactional() diff --git a/static/test.js b/static/test.js index d64a746..ac1fda0 100644 --- a/static/test.js +++ b/static/test.js @@ -117,6 +117,28 @@ asyncTest('Message round trip', function() { cosmo.subscribe(subject, -1); }); +asyncTest('Message round trip without channel', function() { + expect(2); + + var subject = randstring(); + var message = randstring(); + + var callbacks = { + 'onMessage': function(e) { + equal(e['subject']['name'], subject, 'subject matches'); + equal(e['message'], message, 'message matches'); + cosmo.shutdown(); + start(); + } + }; + + var cosmo = new Cosmopolite(callbacks, null, randstring()); + cosmo.channelState_ = Cosmopolite.ChannelState_.OPENING; + cosmo.sendMessage(subject, message); + cosmo.subscribe(subject, -1); +}); + + asyncTest('Complex object', function() { expect(2);