22import sys
33from datetime import datetime , timedelta
44from logging import basicConfig , getLevelName , getLogger
5- from typing import List , Optional
5+ from typing import Dict , List , Optional
66
77import pytz
88from pycron import is_now
99
10+ from taskiq .abc .schedule_source import ScheduleSource
1011from taskiq .cli .scheduler .args import SchedulerArgs
1112from taskiq .cli .utils import import_object , import_tasks
1213from taskiq .scheduler .scheduler import ScheduledTask , TaskiqScheduler
@@ -32,7 +33,7 @@ def to_tz_aware(time: datetime) -> datetime:
3233
3334async def schedules_updater (
3435 scheduler : TaskiqScheduler ,
35- current_schedules : List [ScheduledTask ],
36+ current_schedules : Dict [ ScheduleSource , List [ScheduledTask ] ],
3637 event : asyncio .Event ,
3738) -> None :
3839 """
@@ -48,7 +49,7 @@ async def schedules_updater(
4849 """
4950 while True :
5051 logger .debug ("Started schedule update." )
51- new_schedules : "List[ScheduledTask]" = []
52+ new_schedules : "Dict[ScheduleSource, List[ScheduledTask]] " = {}
5253 for source in scheduler .sources :
5354 try :
5455 schedules = await source .get_schedules ()
@@ -60,10 +61,13 @@ async def schedules_updater(
6061 logger .debug (exc , exc_info = True )
6162 continue
6263
63- new_schedules = scheduler .merge_func (new_schedules , schedules )
64+ new_schedules [source ] = scheduler .merge_func (
65+ new_schedules .get (source ) or [],
66+ schedules ,
67+ )
6468
6569 current_schedules .clear ()
66- current_schedules .extend (new_schedules )
70+ current_schedules .update (new_schedules )
6771 event .set ()
6872 await asyncio .sleep (scheduler .refresh_delay )
6973
@@ -100,6 +104,7 @@ def get_task_delay(task: ScheduledTask) -> Optional[int]:
100104
101105async def delayed_send (
102106 scheduler : TaskiqScheduler ,
107+ source : ScheduleSource ,
103108 task : ScheduledTask ,
104109 delay : int ,
105110) -> None :
@@ -115,13 +120,14 @@ async def delayed_send(
115120 the delay and send the task after some delay.
116121
117122 :param scheduler: current scheduler.
123+ :param source: source of the task.
118124 :param task: task to send.
119125 :param delay: how long to wait.
120126 """
121127 if delay > 0 :
122128 await asyncio .sleep (delay )
123129 logger .info ("Sending task %s." , task .task_name )
124- await scheduler .on_ready (task )
130+ await scheduler .on_ready (source , task )
125131
126132
127133async def run_scheduler_loop (scheduler : TaskiqScheduler ) -> None :
@@ -134,33 +140,34 @@ async def run_scheduler_loop(scheduler: TaskiqScheduler) -> None:
134140 :param scheduler: current scheduler.
135141 """
136142 loop = asyncio .get_event_loop ()
137- tasks : "List[ScheduledTask]" = []
143+ schedules : "Dict[ScheduleSource, List[ScheduledTask]] " = {}
138144
139145 current_task = asyncio .current_task ()
140146 first_update_event = asyncio .Event ()
141147 updater_task = loop .create_task (
142148 schedules_updater (
143149 scheduler ,
144- tasks ,
150+ schedules ,
145151 first_update_event ,
146152 ),
147153 )
148154 if current_task is not None :
149155 current_task .add_done_callback (lambda _ : updater_task .cancel ())
150156 await first_update_event .wait ()
151157 while True :
152- for task in tasks :
153- try :
154- task_delay = get_task_delay (task )
155- except ValueError :
156- logger .warning (
157- "Cannot parse cron: %s for task: %s" ,
158- task .cron ,
159- task .task_name ,
160- )
161- continue
162- if task_delay is not None :
163- loop .create_task (delayed_send (scheduler , task , task_delay ))
158+ for source , task_list in schedules .items ():
159+ for task in task_list :
160+ try :
161+ task_delay = get_task_delay (task )
162+ except ValueError :
163+ logger .warning (
164+ "Cannot parse cron: %s for task: %s" ,
165+ task .cron ,
166+ task .task_name ,
167+ )
168+ continue
169+ if task_delay is not None :
170+ loop .create_task (delayed_send (scheduler , source , task , task_delay ))
164171
165172 delay = (
166173 datetime .now ().replace (second = 1 , microsecond = 0 )
0 commit comments