Mercurial > personal > weatherlog
comparison weatherlog/daemon.py @ 19:7117db65715e
Make weatherlog shutdown properly by handling SIGTERM.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 20 Jan 2020 23:36:23 -0500 |
parents | 39c0686e6765 |
children | 92367b644e29 |
comparison
equal
deleted
inserted
replaced
18:9daa281d996b | 19:7117db65715e |
---|---|
1 """Entry point to set up a temperature logging daemon.""" | 1 """Entry point to set up a temperature logging daemon.""" |
2 | 2 |
3 import argparse | 3 import argparse |
4 import enum | 4 import enum |
5 import signal | |
6 import threading | |
5 import time | 7 import time |
6 import typing as t | 8 import typing as t |
7 | 9 |
8 import attr | 10 import attr |
9 import toml | 11 import toml |
19 def run( | 21 def run( |
20 rd: reader.Reader, | 22 rd: reader.Reader, |
21 log: logger.BufferedLogger, | 23 log: logger.BufferedLogger, |
22 writer: logger.RemoteWriter, | 24 writer: logger.RemoteWriter, |
23 interval: int = DEFAULT_INTERVAL_SECS, | 25 interval: int = DEFAULT_INTERVAL_SECS, |
24 ): | 26 ) -> None: |
25 """Sets up and runs a logger daemon.""" | 27 """Sets up and runs a logger daemon.""" |
26 log.start() | 28 evt = threading.Event() |
29 signal.signal(signal.SIGTERM, lambda *args: evt.set()) | |
27 cycle = 0 | 30 cycle = 0 |
28 start = time.time() | 31 start = time.time() |
32 running = True | |
33 log.start() | |
29 try: | 34 try: |
30 while True: | 35 while running: |
31 log.write(rd.read().as_dict()) | 36 log.write(rd.read().as_dict()) |
32 cycle += 1 | 37 cycle += 1 |
33 target = start + interval * cycle | 38 target = start + interval * cycle |
34 now = time.time() | 39 now = time.time() |
35 time.sleep(max(target - now, MIN_INTERVAL_SECS)) | 40 running = not evt.wait(max(target - now, MIN_INTERVAL_SECS)) |
36 finally: | 41 finally: |
37 log.close() | 42 log.close() |
38 | 43 |
39 | 44 |
40 class SensorType(enum.Enum): | 45 class SensorType(enum.Enum): |
52 sensor: SensorType | 57 sensor: SensorType |
53 # The authentication preamble for the URL. | 58 # The authentication preamble for the URL. |
54 auth: t.Dict[str, object] | 59 auth: t.Dict[str, object] |
55 | 60 |
56 | 61 |
57 def parse_config(config_file: str): | 62 def parse_config(config_file: str) -> _Config: |
58 with open(config_file, 'r') as infile: | 63 with open(config_file, 'r') as infile: |
59 config = toml.load(infile) | 64 config = toml.load(infile) |
60 return _Config( | 65 return _Config( |
61 directory=config['directory'], | 66 directory=config['directory'], |
62 url=config['url'], | 67 url=config['url'], |