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'], |
