only allow one sync per user every time
This commit is contained in:
parent
915f9893a5
commit
8388d73505
11
src/api.rs
11
src/api.rs
|
@ -1,6 +1,8 @@
|
|||
use crate::DbConn;
|
||||
use crate::user;
|
||||
use crate::item;
|
||||
use crate::lock::UserLock;
|
||||
use rocket::State;
|
||||
use rocket::http::Status;
|
||||
use rocket::response::status::Custom;
|
||||
use rocket_contrib::json::Json;
|
||||
|
@ -180,7 +182,14 @@ struct SyncResp {
|
|||
}
|
||||
|
||||
#[post("/items/sync", format = "json", data = "<params>")]
|
||||
fn items_sync(db: DbConn, u: user::User, params: Json<SyncParams>) -> Custom<JsonResp<SyncResp>> {
|
||||
fn items_sync(
|
||||
db: DbConn, lock: State<UserLock>,
|
||||
u: user::User, params: Json<SyncParams>
|
||||
) -> Custom<JsonResp<SyncResp>> {
|
||||
// Only allow one sync per user at the same time
|
||||
let mutex = lock.get_mutex(u.id);
|
||||
let _lock = mutex.lock().unwrap();
|
||||
|
||||
let mut resp = SyncResp {
|
||||
retrieved_items: vec![],
|
||||
saved_items: vec![],
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock, Mutex};
|
||||
|
||||
// A per-user lock used for sync requests
|
||||
pub struct UserLock {
|
||||
lock_map: RwLock<HashMap<i32, Arc<Mutex<()>>>>
|
||||
}
|
||||
|
||||
impl UserLock {
|
||||
pub fn new() -> UserLock {
|
||||
UserLock {
|
||||
lock_map: RwLock::new(HashMap::new())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mutex(&self, uid: i32) -> Arc<Mutex<()>> {
|
||||
if !self.lock_map.read().unwrap().contains_key(&uid) {
|
||||
self.lock_map.write().unwrap().insert(uid, Arc::new(Mutex::new(())));
|
||||
}
|
||||
|
||||
self.lock_map.read().unwrap().get(&uid).unwrap().clone()
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ mod api;
|
|||
mod tokens;
|
||||
mod user;
|
||||
mod item;
|
||||
mod lock;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
@ -126,6 +127,7 @@ pub fn build_rocket() -> Rocket {
|
|||
let r = rocket::custom(build_config())
|
||||
.attach(cors)
|
||||
.attach(DbConn::fairing())
|
||||
.manage(lock::UserLock::new())
|
||||
.mount("/", api::routes());
|
||||
run_db_migrations(r)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue