Mercurial > templog
annotate server/utils.py @ 329:740438e21ea0
Fix bugs in server code (try actually running it)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 04 Jun 2012 23:50:42 +0800 |
parents | 46070aaf29ea |
children | 44c5ab5ea879 |
rev | line source |
---|---|
328
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1 import os |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2 import sys |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
3 import ctypes |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
4 import time |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
5 import select |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
6 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
7 DEFAULT_TRIES = 3 |
329
740438e21ea0
Fix bugs in server code (try actually running it)
Matt Johnston <matt@ucc.asn.au>
parents:
328
diff
changeset
|
8 READLINE_SELECT_TIMEOUT = 20 |
328
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
9 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
10 __all__ = ('monotonic_time', 'retry') |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
11 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
12 clock_gettime = None |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
13 no_clock_gettime = False |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
14 def monotonic_time(): |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
15 global clock_gettime |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
16 global no_clock_gettime |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
17 if no_clock_gettime: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
18 return time.time() |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
19 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
20 class timespec(ctypes.Structure): |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
21 _fields_ = [ |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
22 ('tv_sec', ctypes.c_long), |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
23 ('tv_nsec', ctypes.c_long) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
24 ] |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
25 if not clock_gettime: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
26 try: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
27 librt = ctypes.CDLL('librt.so.0', use_errno=True) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
28 clock_gettime = librt.clock_gettime |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
29 clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)] |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
30 except: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
31 print>>sys.stderr, "No clock_gettime(), using fake fallback." |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
32 no_clock_gettime = True |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
33 return time.time() |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
34 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
35 t = timespec() |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
36 CLOCK_MONOTONIC = 1 # see <linux/time.h> |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
37 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
38 if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
39 errno_ = ctypes.get_errno() |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
40 raise OSError(errno_, os.strerror(errno_)) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
41 return t.tv_sec + t.tv_nsec * 1e-9 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
42 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
43 # decorator, tries a number of times, returns None on failure, sleeps between |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
44 # Must be used as "@retry()" if arguments are defaulted |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
45 def retry(retries=DEFAULT_TRIES, try_time = 1): |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
46 def inner(func): |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
47 def new_f(*args, **kwargs): |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
48 for i in range(retries): |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
49 d = func(*args, **kwargs) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
50 if d: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
51 return d |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
52 time.sleep(try_time) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
53 new_f.func_name = func.func_name |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
54 return new_f |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
55 return inner |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
56 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
57 def readline(sock): |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
58 timeout = READLINE_SELECT_TIMEOUT |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
59 buf = '' |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
60 while true: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
61 (rlist, wlist, xlist) = select.select([sock], [], [], timeout) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
62 if sock not in rlist: |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
63 # hit timeout |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
64 return None |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
65 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
66 c = sock.recv(1) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
67 if c == '\r': |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
68 continue |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
69 |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
70 buf.append(c) |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
71 if c == '\n': |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
72 return buf |
46070aaf29ea
A bit of work on the server python
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
73 |