index : sfrs

A Standard Notes Sync Server written in Rust

diff options
authorPeter Cai <[email protected]>2020-02-23 11:22:08 +0800
committerPeter Cai <[email protected]>2020-02-23 11:22:08 +0800
commitd4c4be4d639f516732fb0227cf0ffdae6c5d641d (patch)
parentfb7beff3e035dd644ab2a2eab1b697304b3b9f45 (diff)
api: items/sync: explain why we need the per-user lock
1 files changed, 13 insertions, 0 deletions
diff --git a/src/ b/src/
index f0e8f97..186ee5d 100644
--- a/src/
+++ b/src/
@@ -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(;
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,