Creating watch for non-existent key

(Iilyak) #1

Is it possible to create a watch for non-existent key (and add it into write conflict range)?

One of the use cases when it could be useful is limiting the number of entries in the range.
Let’s say we want our range to have maximum 1000 entries. If we have an external mechanism to generate sequential ids (starting from 1) we always know that the last key in the range would be “{NS} / 1000”.

If we can add “{NS} / 1000” into write conflict range and set a watch on it. We should be able to:

  • prevent writers from creating more entries
  • do something when watch would fire

To summarize:

  • is it possible to set up a watch on non-existent key?
    • are there any performance problems with it?
  • is it possible to add non-existent key into write conflict range (the key would be written by another transaction)?

(Alex Miller) #2

You can watch non-existent keys, and get notified when they now have a value. There’s no difference in performance between watches of existing and non-existing values.

FDB only checks read-write conflicts, so write conflicts only abort concurrent transactions that have read the same value. The proposed usage of write conflicts wouldn’t stop writers that blind write {NS} / 1000 (ie. writers that don’t also read the key when writing it), and writers started after the watch’s transaction commits.

You would need to implement this as a transaction will decide to not write {NS} / 1001 if it sees that the range already contains more than 1000 elements. Hitting this limit precisely would require reading and writing a counter in each transaction, which would greatly limit concurrency due to the required coordination. If you’re okay with just ending up near 1000 elements, you could potentially get away with doing a non-transactional read of a counter using a “snapshot read”, and incrementing/decrementing it using ATOMIC_ADD.

(Iilyak) #3

Thank you for your explanation.