75 lines
2.4 KiB
Python
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
|