lib.itmens/common/models/cron.py

92 lines
2.3 KiB
Python
Raw Permalink Normal View History

2023-10-21 05:41:38 +00:00
from datetime import timedelta
import django_rq
from loguru import logger
from rq.job import Job
from rq.registry import ScheduledJobRegistry
2023-12-28 22:12:07 -05:00
from boofilsic import settings
2023-10-21 05:41:38 +00:00
class BaseJob:
interval = timedelta(0) # 0 = disabled, don't set it less than 1 minute
2023-10-21 05:41:38 +00:00
@classmethod
def cancel(cls):
job_id = cls.__name__
try:
job = Job.fetch(id=job_id, connection=django_rq.get_connection("cron"))
if job.get_status() in ["queued", "scheduled"]:
logger.info(f"Cancel queued job: {job_id}")
job.cancel()
registry = ScheduledJobRegistry(queue=django_rq.get_queue("cron"))
registry.remove(job)
2024-04-06 00:13:50 -04:00
except Exception:
2023-10-21 05:41:38 +00:00
pass
@classmethod
2024-12-26 14:12:39 -05:00
def schedule(cls, now=False):
2023-10-21 05:41:38 +00:00
job_id = cls.__name__
2024-12-26 14:12:39 -05:00
i = timedelta(seconds=1) if now else cls.interval
2023-12-28 22:12:07 -05:00
if cls.interval <= timedelta(0) or job_id in settings.DISABLE_CRON_JOBS:
2024-12-26 14:12:39 -05:00
logger.info(f"Skip disabled job {job_id}")
return
2024-12-26 14:12:39 -05:00
logger.info(f"Scheduling job {job_id} in {i}")
2023-10-21 05:41:38 +00:00
django_rq.get_queue("cron").enqueue_in(
2024-12-26 14:12:39 -05:00
i,
2023-11-11 20:33:55 -05:00
cls._run,
job_id=job_id,
result_ttl=-1,
failure_ttl=-1,
job_timeout=cls.interval.seconds - 5,
2023-10-21 05:41:38 +00:00
)
2024-12-26 14:12:39 -05:00
@classmethod
def reschedule(cls, now: bool = False):
cls.cancel()
cls.schedule(now=now)
2023-10-21 05:41:38 +00:00
@classmethod
def _run(cls):
cls.schedule() # schedule next run
cls().run()
def run(self):
pass
class JobManager:
2024-12-26 14:12:39 -05:00
registry: set[type[BaseJob]] = set()
2023-10-21 05:41:38 +00:00
@classmethod
def register(cls, target):
cls.registry.add(target)
return target
@classmethod
2024-12-26 14:12:39 -05:00
def get(cls, job_id) -> type[BaseJob]:
2023-10-21 05:41:38 +00:00
for j in cls.registry:
2024-12-26 14:12:39 -05:00
if j.__name__ == job_id:
return j
raise KeyError(f"Job not found: {job_id}")
2023-10-21 05:41:38 +00:00
@classmethod
2024-12-26 14:12:39 -05:00
def get_scheduled_job_ids(cls):
registry = ScheduledJobRegistry(queue=django_rq.get_queue("cron"))
return registry.get_job_ids()
2023-10-21 05:41:38 +00:00
@classmethod
2024-12-26 14:12:39 -05:00
def schedule_all(cls):
2023-10-21 05:41:38 +00:00
for j in cls.registry:
2024-12-26 14:12:39 -05:00
j.schedule()
2023-10-21 05:41:38 +00:00
@classmethod
2024-12-26 14:12:39 -05:00
def cancel_all(cls):
for j in cls.registry:
j.cancel()
2023-11-19 10:59:51 -05:00
@classmethod
2023-11-26 17:23:53 -05:00
def reschedule_all(cls):
cls.cancel_all()
cls.schedule_all()