Files
proc-rota/djangorota/rota/services.py
T
2025-12-09 10:01:04 +00:00

75 lines
2.4 KiB
Python

import threading
import traceback
from typing import Optional
from django.utils import timezone
from .models import RotaRun, RotaSchedule
def _run_rota_job(run_id: int, use_external_generator: bool = False):
"""Background job that executes the scheduler and updates RotaRun.
If `use_external_generator` is True, callers should implement a project
level `generate_rota_for_schedule` function and import it here. By
default a minimal placeholder result is recorded so the UI and workflow
can be tested without wiring the full solver.
"""
run = RotaRun.objects.get(pk=run_id)
try:
run.mark_running()
rota: RotaSchedule = run.rota
# Placeholder: integrate your generator here.
# Example integration point (not implemented in this scaffold):
# from proc.integration import generate_rota_for_schedule
# result = generate_rota_for_schedule(rota)
if use_external_generator:
# Try to import a project-level generator hook. This allows you to
# call into existing code (e.g. your `rota.run2` logic) without
# hard-coding it into the Django app.
try:
from project_rota_hook import generate_rota_for_schedule # type: ignore
result = generate_rota_for_schedule(rota)
except Exception:
tb = traceback.format_exc()
run.mark_failed(message=tb)
return
else:
# Minimal demo result for initial testing
result = {
"rota": rota.name,
"worker_count": rota.workers.count(),
"generated_at": timezone.now().isoformat(),
}
run.mark_finished(result=result)
except Exception:
tb = traceback.format_exc()
try:
run.mark_failed(message=tb)
except Exception:
# last resort: log to stdout
print("Failed to update RotaRun with failure:")
print(tb)
def run_rota_async(rota_id: int, use_external_generator: bool = False) -> RotaRun:
"""Create a RotaRun and start background thread to run it.
Returns the created RotaRun instance.
"""
rota = RotaSchedule.objects.get(pk=rota_id)
run = RotaRun.objects.create(rota=rota)
thread = threading.Thread(target=_run_rota_job, args=(run.id, use_external_generator), daemon=True)
thread.start()
return run