33import traceback
44from datetime import datetime
55from enum import Enum
6+ from logging import DEBUG , INFO
67from threading import Thread
78from typing import List , Set , Optional , Sequence , Dict
89
910import django
1011
1112from scheduler .helpers .queues import Queue
1213from scheduler .helpers .queues import get_queue
14+ from scheduler .helpers .queues .getters import get_queue_connection
1315from scheduler .helpers .utils import current_timestamp
1416from scheduler .models import Task
1517from scheduler .redis_models import SchedulerLock , JobModel , ScheduledJobRegistry
1618from scheduler .settings import SCHEDULER_CONFIG , logger
17- from scheduler .types import ConnectionType
1819
1920
2021class SchedulerStatus (str , Enum ):
@@ -31,22 +32,15 @@ def _reschedule_tasks() -> None:
3132
3233
3334class WorkerScheduler :
34- def __init__ (
35- self ,
36- queues : Sequence [Queue ],
37- connection : ConnectionType ,
38- worker_name : str ,
39- interval : Optional [int ] = None ,
40- ) -> None :
41- interval = interval or SCHEDULER_CONFIG .SCHEDULER_INTERVAL
35+ def __init__ (self , queues : Sequence [Queue ], worker_name : str , interval : Optional [int ] = None ) -> None :
4236 self ._queues = queues
37+ if len (queues ) == 0 :
38+ raise ValueError ("At least one queue must be provided to WorkerScheduler" )
4339 self ._scheduled_job_registries : List [ScheduledJobRegistry ] = []
4440 self .lock_acquisition_time : Optional [datetime ] = None
45- self ._pool_class = connection .connection_pool .connection_class
46- self ._pool_kwargs = connection .connection_pool .connection_kwargs .copy ()
4741 self ._locks : Dict [str , SchedulerLock ] = dict ()
48- self .connection = connection
49- self .interval = interval
42+ self .connection = get_queue_connection ( queues [ 0 ]. name )
43+ self .interval = interval or SCHEDULER_CONFIG . SCHEDULER_INTERVAL
5044 self ._stop_requested = False
5145 self .status = SchedulerStatus .STOPPED
5246 self ._thread : Optional [Thread ] = None
@@ -57,6 +51,9 @@ def __init__(
5751 def pid (self ) -> Optional [int ]:
5852 return self ._pid
5953
54+ def log (self , level : int , message : str , * args , ** kwargs ) -> None :
55+ logger .log (level , f"[Scheduler { self .worker_name } /{ self ._pid } ]: { message } " , * args , ** kwargs )
56+
6057 def _should_reacquire_locks (self ) -> bool :
6158 """Returns True if lock_acquisition_time is longer than 10 minutes ago"""
6259 if not self .lock_acquisition_time :
@@ -70,12 +67,10 @@ def _acquire_locks(self) -> Set[str]:
7067 if self .pid is None :
7168 self ._pid = os .getpid ()
7269 queue_names = [queue .name for queue in self ._queues ]
73- logger .debug (
74- f"""[Scheduler { self .worker_name } /{ self .pid } ] Trying to acquire locks for { ", " .join (queue_names )} """
75- )
70+ self .log (DEBUG , f"""Trying to acquire locks for { ", " .join (queue_names )} """ )
7671 for queue in self ._queues :
7772 lock = SchedulerLock (queue .name )
78- if lock .acquire (self .pid , connection = queue .connection , expire = self .interval + 60 ):
73+ if lock .acquire (self .pid , connection = self .connection , expire = self .interval + 60 ):
7974 self ._locks [queue .name ] = lock
8075 successful_locks .add (queue .name )
8176
@@ -85,7 +80,7 @@ def _acquire_locks(self) -> Set[str]:
8580 for queue_name in self ._locks :
8681 queue = get_queue (queue_name )
8782 self ._scheduled_job_registries .append (queue .scheduled_job_registry )
88- logger . debug ( f"[Scheduler { self . worker_name } / { self . pid } ] Locks acquired for { ', ' .join (self ._locks .keys ())} " )
83+ self . log ( DEBUG , f" Locks acquired for { ', ' .join (self ._locks .keys ())} " )
8984 return successful_locks
9085
9186 def start (self ) -> None :
@@ -98,24 +93,22 @@ def start(self) -> None:
9893
9994 def request_stop_and_wait (self ) -> None :
10095 """Toggle self._stop_requested that's checked on every loop"""
101- logger . debug ( f"[Scheduler { self . worker_name } / { self . pid } ] Stop Scheduler requested" )
96+ self . log ( DEBUG , f" Stop Scheduler requested" )
10297 self ._stop_requested = True
10398 if self ._thread is not None :
10499 self ._thread .join ()
105100
106101 def heartbeat (self ) -> None :
107102 """Updates the TTL on scheduler keys and the locks"""
108103 lock_keys = ", " .join (self ._locks .keys ())
109- logger . debug ( f"[Scheduler { self . worker_name } / { self . pid } ] Scheduler updating lock for queue { lock_keys } " )
104+ self . log ( DEBUG , f" Scheduler updating lock for queue { lock_keys } " )
110105 with self .connection .pipeline () as pipeline :
111106 for lock in self ._locks .values ():
112107 lock .expire (self .connection , expire = self .interval + 60 )
113108 pipeline .execute ()
114109
115110 def stop (self ) -> None :
116- logger .info (
117- f"[Scheduler { self .worker_name } /{ self .pid } ] Stopping scheduler, releasing locks for { ', ' .join (self ._locks .keys ())} ..."
118- )
111+ self .log (INFO , f"Stopping scheduler, releasing locks for { ', ' .join (self ._locks .keys ())} ..." )
119112 self .release_locks ()
120113 self .status = SchedulerStatus .STOPPED
121114
@@ -128,7 +121,7 @@ def release_locks(self) -> None:
128121
129122 def work (self ) -> None :
130123 queue_names = [queue .name for queue in self ._queues ]
131- logger . info ( f"""[Scheduler { self . worker_name } / { self . pid } ] Scheduler for { ", " .join (queue_names )} started""" )
124+ self . log ( INFO , f"""Scheduler for { ", " .join (queue_names )} started""" )
132125 django .setup ()
133126
134127 while True :
0 commit comments