1
- use serde:: { Deserialize , Serialize } ;
2
1
use thiserror:: Error ;
3
- use trailbase_apalis:: sqlite:: SqliteStorage ;
4
2
5
3
use crate :: data_dir:: DataDir ;
6
4
@@ -10,18 +8,71 @@ pub enum QueueError {
10
8
SqliteExtension ( #[ from] trailbase_extension:: Error ) ,
11
9
#[ error( "SQLite error: {0}" ) ]
12
10
Sqlite ( #[ from] trailbase_sqlite:: Error ) ,
11
+ #[ error( "IO error: {0}" ) ]
12
+ IO ( #[ from] std:: io:: Error ) ,
13
13
}
14
14
15
- #[ derive( Debug , Serialize , Deserialize ) ]
16
- pub enum Job {
17
- SendEmail ( ) ,
15
+ #[ cfg( feature = "queue" ) ]
16
+ pub ( crate ) mod queue_impl {
17
+ use log:: * ;
18
+ use serde:: { Deserialize , Serialize } ;
19
+
20
+ use super :: QueueError ;
21
+
22
+ #[ derive( Debug , Serialize , Deserialize ) ]
23
+ pub enum Job {
24
+ Something ( ) ,
25
+ }
26
+
27
+ pub async fn handle_job ( job : Job ) -> Result < ( ) , QueueError > {
28
+ match job {
29
+ Job :: Something ( ) => {
30
+ info ! ( "Queue got something" ) ;
31
+ }
32
+ }
33
+
34
+ return Ok ( ( ) ) ;
35
+ }
36
+
37
+ #[ cfg( feature = "queue" ) ]
38
+ pub ( crate ) type QueueStorage = trailbase_apalis:: sqlite:: SqliteStorage < Job > ;
18
39
}
19
40
20
- pub type QueueStorage = SqliteStorage < Job > ;
41
+ #[ derive( Clone ) ]
42
+ pub struct Queue {
43
+ #[ cfg( feature = "queue" ) ]
44
+ pub ( crate ) storage : queue_impl:: QueueStorage ,
45
+ }
46
+
47
+ impl Queue {
48
+ #[ allow( unused) ]
49
+ pub ( crate ) async fn new ( data_dir : Option < & DataDir > ) -> Result < Self , QueueError > {
50
+ return Ok ( Self {
51
+ #[ cfg( feature = "queue" ) ]
52
+ storage : init_queue_storage ( data_dir) . await ?,
53
+ } ) ;
54
+ }
55
+
56
+ #[ cfg( feature = "queue" ) ]
57
+ #[ allow( unused) ]
58
+ pub ( crate ) async fn run ( & self ) -> Result < ( ) , QueueError > {
59
+ use apalis:: prelude:: * ;
60
+
61
+ let monitor = Monitor :: new ( ) . register ( {
62
+ WorkerBuilder :: new ( "default-worker" )
63
+ // .enable_tracing()
64
+ . backend ( self . storage . clone ( ) )
65
+ . build_fn ( queue_impl:: handle_job)
66
+ } ) ;
67
+
68
+ return Ok ( monitor. run ( ) . await ?) ;
69
+ }
70
+ }
21
71
72
+ #[ cfg( feature = "queue" ) ]
22
73
pub ( crate ) async fn init_queue_storage (
23
74
data_dir : Option < & DataDir > ,
24
- ) -> Result < QueueStorage , QueueError > {
75
+ ) -> Result < queue_impl :: QueueStorage , QueueError > {
25
76
let queue_path = data_dir. map ( |d| d. queue_db_path ( ) ) ;
26
77
let conn = trailbase_sqlite:: Connection :: new (
27
78
|| -> Result < _ , trailbase_sqlite:: Error > {
@@ -34,8 +85,51 @@ pub(crate) async fn init_queue_storage(
34
85
None ,
35
86
) ?;
36
87
37
- SqliteStorage :: setup ( & conn) . await ?;
88
+ trailbase_apalis:: sqlite:: SqliteStorage :: setup ( & conn) . await ?;
89
+
90
+ let config = trailbase_apalis:: Config :: new ( "ns::trailbase" ) ;
91
+ return Ok ( queue_impl:: QueueStorage :: new_with_config ( conn, config) ) ;
92
+ }
93
+
94
+ #[ cfg( test) ]
95
+ #[ cfg( feature = "queue" ) ]
96
+ mod tests {
97
+ use super :: queue_impl:: * ;
98
+ use super :: * ;
99
+
100
+ use apalis:: prelude:: * ;
101
+
102
+ #[ tokio:: test]
103
+ async fn test_queue ( ) {
104
+ let mut queue = Queue :: new ( None ) . await . unwrap ( ) ;
105
+
106
+ let ( sender, receiver) = async_channel:: unbounded :: < ( ) > ( ) ;
107
+
108
+ let storage = queue. storage . clone ( ) ;
109
+ let _ = tokio:: spawn ( async move {
110
+ let monitor = Monitor :: new ( ) . register ( {
111
+ WorkerBuilder :: new ( "default-worker" )
112
+ . data ( sender)
113
+ . backend ( storage)
114
+ . build_fn (
115
+ async |job : Job , sender : Data < async_channel:: Sender < ( ) > > | -> Result < ( ) , QueueError > {
116
+ match job {
117
+ Job :: Something ( ) => sender. send ( ( ) ) . await . unwrap ( ) ,
118
+ }
119
+
120
+ return Ok ( ( ) ) ;
121
+ } ,
122
+ )
123
+ } ) ;
124
+
125
+ return monitor. run ( ) . await ;
126
+ } ) ;
127
+
128
+ let job = queue. storage . push ( Job :: Something ( ) ) . await . unwrap ( ) ;
129
+
130
+ let entry = queue. storage . fetch_by_id ( & job. task_id ) . await . unwrap ( ) ;
131
+ assert ! ( entry. is_some( ) ) ;
38
132
39
- let config = trailbase_apalis :: Config :: new ( "apalis::test" ) ;
40
- return Ok ( SqliteStorage :: new_with_config ( conn , config ) ) ;
133
+ receiver . recv ( ) . await . unwrap ( ) ;
134
+ }
41
135
}
0 commit comments