1
+ use crate :: background_job:: DEFAULT_QUEUE ;
1
2
use crate :: job_registry:: JobRegistry ;
2
3
use crate :: worker:: Worker ;
3
4
use crate :: { storage, BackgroundJob } ;
4
5
use anyhow:: anyhow;
5
6
use diesel:: prelude:: * ;
6
7
use diesel:: r2d2:: { ConnectionManager , Pool , PoolError , PooledConnection } ;
7
8
use futures_util:: future:: join_all;
9
+ use std:: collections:: HashMap ;
8
10
use std:: time:: Duration ;
9
11
use tokio:: runtime:: Handle ;
10
12
use tokio:: task:: JoinHandle ;
@@ -19,7 +21,7 @@ pub type PooledConn = PooledConnection<ConnectionManager<PgConnection>>;
19
21
pub struct Runner < Context > {
20
22
rt_handle : Handle ,
21
23
connection_pool : ConnectionPool ,
22
- queue : Queue < Context > ,
24
+ queues : HashMap < String , Queue < Context > > ,
23
25
context : Context ,
24
26
shutdown_when_queue_empty : bool ,
25
27
}
@@ -29,23 +31,34 @@ impl<Context: Clone + Send + 'static> Runner<Context> {
29
31
Self {
30
32
rt_handle : rt_handle. clone ( ) ,
31
33
connection_pool,
32
- queue : Queue :: default ( ) ,
34
+ queues : HashMap :: new ( ) ,
33
35
context,
34
36
shutdown_when_queue_empty : false ,
35
37
}
36
38
}
37
39
38
- pub fn configure_queue < F > ( mut self , f : F ) -> Self
40
+ /// Register a new job type for this job runner.
41
+ pub fn register_job_type < J : BackgroundJob < Context = Context > > ( mut self ) -> Self {
42
+ let queue = self . queues . entry ( J :: QUEUE . into ( ) ) . or_default ( ) ;
43
+ queue. job_registry . register :: < J > ( ) ;
44
+ self
45
+ }
46
+
47
+ /// Adjust the configuration of the [DEFAULT_QUEUE] queue.
48
+ pub fn configure_default_queue < F > ( self , f : F ) -> Self
39
49
where
40
50
F : FnOnce ( & mut Queue < Context > ) -> & Queue < Context > ,
41
51
{
42
- f ( & mut self . queue ) ;
43
- self
52
+ self . configure_queue ( DEFAULT_QUEUE , f)
44
53
}
45
54
46
- /// Register a new job type for this job runner.
47
- pub fn register_job_type < J : BackgroundJob < Context = Context > > ( mut self ) -> Self {
48
- self . queue . job_registry . register :: < J > ( ) ;
55
+ /// Adjust the configuration of a queue. If the queue does not exist,
56
+ /// it will be created.
57
+ pub fn configure_queue < F > ( mut self , name : & str , f : F ) -> Self
58
+ where
59
+ F : FnOnce ( & mut Queue < Context > ) -> & Queue < Context > ,
60
+ {
61
+ f ( self . queues . entry ( name. into ( ) ) . or_default ( ) ) ;
49
62
self
50
63
}
51
64
@@ -59,11 +72,10 @@ impl<Context: Clone + Send + 'static> Runner<Context> {
59
72
///
60
73
/// This returns a `RunningRunner` which can be used to wait for the workers to shutdown.
61
74
pub fn start ( & self ) -> RunHandle {
62
- let queue = & self . queue ;
63
-
64
- let handles = ( 0 ..queue. num_workers )
65
- . map ( |i| {
66
- let name = format ! ( "background-worker-{i}" ) ;
75
+ let mut handles = Vec :: new ( ) ;
76
+ for ( queue_name, queue) in & self . queues {
77
+ for i in 1 ..=queue. num_workers {
78
+ let name = format ! ( "background-worker-{queue_name}-{i}" ) ;
67
79
info ! ( worker. name = %name, "Starting worker…" ) ;
68
80
69
81
let worker = Worker {
@@ -74,11 +86,13 @@ impl<Context: Clone + Send + 'static> Runner<Context> {
74
86
poll_interval : queue. poll_interval ,
75
87
} ;
76
88
77
- self . rt_handle . spawn_blocking ( move || {
89
+ let handle = self . rt_handle . spawn_blocking ( move || {
78
90
info_span ! ( "worker" , worker. name = %name) . in_scope ( || worker. run ( ) )
79
- } )
80
- } )
81
- . collect ( ) ;
91
+ } ) ;
92
+
93
+ handles. push ( handle) ;
94
+ }
95
+ }
82
96
83
97
RunHandle { handles }
84
98
}
0 commit comments