Locking/Synchronizing Requests

Hi there! I'm wondering if there's any simple way to acquire a lock on something with workers. In an example: I do have an API which carries state between 2 requests (don't ask why, it's not my API 😅). User A sends request 1 with x = 1 User B sends request 1 with x = 2 User A sends request 2 Now user a expects his request to be fulfilled with x = 1, but x will be 2. The solution I see here, is either to work with a queue with max_concurrency = 1, but that might be more overhead than just having some kind of "lock" which needs to be acquired. What would the worker-experts recommend me to do there? Thanks for your help!
9 Replies
Hello, I’m Allie!
Do the users have an assigned ID(via something like a Cookie)?
ByteAlex
ByteAlex•11mo ago
This is not necessarily required, as I'd just let the worker handle doing both requests on behalf of the user. I just need to avoid having 2 users issuing a request concurrently. If it makes things easier, I can add an identifier. Basically I want to have the user request a simple json to the worker. The worker will then handle the annoying mapping and queue the request up, if necessary. Well, even the "queuing up" might be too much. I may just tell the user to try again later. It's not like I expect many users. Just want to quickly let them know, that the service is unavailable for their request right now.
Hello, I’m Allie!
The issue is too that you may not be guaranteed to hit the same Worker, so you may need to have some external DB to actually store the state(ie KV, D1, etc.) Which is where an identifier comes in handy
ByteAlex
ByteAlex•11mo ago
Well, KV doesn't guarantees write consistency in the expected timeframe, so we're more looking towards DO/D1/Queue probably So best I could do, is having a DO with a locked state then?
Hello, I’m Allie!
That could work too? Just need to make sure that the state fits within the 128kb limit, or that you can break it down into chunks of that size.
ByteAlex
ByteAlex•11mo ago
That would probably suffice then. Thanks for the guidance!
Bobby Donchev
Bobby Donchev•11mo ago
but durable objects are made for this kind of stuff. Synchronising state between users.
User A sends request 1 with x = 1 User B sends request 1 with x = 2 User A sends request 2 Now user a expects his request to be fulfilled with x = 1, but x will be 2.
User A sends request and locks the state x=1 User B sends request with x = 2 and receives an error (423) User A sends request 2 and unlocks the state You can even set an alarm with durable objects to unlock the state in case User A never made request 2 after time X
ByteAlex
ByteAlex•11mo ago
This alarm'ing is new to me
Bobby Donchev
Bobby Donchev•11mo ago
check it out: https://developers.cloudflare.com/workers/configuration/durable-objects/#alarms-in-durable-objects I build a similar API here where I provide a lock per URL: curl https://statebin.io/lock/someNamespace/anyKey lock it: curl -XPUT https://statebin.io/lock/someNamespace/anyKey will auto unlock in 1hour or manually unlock it: curl -XDELETE https://statebin.io/lock/someNamespace/anyKey