Skip to content

Commit b242d39

Browse files
committed
layout changes and batching
1 parent 34dfedb commit b242d39

File tree

7 files changed

+240
-261
lines changed

7 files changed

+240
-261
lines changed

Cargo.lock

Lines changed: 1 addition & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[workspace]
2-
members = ["usr-backend", "usr-backend-runner"]
2+
members = ["usr-backend"]

usr-backend-runner/Cargo.toml

Lines changed: 0 additions & 9 deletions
This file was deleted.

usr-backend-runner/src/main.rs

Lines changed: 0 additions & 26 deletions
This file was deleted.

usr-backend/src/manifest.rs

Lines changed: 87 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use std::
2-
sync::Arc
1+
use std::{collections::{hash_map::Entry, HashMap}, sync::{Arc, LazyLock}, time::Instant}
32
;
43

54
use axum::{
65
extract::State, http::StatusCode, response::{IntoResponse, Response}, routing::{delete, get, post}, Json, Router
76
};
87
use discord_webhook2::message::Message;
8+
use parking_lot::Mutex;
99
use sea_orm::{
1010
prelude::Decimal, sea_query::Table, sqlx::types::chrono::Local, ActiveModelTrait, ActiveValue, ConnectionTrait, DatabaseConnection, EntityTrait, Schema
1111
};
@@ -15,6 +15,14 @@ use tracing::error;
1515
use crate::{scheduler, UsrState};
1616

1717
mod order;
18+
struct BatchedTask {
19+
queue: HashMap<u32, String>,
20+
deadline: Option<Instant>,
21+
}
22+
static BATCHED: LazyLock<Mutex<BatchedTask>> = LazyLock::new(|| Mutex::new(BatchedTask {
23+
queue: HashMap::new(),
24+
deadline: None,
25+
}));
1826

1927
#[derive(Deserialize)]
2028
pub struct PendingOrder {
@@ -57,20 +65,67 @@ async fn new_order(
5765
vendor: ActiveValue::Set(pending_order.vendor),
5866
link: ActiveValue::Set(pending_order.link),
5967
};
60-
if let Err(e) = active_model.insert(&state.db).await {
61-
error!("Failed to create new order: {e}");
62-
(StatusCode::INTERNAL_SERVER_ERROR, "")
63-
} else {
64-
tokio::spawn(async move {
65-
if let Err(e) = state
66-
.new_orders_webhook
67-
.send(&Message::new(|message| message.content(webhook_msg)))
68-
.await
69-
{
70-
error!("Failed to trigger new-order webhook: {e}");
68+
match active_model.insert(&state.db).await {
69+
Ok(m) => {
70+
let mut guard = BATCHED.lock();
71+
guard.queue.insert(m.id, webhook_msg);
72+
let was_none = guard.deadline.is_none();
73+
guard.deadline = Some(Instant::now() + std::time::Duration::from_secs(60 * 5));
74+
75+
if was_none {
76+
drop(guard);
77+
78+
tokio::spawn(async move {
79+
loop {
80+
let deadline = BATCHED.lock().deadline.unwrap();
81+
tokio::time::sleep_until(deadline.into()).await;
82+
let queue;
83+
{
84+
let mut guard = BATCHED.lock();
85+
if guard.deadline.unwrap() != deadline {
86+
continue;
87+
}
88+
let replacement = HashMap::with_capacity(guard.queue.capacity());
89+
queue = std::mem::replace(&mut guard.queue, replacement);
90+
}
91+
let mut running = String::new();
92+
for (_, msg) in queue {
93+
if running.len() + msg.len() + 1 < 2000 {
94+
running.push_str(&msg);
95+
running.push_str("\n");
96+
} else {
97+
if let Err(e) = state
98+
.new_orders_webhook
99+
.send(&Message::new(|message| message.content(running)))
100+
.await
101+
{
102+
error!("Failed to trigger new-order webhook: {e}");
103+
}
104+
running = msg;
105+
}
106+
}
107+
if let Err(e) = state
108+
.new_orders_webhook
109+
.send(&Message::new(|message| message.content(running)))
110+
.await
111+
{
112+
error!("Failed to trigger new-order webhook: {e}");
113+
}
114+
let mut guard = BATCHED.lock();
115+
if guard.queue.is_empty() {
116+
guard.deadline = None;
117+
break;
118+
}
119+
}
120+
});
71121
}
72-
});
73-
(StatusCode::OK, "")
122+
123+
(StatusCode::OK, "")
124+
}
125+
Err(e) => {
126+
error!("Failed to create new order: {e}");
127+
(StatusCode::INTERNAL_SERVER_ERROR, "")
128+
}
74129
}
75130
}
76131

@@ -134,15 +189,24 @@ async fn change_order(
134189
error!("Failed to change order: {e}");
135190
(StatusCode::INTERNAL_SERVER_ERROR, "")
136191
} else {
137-
tokio::spawn(async move {
138-
if let Err(e) = state
139-
.new_orders_webhook
140-
.send(&Message::new(|message| message.content(webhook_msg)))
141-
.await
142-
{
143-
error!("Failed to trigger new-order webhook: {e}");
192+
let mut guard = BATCHED.lock();
193+
match guard.queue.entry(change_order.id) {
194+
Entry::Occupied(mut entry) => {
195+
entry.insert(webhook_msg);
144196
}
145-
});
197+
Entry::Vacant(_) => {
198+
tokio::spawn(async move {
199+
if let Err(e) = state
200+
.new_orders_webhook
201+
.send(&Message::new(|message| message.content(webhook_msg)))
202+
.await
203+
{
204+
error!("Failed to trigger new-order webhook: {e}");
205+
}
206+
});
207+
}
208+
}
209+
146210
(StatusCode::OK, "")
147211
}
148212
}

0 commit comments

Comments
 (0)