@@ -241,3 +241,82 @@ def test_workflow(var1: str, var2: str) -> float:
241241
242242 # Verify all queue entries eventually get cleaned up.
243243 assert queue_entries_are_cleaned_up (dbos )
244+
245+
246+ def test_multiple_queues (dbos : DBOS ) -> None :
247+
248+ wf_counter = 0
249+ flag = False
250+ workflow_event = threading .Event ()
251+ main_thread_event = threading .Event ()
252+
253+ @DBOS .workflow ()
254+ def workflow_one () -> None :
255+ nonlocal wf_counter
256+ wf_counter += 1
257+ main_thread_event .set ()
258+ workflow_event .wait ()
259+
260+ @DBOS .workflow ()
261+ def workflow_two () -> None :
262+ nonlocal flag
263+ flag = True
264+
265+ concurrency_queue = Queue ("test_concurrency_queue" , 1 )
266+ handle1 = concurrency_queue .enqueue (workflow_one )
267+ assert handle1 .get_status ().queue_name == "test_concurrency_queue"
268+ handle2 = concurrency_queue .enqueue (workflow_two )
269+
270+ @DBOS .workflow ()
271+ def limited_workflow (var1 : str , var2 : str ) -> float :
272+ assert var1 == "abc" and var2 == "123"
273+ return time .time ()
274+
275+ limit = 5
276+ period = 2
277+ limiter_queue = Queue (
278+ "test_limit_queue" , limiter = {"limit" : limit , "period" : period }
279+ )
280+
281+ handles : list [WorkflowHandle [float ]] = []
282+ times : list [float ] = []
283+
284+ # Launch a number of tasks equal to three times the limit.
285+ # This should lead to three "waves" of the limit tasks being
286+ # executed simultaneously, followed by a wait of the period,
287+ # followed by the next wave.
288+ num_waves = 3
289+ for _ in range (limit * num_waves ):
290+ h = limiter_queue .enqueue (limited_workflow , "abc" , "123" )
291+ handles .append (h )
292+ for h in handles :
293+ times .append (h .get_result ())
294+
295+ # Verify that each "wave" of tasks started at the ~same time.
296+ for wave in range (num_waves ):
297+ for i in range (wave * limit , (wave + 1 ) * limit - 1 ):
298+ assert times [i + 1 ] - times [i ] < 0.2
299+
300+ # Verify that the gap between "waves" is ~equal to the period
301+ for wave in range (num_waves - 1 ):
302+ assert times [limit * (wave + 1 )] - times [limit * wave ] > period - 0.2
303+ assert times [limit * (wave + 1 )] - times [limit * wave ] < period + 0.2
304+
305+ # Verify all workflows get the SUCCESS status eventually
306+ dbos ._sys_db .wait_for_buffer_flush ()
307+ for h in handles :
308+ assert h .get_status ().status == WorkflowStatusString .SUCCESS .value
309+
310+ # Verify that during all this time, the second task
311+ # was not launched on the concurrency-limited queue.
312+ # Then, finish the first task and verify the second
313+ # task runs on schedule.
314+ assert not flag
315+ workflow_event .set ()
316+ assert handle1 .get_result () == None
317+ assert handle2 .get_result () == None
318+ assert flag
319+ assert wf_counter == 1
320+
321+ # Verify all queue entries eventually get cleaned up.
322+ assert queue_entries_are_cleaned_up (dbos )
0 commit comments