Chronicle-Queue
Chronicle-Queue copied to clipboard
Refactor TableStoreWriteLock and TSQueueLock
These descend from the same base class but have subtly different behaviour (re-entrancy and PID vs PID+TID).
Given the importance of locking to system stability, I feel there is benefit in tidying these up: deduplicate, address TODOs, internalise impls, combine impls and strategise the differences perhaps.
Another thing to focus on IMO is API. Some things to consider
- Having a consistent API across locks
- Using standard interfaces (e.g. Lock, and ReadWriteLock)
- Writing an interface that allows the use of try-with-resources a-la affinity lock
Some other behaviours to consider
- Persistence of locks, what happens when the holder dies?
- Something like file locks that are automatically released would come in handy I think (although if we go down the file locks path again we should remember our learnings about their reliability)
- Is scoping just process or thread, or is there another "scope" where whoever holds a key (e.g. a random number) can unlock, that would allow me to transfer or share "ownership" of the lock to alllow e.g. unlocking on another thread's behalf if that thread had shared the key with me.
- Given our use of event loops, are thread-scoped locks really that useful? If a lock was thread-scoped re-entrant then every handler on the same MediumEventLoop could acquire it.
Is there an alternative to using PIDs? as we've seen, PIDs are allocated sequentially and Docker containers usually have the same fixed number of processes every time, it makes detection of "is the holding process dead" because e.g. PID 11 is always present in this container.
I like Peter's new lock using Posix thread IDs but can we really depend heavily on something that only works in Linux? It seems many of our users dev on Windows.
Maybe there is a unique value for any given JVM instance or we could have a random JVM identity number generated that could be combined with the PID thereby reducing the likelihood of PID collisions, especially in the case of running under Docker where there it is almost guaranteed, instances of the same image would have the same PID. I know there was a trick in the static Map.of() static constructors that provide different iteration orders of maps depending on some random JVM value. This allows assumptions on unspecified order to be caught in unit testing.
this is somewhat related to https://github.com/ChronicleEnterprise/Chronicle-Queue-Enterprise/issues/278
TSQueueLock has been deprecated - changing the title
TSQueueLock is marked as deprecated so refactor if TableStoreWriteLock is likely no longer needed.