Skip to content

Add timed acquisition and queue diagnostics to GraphLock - #294

Open
MattArtzAnthro wants to merge 1 commit into
gephi:masterfrom
MattArtzAnthro:graphlock-timed-acquisition
Open

MattArtzAnthro wants to merge 1 commit into
gephi:masterfrom
MattArtzAnthro:graphlock-timed-acquisition

Conversation

@MattArtzAnthro

@MattArtzAnthro MattArtzAnthro commented Aug 28, 2026 •

Copy link
Copy Markdown

Summary

  • GraphLock exposed only unbounded, non-interruptible readLock() / writeLock() calls, so a caller that cannot afford to wait indefinitely (a plugin doing graph work off the EDT while the viz engine renders) had no option in the public API short of reflecting into GraphLockImpl.
  • Adds tryReadLock(timeout, unit) and tryWriteLock(timeout, unit), delegating to the underlying ReentrantReadWriteLock's timed tryLock. The timed form enqueues rather than barging, which is why it did not starve in the reproducer on raphLock has no timed/try acquisition; polling writers can starve, and a stalled reader plus a queued writer can wedge all graph operations #282 where untimed tryLock() polling did (0 of 4637 attempts vs 2116 of 2116). tryWriteLock performs the same read-hold check as writeLock().
  • Adds getReadLockCount(), isWriteLocked(), and getQueueLength() for monitoring. getReadLockCount() counts holds across all threads, which is what makes a leaked read hold (an abandoned auto-locking iterator) diagnosable; today it is invisible to a thread dump once the holding thread has exited.
  • All five are default methods on the interface, throwing UnsupportedOperationException, so any external implementation keeps compiling. Happy to make them abstract instead if you prefer, since GraphLockImpl is the only implementation in this repository.
  • Javadoc on readLock() now states that a read hold across a cross-thread wait, or an iterator abandoned before exhaustion or doBreak(), blocks all graph operations once a writer queues. No existing behavior changes; fairness is untouched.

Fixes #282

Test plan

  • Nine tests added to GraphLockImplTest: timed read and write acquire when free; time out under another thread's write and read respectively, then acquire after release; tryWriteLock throws IllegalMonitorStateException when the caller holds a read lock; interruption during a timed wait propagates and leaves no hold; getQueueLength reports a queued writer; getReadLockCount counts holds from two threads while getReadHoldCount stays per-thread; isWriteLocked follows lock and unlock. Contention is set up with latches, not sleeps, apart from a bounded poll on the queue length.
  • mvn -B package passes the full suite (1657 tests) with the formatter applied, after rebasing onto current master (2b9ef7f).

As with the issue, this was worked out together with Claude, Anthropic's AI assistant; I built and ran the tests on my machine.

@MattArtzAnthro
MattArtzAnthro force-pushed the graphlock-timed-acquisition branch 2 times, most recently from ca07fe7 to 890e9e7 Compare August 28, 2026 19:43
GraphLock exposed only unbounded, non-interruptible lock() calls, so a
caller that cannot afford to wait indefinitely had no option in the
public API. This adds tryReadLock and tryWriteLock with a timeout, plus
getReadLockCount, isWriteLocked, and getQueueLength for monitoring,
each delegating to the underlying ReentrantReadWriteLock. New methods
are default methods on the interface so existing implementations keep
compiling. Javadoc on readLock now states the consequence of holding a
read lock across a cross-thread wait or abandoning an auto-locking
iterator. Fixes gephi#282.
@MattArtzAnthro
MattArtzAnthro force-pushed the graphlock-timed-acquisition branch from 890e9e7 to 1ceca12 Compare September 25, 2026 13:39
@MattArtzAnthro
MattArtzAnthro requested a review from a team as a code owner September 25, 2026 13:39

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

raphLock has no timed/try acquisition; polling writers can starve, and a stalled reader plus a queued writer can wedge all graph operations

1 participant