Mercurial > templog
comparison py/tempserver.py @ 233:19569cb5ed46
better arg parser. seems close to ready
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 11 Apr 2015 23:32:59 +0800 |
parents | a01b7bccccd3 |
children | fd29ae905d1b |
comparison
equal
deleted
inserted
replaced
232:a01b7bccccd3 | 233:19569cb5ed46 |
---|---|
4 import os | 4 import os |
5 import logging | 5 import logging |
6 import time | 6 import time |
7 import signal | 7 import signal |
8 import asyncio | 8 import asyncio |
9 import argparse | |
9 | 10 |
10 import lockfile.pidlockfile | 11 import lockfile.pidlockfile |
11 import daemon | 12 import daemon |
12 | 13 |
13 import utils | 14 import utils |
18 import params | 19 import params |
19 import uploader | 20 import uploader |
20 | 21 |
21 | 22 |
22 class Tempserver(object): | 23 class Tempserver(object): |
23 def __init__(self): | 24 def __init__(self, test_mode): |
24 self.readings = [] | 25 self.readings = [] |
25 self.current = (None, None) | 26 self.current = (None, None) |
26 self.fridge = None | 27 self.fridge = None |
27 self._wakeup = asyncio.Condition() | 28 self._wakeup = asyncio.Event() |
29 self._test_mode = test_mode | |
28 | 30 |
29 def __enter__(self): | 31 def __enter__(self): |
30 self.params = params.Params() | 32 self.params = params.Params() |
31 self.fridge = fridge.Fridge(self) | 33 self.fridge = fridge.Fridge(self) |
32 self.uploader = uploader.Uploader(self) | 34 self.uploader = uploader.Uploader(self) |
51 self.sensors.run(), | 53 self.sensors.run(), |
52 self.uploader.run(), | 54 self.uploader.run(), |
53 ) | 55 ) |
54 | 56 |
55 loop = asyncio.get_event_loop() | 57 loop = asyncio.get_event_loop() |
56 result_tasks = loop.run_until_complete(asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)) | 58 try: |
57 # use the results so that exceptions get thrown | 59 result_tasks = loop.run_until_complete(asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)) |
58 [t.result() for x in result_tasks for t in x] | 60 # use the results so that exceptions get thrown |
61 [t.result() for x in result_tasks for t in x] | |
62 except KeyboardInterrupt: | |
63 print('ctrl-c') | |
64 pass | |
65 finally: | |
66 loop.close() | |
59 | 67 |
60 def now(self): | 68 def now(self): |
61 return utils.monotonic_time() | 69 return utils.monotonic_time() |
62 | 70 |
63 def set_sensors(self, sensors): | 71 def set_sensors(self, sensors): |
96 def sleep(self, timeout): | 104 def sleep(self, timeout): |
97 """ sleeps for timeout seconds, though wakes if the server's config is updated """ | 105 """ sleeps for timeout seconds, though wakes if the server's config is updated """ |
98 # XXX fixme - we should wake on _wakeup but asyncio Condition with wait_for is a bit broken? | 106 # XXX fixme - we should wake on _wakeup but asyncio Condition with wait_for is a bit broken? |
99 # https://groups.google.com/forum/#!topic/python-tulip/eSm7rZAe9LM | 107 # https://groups.google.com/forum/#!topic/python-tulip/eSm7rZAe9LM |
100 # For now we just sleep, ignore the _wakeup | 108 # For now we just sleep, ignore the _wakeup |
101 yield from asyncio.sleep(timeout) | 109 try: |
110 yield from asyncio.wait_for(self._wakeup.wait(), timeout=timeout) | |
111 except asyncio.TimeoutError: | |
112 pass | |
102 | 113 |
103 @asyncio.coroutine | |
104 def _reload_signal(self): | 114 def _reload_signal(self): |
105 try: | 115 try: |
106 self.params.load() | 116 self.params.load() |
107 L("Reloaded.") | 117 L("Reloaded.") |
108 yield from self._wakeup.acquire() | 118 self._wakeup.set() |
109 self._wakeup.notify_all() | 119 self._wakeup.clear() |
110 self._wakeup.release() | |
111 except Error as e: | 120 except Error as e: |
112 W("Problem reloading: %s" % str(e)) | 121 W("Problem reloading: %s" % str(e)) |
113 | 122 |
114 def setup_logging(): | 123 def test_mode(self): |
124 return self._test_mode | |
125 | |
126 def setup_logging(debug = False): | |
127 level = logging.INFO | |
128 if debug: | |
129 level = logging.DEBUG | |
115 logging.basicConfig(format='%(asctime)s %(message)s', | 130 logging.basicConfig(format='%(asctime)s %(message)s', |
116 datefmt='%m/%d/%Y %I:%M:%S %p', | 131 datefmt='%m/%d/%Y %I:%M:%S %p', |
117 level=logging.DEBUG) | 132 level=level) |
118 logging.getLogger("asyncio").setLevel(logging.DEBUG) | 133 #logging.getLogger("asyncio").setLevel(logging.DEBUG) |
119 | 134 |
120 def start(): | 135 def start(test_mode): |
121 with Tempserver() as server: | 136 with Tempserver(test_mode) as server: |
122 server.run() | 137 server.run() |
123 | 138 |
124 def main(): | 139 def main(): |
125 setup_logging() | 140 parser = argparse.ArgumentParser() |
141 parser.add_argument('--hup', action='store_true') | |
142 parser.add_argument('--new', action='store_true') | |
143 parser.add_argument('--daemon', action='store_true') | |
144 parser.add_argument('-d', '--debug', action='store_true') | |
145 parser.add_argument('-t', '--test', action='store_true') | |
146 args = parser.parse_args() | |
147 | |
148 setup_logging(args.debug) | |
126 | 149 |
127 heredir = os.path.abspath(os.path.dirname(__file__)) | 150 heredir = os.path.abspath(os.path.dirname(__file__)) |
128 pidpath = os.path.join(heredir, 'tempserver.pid') | 151 pidpath = os.path.join(heredir, 'tempserver.pid') |
129 pidf = lockfile.pidlockfile.PIDLockFile(pidpath, threaded=False) | 152 pidf = lockfile.pidlockfile.PIDLockFile(pidpath, threaded=False) |
130 do_hup = '--hup' in sys.argv | 153 |
154 | |
131 try: | 155 try: |
132 pidf.acquire(1) | 156 pidf.acquire(1) |
133 pidf.release() | 157 pidf.release() |
134 except (lockfile.AlreadyLocked, lockfile.LockTimeout) as e: | 158 except (lockfile.AlreadyLocked, lockfile.LockTimeout) as e: |
135 pid = pidf.read_pid() | 159 pid = pidf.read_pid() |
136 if do_hup: | 160 if args.hup: |
137 try: | 161 try: |
138 os.kill(pid, signal.SIGHUP) | 162 os.kill(pid, signal.SIGHUP) |
139 print("Sent SIGHUP to process %d" % pid, file=sys.stderr) | 163 print("Sent SIGHUP to process %d" % pid, file=sys.stderr) |
140 sys.exit(0) | 164 sys.exit(0) |
141 except OSError: | 165 except OSError: |
144 | 168 |
145 print("Locked by PID %d" % pid, file=sys.stderr) | 169 print("Locked by PID %d" % pid, file=sys.stderr) |
146 | 170 |
147 stale = False | 171 stale = False |
148 if pid > 0: | 172 if pid > 0: |
149 if '--new' in sys.argv: | 173 if args.new: |
150 try: | 174 try: |
151 os.kill(pid, 0) | 175 os.kill(pid, 0) |
152 except OSError: | 176 except OSError: |
153 stale = True | 177 stale = True |
154 | 178 |
169 if stale: | 193 if stale: |
170 # isn't still running, steal the lock | 194 # isn't still running, steal the lock |
171 print("Unlinking stale lockfile %s for pid %d" % (pidpath, pid), file=sys.stderr) | 195 print("Unlinking stale lockfile %s for pid %d" % (pidpath, pid), file=sys.stderr) |
172 pidf.break_lock() | 196 pidf.break_lock() |
173 | 197 |
174 if do_hup: | 198 if args.hup: |
175 print("Doesn't seem to be running", file=sys.stderr) | 199 print("Doesn't seem to be running", file=sys.stderr) |
176 sys.exit(1) | 200 sys.exit(1) |
177 | 201 |
178 if '--daemon' in sys.argv: | 202 if args.daemon: |
179 logpath = os.path.join(os.path.dirname(__file__), 'tempserver.log') | 203 logpath = os.path.join(os.path.dirname(__file__), 'tempserver.log') |
180 logf = open(logpath, 'a+') | 204 logf = open(logpath, 'a+') |
181 with daemon.DaemonContext(pidfile=pidf, stdout=logf, stderr = logf): | 205 with daemon.DaemonContext(pidfile=pidf, stdout=logf, stderr = logf): |
182 start() | 206 start(args.test) |
183 else: | 207 else: |
184 with pidf: | 208 with pidf: |
185 start() | 209 start(args.test) |
186 | 210 |
187 if __name__ == '__main__': | 211 if __name__ == '__main__': |
188 main() | 212 main() |