I’m implementing a sync algorithm where multiple apps sync files with a data source. Syncing is already working and has been for several years so there’s no issue with this.
Now I want to implement a way to lock the data source, to tell clients that they shouldn’t write to it anymore. This will be used to upgrade the data source – i.e. upgrade its structure, move folders around, etc. which needs to be done when nothing else is syncing.
So I came up with the following algorithm, inspired by [SQLite 3 locking mechanism], but changed to take into account that it’s network based.
There are three types of locks, and a client request a lock by POSTing a file to the data source. The locks are:
- SYNCING: The client is syncing – any other client can still read or write to the data source. There can be multiple SYNCING locks.
- PENDING: The client wants to acquire an exclusive lock on the data source – any other clients can still read or write to the data source, but no new SYNCING lock can be posted. There can be multiple PENDING locks.
- EXCLUSIVE: The client has locked the data source – no other client can read or write to it. There can be only one EXCLUSIVE lock.
And it would work like so:
- When a client starts syncing with the data source, they acquire a SYNCING lock. When a client finishes syncing, they release the SYNCING lock they’ve created
- When a client needs to lock the data source, it first posts a PENDING lock. When a PENDING lock is present, no new SYNCING or PENDING locks can be posted. Clients that are syncing however can complete the process. The client who has acquired a PENDING lock will poll the data source and wait for all SYNCING lock to be released. When they are all gone, the client checks for all the PENDING locks – if there are others, the client checks the timestamps of these other locks and if his lock is not the oldest one, it deletes it and exit. Locking failed, and it will need to try again later.
- If the PENDING lock is the oldest, then the client posts an EXCLUSIVE lock. At this point, no other client can post any other lock.
I’m wondering if I overlook something with this system, like I’m wondering if there could be some race conditions in some cases?
For now, I’m not dealing with clients that post a lock then crash, there will be some logic to clean up. At this point, I just want to make sure that this system will only allow one client to acquire an EXCLUSIVE lock. Any ideas?