only allow one sync per user every time

This commit is contained in:
Peter Cai 2020-02-22 10:45:06 +08:00
parent 915f9893a5
commit 8388d73505
No known key found for this signature in database
GPG Key ID: 71F5FB4E4F3FD54F
3 changed files with 35 additions and 1 deletions

View File

@ -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![],

23
src/lock.rs Normal file
View 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()
}
}

View File

@ -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)
}