Atomic list updates

The best way to model this with Couchbase would be to retrieve/modify/write each resource indicating it’s being used. The modify/write should use a CAS operation.

There are a couple of loopholes there though which can be closed up with some additions.

The first loophole is durability. It’s not guaranteed that a write is durable. You can express more durability requirements by adding the PersistTo and ReplicateTo options to your write.

The second loophole is that what if the client using that resource doesn’t release it withinin a reasonable period of time. One approach for that would be to store some kind of absolute time in the document after which the client will give up that resource. The other approach would be to store it in a separate document with a TTL.

For instance, if you wanted to have item1 taken by a client and then later returned, have two documents, “item1” and “item1:co” (for checkout).

Two actors, A and B, try to retrieve “item1:co”. Failing that, they both try to upsert() a new document named “item1:co” with a TTL of 300 seconds because they both expect to use no more than that amount of time to do their work.

Assume that actor “B” succeeds, and client “A” does not. Actor “B” will be able to do whatever it needs with the resource “item1”. Actor “A” can do a backoff/retry with “item1:co”.

Once actor “B” is done, it can remove the “item1:co” and then others can access that resource.

Failures may need other special handling, but using a TTL and CAS operations will get you most of the way there. Note that the cluster won’t guarantee any kind of locking or prevent mutation by erroneous actors, so that’ll be up to your program (and it’s tests) to verify correctness.

Hopefully that helps!