From 94d0fda6ab82dad3ec474f8fededde13426a902c Mon Sep 17 00:00:00 2001 From: Klaas van Schelven Date: Fri, 19 Apr 2024 11:58:20 +0200 Subject: [PATCH] Midway checking to preserve state --- snappea/__init__.py | 0 snappea/admin.py | 3 + snappea/apps.py | 6 ++ snappea/foreman.py | 68 ++++++++++++++++++++++ snappea/management/__init__.py | 0 snappea/management/commands/__init__.py | 0 snappea/management/commands/run_snappea.py | 11 ++++ snappea/migrations/__init__.py | 0 snappea/models.py | 3 + snappea/tests.py | 3 + snappea/views.py | 3 + 11 files changed, 97 insertions(+) create mode 100644 snappea/__init__.py create mode 100644 snappea/admin.py create mode 100644 snappea/apps.py create mode 100644 snappea/foreman.py create mode 100644 snappea/management/__init__.py create mode 100644 snappea/management/commands/__init__.py create mode 100644 snappea/management/commands/run_snappea.py create mode 100644 snappea/migrations/__init__.py create mode 100644 snappea/models.py create mode 100644 snappea/tests.py create mode 100644 snappea/views.py diff --git a/snappea/__init__.py b/snappea/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/snappea/admin.py b/snappea/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/snappea/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/snappea/apps.py b/snappea/apps.py new file mode 100644 index 0000000..dcd6476 --- /dev/null +++ b/snappea/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class SnappeaConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'snappea' diff --git a/snappea/foreman.py b/snappea/foreman.py new file mode 100644 index 0000000..387764b --- /dev/null +++ b/snappea/foreman.py @@ -0,0 +1,68 @@ +import os +import logging +import time +import signal +import threading +from sentry_sdk import capture_exception + + +logger = logging.getLogger("snappea.foreman") + + +def example_worker(): + logger.info("example worker started") + time.sleep(10) + logger.info("example worker stopped") + + +def example_failing_worker(): + raise Exception("I am failing") + + +lll = [] + + +class Foreman: + + def __init__(self): + # signal.signal(signal.SIGTERM, self.handle_sigterm) later + signal.signal(signal.SIGUSR1, self.handle_sigusr1) + + self.workers = [] + + pid = os.getpid() + logger.info("Foreman created, my pid is %s", pid) + with open("/tmp/snappea.pid", "w") as f: + f.write(str(pid)) + + def handle_sigterm(self, sig, frame): + print("Handling SIGTERM signal") + + def run_in_thread(self, function, *args, **kwargs): + def non_failing_function(*inner_args, **inner_kwargs): + try: + function(*inner_args, **inner_kwargs) + except Exception as e: + # Potential TODO: make this configurable / depend on our existing config in bugsink/settings.py + logger.info("Worker exception: %s", str(e)) + capture_exception(e) + + worker_thread = threading.Thread(target=non_failing_function, *args, **kwargs) + worker_thread.run() + return worker_thread + + def handle_sigusr1(self, sig, frame): + logger.info("Received signal, starting new thread") + self.run_in_thread(example_failing_worker) + # worker_thread = threading.Thread(target=example_worker) + + lll.append("x") + me = len(lll) + for i in range(4): + print("am I locked?", me, i) + time.sleep(1) + + def run_forever(self): + # there is no actual code here, all the action happens in the signal handlers + while True: + time.sleep(3600) diff --git a/snappea/management/__init__.py b/snappea/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/snappea/management/commands/__init__.py b/snappea/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/snappea/management/commands/run_snappea.py b/snappea/management/commands/run_snappea.py new file mode 100644 index 0000000..0437b39 --- /dev/null +++ b/snappea/management/commands/run_snappea.py @@ -0,0 +1,11 @@ +from django.core.management.base import BaseCommand + +from snappea.foreman import Foreman + + +class Command(BaseCommand): + help = "Run the SnapPea foreman service." + + def handle(self, *args, **options): + + Foreman().run_forever() diff --git a/snappea/migrations/__init__.py b/snappea/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/snappea/models.py b/snappea/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/snappea/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/snappea/tests.py b/snappea/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/snappea/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/snappea/views.py b/snappea/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/snappea/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.