Currently locking takes place all over the codebase, pretty messy.
1. Locks reside in a Node, and is exposed via NodeSPI.getLock()
2. Some interceptors and the state transfer manager acquire and
release locks using methods on NodeLock from NodeSPI.getLock().
3. Others release locks by using helper methods in TransactionEntry,
InvocationContext, TransactionTable and TransactionUtil.
4. NodeLock has methods for acquiring and releasing locks, both
individually and recursively.
I propose that we lose all this bloat and profileration of logic by
writing a single LockManager, which would expose a few simple methods
to acquire and release locks. All lock acquisitions/releases would go
through this LockManager.
Specifically, I want to deprecate NodeSPI#getLock(). I think code
should not have direct access to locks, and should always go through
the LockManager. The reason for this is to allow easy migration to
more interesting locking strategies in future, especially not having a
lock being a part of a node (this has caused us to introduce all sorts
of inefficiencies to prevent concurrent eviction/deletion/creation
events) and to lock based on Fqn. Even allows us to easily introduce
StripedLocks or distributed locks at a later date.
It also helps us write specific LockManager implementations that just
uses standard JDK util.concurrent locks, which is what I need for MVCC
in 3.x.
What are your thoughts on this?
Cheers,
--
Manik Surtani
Lead, JBoss Cache
manik(a)jboss.org