Mercurial > templog
comparison web/settings.py @ 253:0a1b642e3086
long polling config updates
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 08 Jun 2015 22:29:46 +0800 |
parents | |
children | 03e540c3ec24 |
comparison
equal
deleted
inserted
replaced
251:b6079cb0c665 | 253:0a1b642e3086 |
---|---|
1 import gevent | |
2 import fcntl | |
3 import hashlib | |
4 | |
5 class Settings(object): | |
6 RAND_SIZE = 15 # 120 bits | |
7 | |
8 """ Handles state updates from both the web UI and from the fridge client. | |
9 The fridge client is canonical. It provides the epoch (apart from 'startepoch'), that | |
10 is changed any time the fridge reloads its local config. The fridge only accepts | |
11 updates that have the same epoch. | |
12 | |
13 When the web UI changes it keeps the same epoch but generates a new tag. The fridge sends | |
14 its current known tag and waits for it to change. | |
15 | |
16 content is opaque, presently a dictionary of decoded json | |
17 """ | |
18 | |
19 def __init__(self): | |
20 self.event = gevent.event.Event() | |
21 self.contents = None | |
22 self.epoch = None | |
23 self.tag = None | |
24 | |
25 self.update(self, None, 'startepoch') | |
26 | |
27 def wait(self, epoch_tag = None, timeout = None): | |
28 """ returns false if the timeout was hit """ | |
29 if self.epoch_tag() != epoch_tag: | |
30 # has alredy changed | |
31 return True | |
32 return self.event.wait(timeout) | |
33 | |
34 def epoch_tag(self): | |
35 return '%s-%s' % (self.epoch, self.tag) | |
36 | |
37 def random(self): | |
38 return binascii.hexlify(os.urandom(self.RAND_SIZE)) | |
39 | |
40 def update(self, contents, epoch = None): | |
41 """ replaces settings contents and updates waiters if changed """ | |
42 if epoch: | |
43 if self.epoch == epoch: | |
44 return | |
45 else: | |
46 self.epoch = epoch | |
47 | |
48 self.tag = self.random() | |
49 self.contents = contents | |
50 | |
51 self.event.set() | |
52 self.event.clear() | |
53 | |
54 def get(self): | |
55 """ Returns (contents, epoch-tag) """ | |
56 return self.contents, self.epoch_tag() | |
57 | |
58 | |
59 | |
60 | |
61 |