-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathregistry.py
73 lines (60 loc) · 2.44 KB
/
registry.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from hbpush.message import Message
from hbpush.channel import Channel
class Registry(object):
def __init__(self, store):
self.store = store
self.channels = {}
self.get_request = {}
def get(self, id, callback, errback):
try:
callback(self.channels[id])
except KeyError:
# Try to get the channel from the store to populate
# the cache.
# We might not be the first ones to do that
reqs = self.get_request.get(id, ())
if len(reqs):
self.get_request[id].append((callback, errback))
else:
def _cache_channel(message):
channel = Channel(id, self.store)
channel.last_message = message
self.channels[id] = channel
for (cb, _) in self.get_request[id]:
cb(channel)
del self.get_request[id]
def _no_message(error):
if error.__class__ == Message.DoesNotExist:
error = Channel.DoesNotExist()
for (_, eb) in self.get_request[id]:
eb(error)
del self.get_request[id]
self.get_request[id] = [(callback, errback),]
self.store.get_last(id, _cache_channel, _no_message)
def create(self, id, callback, errback):
def _no_channel(error):
if error.__class__ == Channel.DoesNotExist:
# someone might have populated the cache in between
if id in self.channels:
errback(Channel.Duplicate())
else:
channel = Channel(id, self.store)
self.channels[id] = channel
callback(channel)
else:
errback(error)
def _got_channel(channel):
errback(Channel.Duplicate())
self.get(id, _got_channel, _no_channel)
def get_or_create(self, id, callback, errback):
def _duplicate(error):
if error.__class__ == Channel.Duplicate:
callback(self.channels[id])
else:
errback(error)
self.create(id, callback, _duplicate)
def delete(self, id, callback, errback):
def _delete(channel):
self.channels.pop(id)
channel.delete(callback, errback)
self.get(id, _delete, errback)