57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
import logging
|
|
import os
|
|
import time
|
|
from multiprocessing import Process
|
|
|
|
from django.conf import settings
|
|
from django.db import connections
|
|
from schedule import Scheduler
|
|
|
|
from awx.main.dispatch.worker import TaskWorker
|
|
|
|
logger = logging.getLogger('awx.main.dispatch.periodic')
|
|
|
|
|
|
class Scheduler(Scheduler):
|
|
|
|
def run_continuously(self):
|
|
idle_seconds = max(
|
|
1,
|
|
min(self.jobs).period.total_seconds() / 2
|
|
)
|
|
|
|
def run():
|
|
ppid = os.getppid()
|
|
logger.warn('periodic beat started')
|
|
while True:
|
|
if os.getppid() != ppid:
|
|
# if the parent PID changes, this process has been orphaned
|
|
# via e.g., segfault or sigkill, we should exit too
|
|
pid = os.getpid()
|
|
logger.warn(f'periodic beat exiting gracefully pid:{pid}')
|
|
raise SystemExit()
|
|
try:
|
|
for conn in connections.all():
|
|
# If the database connection has a hiccup, re-establish a new
|
|
# connection
|
|
conn.close_if_unusable_or_obsolete()
|
|
self.run_pending()
|
|
except Exception:
|
|
logger.exception(
|
|
'encountered an error while scheduling periodic tasks'
|
|
)
|
|
time.sleep(idle_seconds)
|
|
|
|
process = Process(target=run)
|
|
process.daemon = True
|
|
process.start()
|
|
|
|
|
|
def run_continuously():
|
|
scheduler = Scheduler()
|
|
for task in settings.CELERYBEAT_SCHEDULE.values():
|
|
apply_async = TaskWorker.resolve_callable(task['task']).apply_async
|
|
total_seconds = task['schedule'].total_seconds()
|
|
scheduler.every(total_seconds).seconds.do(apply_async)
|
|
scheduler.run_continuously()
|