annotate web/settings.py @ 562:55cae4f27e75

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