websocket for single db update

This commit is contained in:
2025-09-26 04:05:22 +02:00
parent 65146fce91
commit a3b55f00df
6 changed files with 38 additions and 23 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -21,9 +21,12 @@ use crate::utils::auth::JwtKeys;
#[tokio::main] #[tokio::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
let hotel_pools = HotelPool::new(); let hotel_pools = HotelPool::new();
let logs_manager = SqliteConnectionManager::file("db/auth.sqlite"); let logs_manager = SqliteConnectionManager::file("db/auth.sqlite");
let logs_pool = Pool::builder() let logs_pool = Pool::builder()
@@ -31,13 +34,6 @@ async fn main() -> std::io::Result<()> {
.build(logs_manager) .build(logs_manager)
.expect("Failed to build logs pool"); .expect("Failed to build logs pool");
type UserMap = DashMap<i32, mpsc::UnboundedSender<Message>>;
/// hotel_id → users
type HotelMap = DashMap<i32, Arc<UserMap>>;
/// global map of all hotels
type WsMap = Arc<HotelMap>;
let state = AppState { let state = AppState {
hotel_pools, hotel_pools,
logs_pool, logs_pool,

View File

@@ -1,6 +1,8 @@
use axum::{Json, extract::Path, extract::State }; use axum::{Json, extract::Path, extract::State };
use axum::response::IntoResponse; use axum::response::IntoResponse;
use axum::http::StatusCode; use axum::http::StatusCode;
use axum::extract::ws::Message;
use serde_json::json;
use crate::rooms::extractor::UpdateRoomPayload; use crate::rooms::extractor::UpdateRoomPayload;
//use crate::utils::db_pool::*; //use crate::utils::db_pool::*;
@@ -85,7 +87,25 @@ pub async fn clean_db_update(
); );
match result { match result {
Ok(rows) if rows > 0 => (StatusCode::OK, format!("updated room {room_id} in hotel{}, with status : {}", hotel_id, payload.status )), Ok(rows) if rows > 0 => {
// --- broadcast to all WS clients in the hotel ---
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
let update_msg = json!({
"room_id": room_id,
"status": payload.status,
"updated_by": user_id,
})
.to_string();
for entry in hotel_users.iter() {
let sender = entry.value();
// ignore errors (client disconnected)
let _ = sender.send(Message::Text(update_msg.clone().into()));
}
}
(StatusCode::OK, format!("updated room {room_id} in hotel {hotel_id}, with status: {}", payload.status))
}
Ok(_) => (StatusCode::NOT_FOUND, "No room found".to_string()), Ok(_) => (StatusCode::NOT_FOUND, "No room found".to_string()),
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error from DB: {err}")), Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error from DB: {err}")),
} }

View File

@@ -5,19 +5,18 @@ use r2d2_sqlite::SqliteConnectionManager;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use axum::extract::{ws::{Message, WebSocket, WebSocketUpgrade}, State}; use axum::extract::{ws::{Message, WebSocket, WebSocketUpgrade}, State};
type HotelId = i32; // or i32 if you want numeric ids use crate::utils::websocket::WsMap;
#[derive(Clone)] #[derive(Clone)]
pub struct AppState { pub struct AppState {
pub hotel_pools: HotelPool, pub hotel_pools: HotelPool,
pub logs_pool: Pool<SqliteConnectionManager>, pub logs_pool: Pool<SqliteConnectionManager>,
pub ws_map: WsMap, pub ws_map: WsMap,
} }
type HotelId = i32; // or i32 if you want numeric ids
#[derive(Clone)] #[derive(Clone)]
pub struct HotelPool { pub struct HotelPool {
hotel_pools: Arc<DashMap<HotelId, Pool<SqliteConnectionManager>>>, hotel_pools: Arc<DashMap<HotelId, Pool<SqliteConnectionManager>>>,

View File

@@ -12,11 +12,11 @@ use crate::utils::{auth::AuthClaims, db_pool::{AppState, HotelPool}};
/// Type alias: user_id → sender to that user /// Type alias: user_id → sender to that user
type UserMap = DashMap<i32, mpsc::UnboundedSender<Message>>; pub type UserMap = DashMap<i32, mpsc::UnboundedSender<Message>>;
/// hotel_id → users /// hotel_id → users
type HotelMap = DashMap<i32, Arc<UserMap>>; pub type HotelMap = DashMap<i32, Arc<UserMap>>;
/// global map of all hotels /// global map of all hotels
type WsMap = Arc<HotelMap>; pub type WsMap = Arc<HotelMap>;
/// Type alias: user_id → sender to that user /// Type alias: user_id → sender to that user