Mercurial > templog
annotate py/utils.py @ 258:03e540c3ec24
fix server side long polling
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 09 Jun 2015 23:29:11 +0800 |
parents | 0a1b642e3086 |
children | 26eee8591f61 |
rev | line source |
---|---|
141 | 1 import os |
2 import sys | |
3 #import ctypes | |
4 import time | |
5 import select | |
6 import logging | |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
230
diff
changeset
|
7 import binascii |
141 | 8 |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
145
diff
changeset
|
9 D = logging.debug |
141 | 10 L = logging.info |
11 W = logging.warning | |
12 E = logging.error | |
13 | |
14 DEFAULT_TRIES = 3 | |
15 READLINE_SELECT_TIMEOUT = 1 | |
16 | |
144 | 17 def EX(msg, *args, **kwargs): |
18 kwargs['exc_info'] = True | |
19 logging.error(msg, *args, **kwargs) | |
20 | |
141 | 21 clock_gettime = None |
22 no_clock_gettime = True | |
23 def monotonic_time(): | |
24 global clock_gettime | |
25 global no_clock_gettime | |
26 if no_clock_gettime: | |
27 return time.time() | |
28 | |
29 class timespec(ctypes.Structure): | |
30 _fields_ = [ | |
31 ('tv_sec', ctypes.c_long), | |
32 ('tv_nsec', ctypes.c_long) | |
33 ] | |
34 if not clock_gettime: | |
35 try: | |
36 librt = ctypes.CDLL('librt.so.0', use_errno=True) | |
37 clock_gettime = librt.clock_gettime | |
38 clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)] | |
39 except: | |
40 W("No clock_gettime(), using fake fallback.") | |
41 no_clock_gettime = True | |
42 return time.time() | |
43 | |
44 t = timespec() | |
45 CLOCK_MONOTONIC = 1 # see <linux/time.h> | |
46 | |
47 if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0: | |
48 errno_ = ctypes.get_errno() | |
49 raise OSError(errno_, os.strerror(errno_)) | |
50 return t.tv_sec + t.tv_nsec * 1e-9 | |
51 | |
52 # decorator, tries a number of times, returns None on failure, sleeps between | |
53 # Must be used as "@retry()" if arguments are defaulted | |
54 def retry(retries=DEFAULT_TRIES, try_time = 1): | |
55 def inner(func): | |
56 def new_f(*args, **kwargs): | |
57 for i in range(retries): | |
58 d = func(*args, **kwargs) | |
59 if d is not None: | |
60 return d | |
61 time.sleep(try_time) | |
62 return None | |
63 | |
230 | 64 new_f.__name__ = func.__name__ |
141 | 65 return new_f |
66 return inner | |
67 | |
68 def readline(sock): | |
69 timeout = READLINE_SELECT_TIMEOUT | |
70 buf = '' | |
71 while True: | |
72 (rlist, wlist, xlist) = select.select([sock], [], [], timeout) | |
73 if sock not in rlist: | |
74 # hit timeout | |
75 return None | |
76 | |
77 c = sock.recv(1) | |
78 if c == '': | |
79 # lightblue timeout | |
80 return None | |
81 if c == '\r': | |
82 continue | |
83 | |
84 buf += c | |
85 if c == '\n': | |
86 return buf | |
87 | |
88 # from http://blog.stalkr.net/2011/04/pctf-2011-32-thats-no-bluetooth.html | |
89 def crc16(buff, crc = 0, poly = 0x8408): | |
90 l = len(buff) | |
91 i = 0 | |
92 while i < l: | |
93 ch = ord(buff[i]) | |
94 uc = 0 | |
95 while uc < 8: | |
96 if (crc & 1) ^ (ch & 1): | |
97 crc = (crc >> 1) ^ poly | |
98 else: | |
99 crc >>= 1 | |
100 ch >>= 1 | |
101 uc += 1 | |
102 i += 1 | |
103 return crc | |
104 | |
105 def cheap_daemon(): | |
106 L("Daemonising.") | |
107 sys.stdout.flush() | |
108 sys.stderr.flush() | |
109 out = file('/dev/null', 'a+') | |
110 os.dup2(out.fileno(), sys.stdout.fileno()) | |
111 os.dup2(out.fileno(), sys.stderr.fileno()) | |
112 | |
113 try: | |
114 pid = os.fork() | |
115 if pid > 0: | |
116 sys.exit(0) | |
230 | 117 except OSError as e: |
141 | 118 E("Bad fork()") |
119 sys.exit(1) | |
120 | |
121 os.setsid() | |
122 | |
123 try: | |
124 pid = os.fork() | |
125 if pid > 0: | |
126 sys.exit(0) | |
230 | 127 except OSError as e: |
141 | 128 E("Bad fork()") |
129 sys.exit(1) | |
130 | |
145 | 131 def uptime(): |
132 try: | |
133 return float(open('/proc/uptime', 'r').read().split(' ', 1)[0]) | |
230 | 134 except Exception as e: |
145 | 135 return -1 |
141 | 136 |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
230
diff
changeset
|
137 def hexnonce(): |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
230
diff
changeset
|
138 return binascii.hexlify(os.urandom(120)) |