1- use std:: { collections:: { hash_map:: Entry , HashMap } , sync:: { Arc , LazyLock } , time:: Instant }
2- ;
3-
41use axum:: {
52 extract:: State , http:: StatusCode , response:: { IntoResponse , Response } , routing:: { delete, get, post} , Json , Router
63} ;
7- use discord_webhook2:: message:: Message ;
8- use parking_lot:: Mutex ;
94use sea_orm:: {
105 prelude:: Decimal , sea_query:: Table , sqlx:: types:: chrono:: Local , ActiveModelTrait , ActiveValue , ColumnTrait , ConnectionTrait , DatabaseConnection , EntityTrait , QueryFilter , QueryOrder , Schema , TransactionTrait
116} ;
127use serde:: Deserialize ;
138use tracing:: error;
149
15- use crate :: { scheduler, UsrState } ;
10+ use crate :: { backup :: backup_db , scheduler, UsrState } ;
1611
1712mod order;
1813mod order_status;
1914
20- struct BatchedTask {
21- queue : HashMap < u32 , String > ,
22- deadline : Option < Instant > ,
23- }
24- static BATCHED : LazyLock < Mutex < BatchedTask > > = LazyLock :: new ( || Mutex :: new ( BatchedTask {
25- queue : HashMap :: new ( ) ,
26- deadline : None ,
27- } ) ) ;
28-
2915#[ derive( Deserialize ) ]
3016pub struct PendingOrder {
3117 pub name : String ,
@@ -40,7 +26,7 @@ pub struct PendingOrder {
4026
4127#[ axum:: debug_handler]
4228async fn new_order (
43- State ( state) : State < Arc < UsrState > > ,
29+ State ( state) : State < & ' static UsrState > ,
4430 Json ( pending_order) : Json < PendingOrder > ,
4531) -> ( StatusCode , & ' static str ) {
4632 let webhook_msg = format ! (
@@ -82,59 +68,8 @@ async fn new_order(
8268
8369 match result {
8470 Ok ( m) => {
85- let mut guard = BATCHED . lock ( ) ;
86- guard. queue . insert ( m. id , webhook_msg) ;
87- let was_none = guard. deadline . is_none ( ) ;
88- guard. deadline = Some ( Instant :: now ( ) + std:: time:: Duration :: from_secs ( 60 * 5 ) ) ;
89-
90- if was_none {
91- drop ( guard) ;
92- if state. new_orders_webhook . is_some ( ) {
93- tokio:: spawn ( async move {
94- let new_orders_webhook = state. new_orders_webhook . as_ref ( ) . unwrap ( ) ;
95- loop {
96- let deadline = BATCHED . lock ( ) . deadline . unwrap ( ) ;
97- tokio:: time:: sleep_until ( deadline. into ( ) ) . await ;
98- let queue;
99- {
100- let mut guard = BATCHED . lock ( ) ;
101- if guard. deadline . unwrap ( ) != deadline {
102- continue ;
103- }
104- let replacement = HashMap :: with_capacity ( guard. queue . capacity ( ) ) ;
105- queue = std:: mem:: replace ( & mut guard. queue , replacement) ;
106- }
107- let mut running = String :: new ( ) ;
108- for ( _, msg) in queue {
109- if running. len ( ) + msg. len ( ) + 1 < 2000 {
110- running. push_str ( & msg) ;
111- running. push_str ( "\n " ) ;
112- } else {
113- if let Err ( e) = new_orders_webhook
114- . send ( & Message :: new ( |message| message. content ( running) ) )
115- . await
116- {
117- error ! ( "Failed to trigger new-order webhook: {e}" ) ;
118- }
119- running = msg;
120- }
121- }
122- if let Err ( e) = new_orders_webhook
123- . send ( & Message :: new ( |message| message. content ( running) ) )
124- . await
125- {
126- error ! ( "Failed to trigger new-order webhook: {e}" ) ;
127- }
128- let mut guard = BATCHED . lock ( ) ;
129- if guard. queue . is_empty ( ) {
130- guard. deadline = None ;
131- break ;
132- }
133- }
134- } ) ;
135- }
136- }
137-
71+ backup_db ( state) ;
72+ state. new_orders_webhook . as_ref ( ) . map ( |x| x. enqueue ( m. id , webhook_msg) ) ;
13873 ( StatusCode :: OK , "" )
13974 }
14075 Err ( e) => {
@@ -159,7 +94,7 @@ pub struct ChangeOrder {
15994
16095#[ axum:: debug_handler]
16196async fn change_order (
162- State ( state) : State < Arc < UsrState > > ,
97+ State ( state) : State < & ' static UsrState > ,
16398 Json ( change_order) : Json < ChangeOrder > ,
16499) -> ( StatusCode , & ' static str ) {
165100 match order_status:: Entity :: find ( ) . filter ( order_status:: Column :: OrderId . eq ( change_order. id ) ) . order_by_desc ( order_status:: Column :: InstanceId ) . one ( & state. db ) . await {
@@ -202,23 +137,25 @@ async fn change_order(
202137 error ! ( "Failed to change order: {e}" ) ;
203138 ( StatusCode :: INTERNAL_SERVER_ERROR , "" )
204139 } else {
205- let mut guard = BATCHED . lock ( ) ;
206- match guard. queue . entry ( change_order. id ) {
207- Entry :: Occupied ( mut entry) => {
208- entry. insert ( webhook_msg) ;
209- }
210- Entry :: Vacant ( _) => {
211- tokio:: spawn ( async move {
212- let Some ( new_orders_webhook) = state. new_orders_webhook . as_ref ( ) else { return ; } ;
213- if let Err ( e) = new_orders_webhook
214- . send ( & Message :: new ( |message| message. content ( webhook_msg) ) )
215- . await
216- {
217- error ! ( "Failed to trigger new-order webhook: {e}" ) ;
218- }
219- } ) ;
220- }
221- }
140+ backup_db ( state) ;
141+ state. new_orders_webhook . as_ref ( ) . map ( |x| x. enqueue ( change_order. id , webhook_msg) ) ;
142+ // let mut guard = BATCHED.lock();
143+ // match guard.queue.entry(change_order.id) {
144+ // Entry::Occupied(mut entry) => {
145+ // entry.insert(webhook_msg);
146+ // }
147+ // Entry::Vacant(_) => {
148+ // tokio::spawn(async move {
149+ // let Some(new_orders_webhook) = state.new_orders_webhook.as_ref() else { return; };
150+ // if let Err(e) = new_orders_webhook
151+ // .send(&Message::new(|message| message.content(webhook_msg)))
152+ // .await
153+ // {
154+ // error!("Failed to trigger new-order webhook: {e}");
155+ // }
156+ // });
157+ // }
158+ // }
222159
223160 ( StatusCode :: OK , "" )
224161 }
@@ -233,7 +170,7 @@ struct DeleteOrder {
233170
234171#[ axum:: debug_handler]
235172async fn cancel_order (
236- State ( state) : State < Arc < UsrState > > ,
173+ State ( state) : State < & ' static UsrState > ,
237174 Json ( DeleteOrder { id, force } ) : Json < DeleteOrder > ,
238175) -> ( StatusCode , & ' static str ) {
239176 let webhook_msg;
@@ -284,15 +221,8 @@ async fn cancel_order(
284221 return ( StatusCode :: INTERNAL_SERVER_ERROR , "" ) ;
285222 }
286223
287- tokio:: spawn ( async move {
288- let Some ( new_orders_webhook) = state. new_orders_webhook . as_ref ( ) else { return ; } ;
289- if let Err ( e) = new_orders_webhook
290- . send ( & Message :: new ( |message| message. content ( webhook_msg) ) )
291- . await
292- {
293- error ! ( "Failed to trigger new-order webhook: {e}" ) ;
294- }
295- } ) ;
224+ state. new_orders_webhook . as_ref ( ) . map ( |x| x. enqueue ( id, webhook_msg) ) ;
225+ backup_db ( state) ;
296226
297227 ( StatusCode :: OK , "" )
298228}
@@ -305,7 +235,7 @@ pub struct UpdateOrder {
305235
306236#[ axum:: debug_handler]
307237async fn update_order (
308- State ( state) : State < Arc < UsrState > > ,
238+ State ( state) : State < & ' static UsrState > ,
309239 Json ( update_order) : Json < UpdateOrder > ,
310240) -> ( StatusCode , & ' static str ) {
311241 let webhook_msg;
@@ -369,22 +299,15 @@ async fn update_order(
369299 error ! ( "Failed to update order status: {e}" ) ;
370300 ( StatusCode :: INTERNAL_SERVER_ERROR , "" )
371301 } else {
372- tokio:: spawn ( async move {
373- let Some ( order_updates_webhook) = state. order_updates_webhook . as_ref ( ) else { return ; } ;
374- if let Err ( e) = order_updates_webhook
375- . send ( & Message :: new ( |message| message. content ( webhook_msg) ) )
376- . await
377- {
378- error ! ( "Failed to trigger order-updates webhook: {e}" ) ;
379- }
380- } ) ;
302+ state. order_updates_webhook . as_ref ( ) . map ( |x| x. enqueue ( update_order. id , webhook_msg) ) ;
303+ backup_db ( state) ;
381304 ( StatusCode :: OK , "" )
382305 }
383306}
384307
385308#[ axum:: debug_handler]
386309async fn get_orders (
387- State ( state) : State < Arc < UsrState > > ,
310+ State ( state) : State < & ' static UsrState > ,
388311) -> Response {
389312 let result = order:: Entity :: find ( ) . all ( & state. db ) . await ;
390313
@@ -412,7 +335,7 @@ async fn get_orders(
412335 }
413336}
414337
415- pub fn router ( ) -> Router < Arc < UsrState > > {
338+ pub fn router ( ) -> Router < & ' static UsrState > {
416339 Router :: new ( )
417340 . route ( "/new/order" , post ( new_order) )
418341 . route ( "/change/order" , post ( change_order) )
0 commit comments