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::DbConn;
|
||||||
use crate::user;
|
use crate::user;
|
||||||
use crate::item;
|
use crate::item;
|
||||||
|
use crate::lock::UserLock;
|
||||||
|
use rocket::State;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::response::status::Custom;
|
use rocket::response::status::Custom;
|
||||||
use rocket_contrib::json::Json;
|
use rocket_contrib::json::Json;
|
||||||
|
@ -180,7 +182,14 @@ struct SyncResp {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/items/sync", format = "json", data = "<params>")]
|
#[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 {
|
let mut resp = SyncResp {
|
||||||
retrieved_items: vec![],
|
retrieved_items: vec![],
|
||||||
saved_items: vec![],
|
saved_items: vec![],
|
||||||
|
|
23
src/lock.rs
Normal file
23
src/lock.rs
Normal file
|
@ -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 tokens;
|
||||||
mod user;
|
mod user;
|
||||||
mod item;
|
mod item;
|
||||||
|
mod lock;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -126,6 +127,7 @@ pub fn build_rocket() -> Rocket {
|
||||||
let r = rocket::custom(build_config())
|
let r = rocket::custom(build_config())
|
||||||
.attach(cors)
|
.attach(cors)
|
||||||
.attach(DbConn::fairing())
|
.attach(DbConn::fairing())
|
||||||
|
.manage(lock::UserLock::new())
|
||||||
.mount("/", api::routes());
|
.mount("/", api::routes());
|
||||||
run_db_migrations(r)
|
run_db_migrations(r)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue