index : sfrs

A Standard Notes Sync Server written in Rust

diff options
context:
space:
mode:
authorPeter Cai <[email protected]>2020-02-23 11:22:08 +0800
committerPeter Cai <[email protected]>2020-02-23 11:22:08 +0800
commitd4c4be4d639f516732fb0227cf0ffdae6c5d641d (patch)
tree81e098a465d2ddcc5418146af038eb0e051fd8da
parentfb7beff3e035dd644ab2a2eab1b697304b3b9f45 (diff)
downloadsfrs-d4c4be4d639f516732fb0227cf0ffdae6c5d641d.tar.gz
api: items/sync: explain why we need the per-user lock
-rw-r--r--src/api.rs13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/api.rs b/src/api.rs
index f0e8f97..186ee5d 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -198,11 +198,24 @@ fn items_sync(
u: user::User, params: Json<SyncParams>
) -> Custom<JsonResp<SyncResp>> {
// Only allow one sync per user at the same time
+ // Operations below are far from atomic (neither are they in Ruby or Go impl)
+ // so allowing multiple synchronize sessions each time can cause
+ // some confusing behavior, e.g. another sync session might insert
+ // something new into the database after this one gets the current_max_id
+ // but before this one returns. It can also mess things up during
+ // insertions into the database.
+ // In short, do not let the same user synchronize from two clients
+ // at the same time. All code below assumes that this lock works
+ // and at any given point in time, up to one sync process is running
+ // for each user.
let mutex = lock.get_mutex(u.id);
let _lock = mutex.lock().unwrap();
// sync_token should always be set to the maximum ID currently available
// (for this user, of course)
+ // Remember that we have a mutex at the beginning of this function,
+ // so all that can change the current_max_id for the current user
+ // is operations later in this function.
let new_sync_token = match item::SyncItem::get_current_max_id(&db, &u) {
Ok(Some(id)) => Some(id.to_string()),
Ok(None) => None,