diff options
author | Håkon Hallingstad <hakon@yahooinc.com> | 2022-04-26 14:47:03 +0200 |
---|---|---|
committer | Håkon Hallingstad <hakon@yahooinc.com> | 2022-04-26 14:47:03 +0200 |
commit | 5fafbc12f4d63271534a4522ac136c50ba5027a0 (patch) | |
tree | ed7bd2082f27be7dd64f4d24437165e146e2339f | |
parent | 2949f715850f83417d4c5a319f2476b60fe84e94 (diff) |
Add lockId
3 files changed, 21 insertions, 16 deletions
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/Lock.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/Lock.java index d442cae40a0..d28ce299dde 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/Lock.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/Lock.java @@ -12,7 +12,6 @@ import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; /** * A cluster-wide re-entrant mutex which is released on (the last symmetric) close. @@ -63,8 +62,13 @@ public class Lock implements Mutex { invoke(+1L, threadLockStats::lockAcquired); } + @FunctionalInterface + private interface TriConsumer { + void accept(String lockId, long reentryCountDiff, Map<Long, Long> reentriesByThreadId); + } + // TODO(hakon): Remove once debugging is unnecessary - private void invoke(long reentryCountDiff, BiConsumer<Long, Map<Long, Long>> consumer) { + private void invoke(long reentryCountDiff, TriConsumer consumer) { long threadId = Thread.currentThread().getId(); final long sequenceNumber; final Map<Long, Long> reentriesByThreadIdCopy; @@ -82,7 +86,8 @@ public class Lock implements Mutex { reentriesByThreadIdCopy = Map.copyOf(reentriesByThreadId); } - consumer.accept(sequenceNumber, reentriesByThreadIdCopy); + String lockId = Integer.toHexString(System.identityHashCode(this)); + consumer.accept(lockId, sequenceNumber, reentriesByThreadIdCopy); } @Override diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockStats.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockStats.java index 1b8b68c2ccb..ecb344dedb9 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockStats.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LockStats.java @@ -64,33 +64,33 @@ public class LockStats { } /** Must be invoked only after the first and non-reentry acquisition of the lock. */ - void notifyOfThreadHoldingLock(Thread currentThread, String lockPath, long sequenceNumber, - Map<Long, Long> reentriesByThreadId) { + void notifyOfThreadHoldingLock(Thread currentThread, String lockPath, String lockId, + long sequenceNumber, Map<Long, Long> reentriesByThreadId) { Thread oldThread = lockPathsHeld.put(lockPath, currentThread); if (oldThread != null) { getLockMetrics(lockPath).incrementAcquireWithoutReleaseCount(); logger.warning("Thread " + currentThread.getName() + " reports it has the lock on " + lockPath + ", but thread " + oldThread.getName() + - " has not reported it released the lock. #" + sequenceNumber + + " has not reported it released the lock. " + lockId + "#" + sequenceNumber + ", reentries by thread ID = " + reentriesByThreadId); } } /** Must be invoked only before the last and non-reentry release of the lock. */ - void notifyOfThreadReleasingLock(Thread currentThread, String lockPath, long sequenceNumber, - Map<Long, Long> reentriesByThreadId) { + void notifyOfThreadReleasingLock(Thread currentThread, String lockPath, String lockId, + long sequenceNumber, Map<Long, Long> reentriesByThreadId) { Thread oldThread = lockPathsHeld.remove(lockPath); if (oldThread == null) { getLockMetrics(lockPath).incrementNakedReleaseCount(); logger.warning("Thread " + currentThread.getName() + " is releasing the lock " + lockPath + - ", but nobody owns that lock. #" + sequenceNumber + ", reentries by thread ID = " + - reentriesByThreadId); + ", but nobody owns that lock. " + lockId + "#" + sequenceNumber + + ", reentries by thread ID = " + reentriesByThreadId); } else if (oldThread != currentThread) { getLockMetrics(lockPath).incrementForeignReleaseCount(); logger.warning("Thread " + currentThread.getName() + " is releasing the lock " + lockPath + ", but it was owned by thread " + - oldThread.getName() + ". #" + sequenceNumber + ", reentries by thread ID = " + - reentriesByThreadId); + oldThread.getName() + ". " + lockId + "#" + sequenceNumber + + ", reentries by thread ID = " + reentriesByThreadId); } } diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java index 972e3babb1d..7f8eafdcf7f 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java @@ -98,7 +98,7 @@ public class ThreadLockStats { } /** Mutable method (see class doc) */ - public void lockAcquired(long sequenceNumber, Map<Long, Long> reentriesByThreadId) { + public void lockAcquired(String lockId, long sequenceNumber, Map<Long, Long> reentriesByThreadId) { withLastLockAttempt(lockAttempt -> { // Note on the order of lockAcquired() vs notifyOfThreadHoldingLock(): When the latter is // invoked, other threads may query e.g. isAcquired() on the lockAttempt, which would @@ -108,19 +108,19 @@ public class ThreadLockStats { if (!lockAttempt.isReentry()) { LockStats.getGlobal().notifyOfThreadHoldingLock(thread, lockAttempt.getLockPath(), - sequenceNumber, reentriesByThreadId); + lockId, sequenceNumber, reentriesByThreadId); } }); } /** Mutable method (see class doc) */ - public void preRelease(long sequenceNumber, Map<Long, Long> reentriesByThreadId) { + public void preRelease(String lockId, long sequenceNumber, Map<Long, Long> reentriesByThreadId) { withLastLockAttempt(lockAttempt -> { // Note on the order of these two statement: Same concerns apply here as in lockAcquired(). if (!lockAttempt.isReentry()) { LockStats.getGlobal().notifyOfThreadReleasingLock(thread, lockAttempt.getLockPath(), - sequenceNumber, reentriesByThreadId); + lockId, sequenceNumber, reentriesByThreadId); } lockAttempt.preRelease(); |