Files

125 lines
3.4 KiB
Python

"""Grotti starten. Kern und Seiten liegen daneben."""
import atexit
import signal
import threading
import time
from waitress import serve
from grotti import db, jobs, library, logutil, store
from grotti.config import load
from web.app import create_app
log = logutil.get("grotti.server")
def background(cfg):
def work():
try:
with db.connect(cfg["database_url"]) as conn:
library.sync_watch(conn, cfg, force=False)
jobs.sync_history(conn, cfg)
deleted = db.prune_run_samples(conn, keep_days=90)
if deleted:
log.info("Proben gelöscht: %s", deleted)
conn.commit()
except Exception as exc:
log.warning("Abgleich: %s", exc)
threading.Thread(target=work, name="grotti-abgleich", daemon=True).start()
def _retention_loop(cfg, stop_event):
"""Nächtlich alte run_samples entfernen."""
while not stop_event.wait(3600):
hour = time.localtime().tm_hour
if hour != 3:
continue
try:
with db.connect(cfg["database_url"]) as conn:
n = db.prune_run_samples(conn, keep_days=90)
conn.commit()
if n:
log.info("Retention: %s Proben gelöscht.", n)
except Exception as exc:
log.warning("Retention: %s", exc)
stop_event.wait(3600)
def main():
cfg = load()
logutil.setup(cfg.get("log_level") or "INFO")
cfg["data_dir"].mkdir(parents=True, exist_ok=True)
(cfg["data_dir"] / "eingang").mkdir(exist_ok=True)
db.prepare(cfg["database_url"])
db.init_pool(cfg["database_url"], min_size=2, max_size=16)
with db.connect(cfg["database_url"]) as conn:
store.seed_printers(conn, cfg["printers_file"])
store.seed_materials(conn)
conn.commit()
app = create_app(cfg)
watcher = app.extensions["watcher"]
dispatcher = app.extensions["print_queue"]
send_queue = app.extensions["send_queue"]
watcher.start()
dispatcher.start()
if hasattr(send_queue, "start"):
send_queue.start()
from grotti.daily_report import DailyReportThread
daily = DailyReportThread(cfg["database_url"], cfg, watcher=watcher)
daily.start()
app.extensions["daily_report"] = daily
stop_event = threading.Event()
retention = threading.Thread(
target=_retention_loop,
args=(cfg, stop_event),
name="grotti-retention",
daemon=True,
)
retention.start()
background(cfg)
def shutdown(*_args):
stop_event.set()
try:
watcher.stop()
except Exception:
pass
try:
dispatcher.stop()
except Exception:
pass
try:
if hasattr(send_queue, "stop"):
send_queue.stop()
except Exception:
pass
try:
daily.stop()
except Exception:
pass
db.close_pool()
atexit.register(shutdown)
for sig in (signal.SIGINT, signal.SIGTERM):
try:
signal.signal(sig, lambda *_: shutdown())
except (ValueError, OSError):
pass
log.info("Grotti: http://%s:%s/", cfg["host"], cfg["port"])
serve(
app,
host=cfg["host"],
port=cfg["port"],
threads=int(cfg.get("http_threads") or 16),
channel_timeout=120,
)
if __name__ == "__main__":
main()