summaryrefslogtreecommitdiffstats
path: root/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockInfo.java
diff options
context:
space:
mode:
Diffstat (limited to 'zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockInfo.java')
-rw-r--r--zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockInfo.java30
1 files changed, 22 insertions, 8 deletions
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockInfo.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockInfo.java
index bba39e6dc49..5e77ec76290 100644
--- a/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockInfo.java
+++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockInfo.java
@@ -4,11 +4,12 @@ package com.yahoo.vespa.curator.stats;
import com.yahoo.vespa.curator.Lock;
import java.time.Duration;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.PriorityQueue;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
@@ -26,8 +27,10 @@ public class ThreadLockInfo {
private static final ConcurrentHashMap<Thread, ThreadLockInfo> locks = new ConcurrentHashMap<>();
- private static final int MAX_COMPLETED_LOCK_INFOS_SIZE = 10;
- private static final ConcurrentLinkedDeque<LockInfo> completedLockInfos = new ConcurrentLinkedDeque<>();
+ private static final int MAX_COMPLETED_LOCK_INFOS_SIZE = 5;
+ /** Would have used a thread-safe priority queue. */
+ private static final Object completedLockInfosMonitor = new Object();
+ private static final PriorityQueue<LockInfo> completedLockInfos = new PriorityQueue<>(Comparator.comparing(LockInfo::getTotalTime));
private static final ConcurrentHashMap<String, LockCounters> countersByLockPath = new ConcurrentHashMap<>();
@@ -43,6 +46,12 @@ public class ThreadLockInfo {
public static List<ThreadLockInfo> getThreadLockInfos() { return List.copyOf(locks.values()); }
+ public static List<LockInfo> getSlowLockInfos() {
+ synchronized (completedLockInfosMonitor) {
+ return List.copyOf(completedLockInfos);
+ }
+ }
+
/** Returns the per-thread singleton ThreadLockInfo. */
public static ThreadLockInfo getCurrentThreadLockInfo(String lockPath, ReentrantLock lock) {
return locks.computeIfAbsent(
@@ -68,7 +77,7 @@ public class ThreadLockInfo {
public void invokingAcquire(Duration timeout) {
lockCountersForPath.invokeAcquireCount.incrementAndGet();
lockCountersForPath.inCriticalRegionCount.incrementAndGet();
- lockInfos.add(LockInfo.invokingAcquire(lock.getHoldCount(), timeout));
+ lockInfos.add(LockInfo.invokingAcquire(getThreadName(), lockPath, lock.getHoldCount(), timeout));
}
/** Mutable method (see class doc) */
@@ -113,10 +122,15 @@ public class ThreadLockInfo {
LockInfo lockInfo = lockInfos.poll();
completeLockInfo.accept(lockInfo);
- if (completedLockInfos.size() >= MAX_COMPLETED_LOCK_INFOS_SIZE) {
- // This is thread-safe, as no-one but currentThread mutates completedLockInfos
- completedLockInfos.removeLast();
+ synchronized (completedLockInfosMonitor) {
+ if (completedLockInfos.size() < MAX_COMPLETED_LOCK_INFOS_SIZE) {
+ lockInfo.fillStackTrace();
+ completedLockInfos.add(lockInfo);
+ } else if (lockInfo.getTotalTime().compareTo(completedLockInfos.peek().getTotalTime()) > 0) {
+ completedLockInfos.poll();
+ lockInfo.fillStackTrace();
+ completedLockInfos.add(lockInfo);
+ }
}
- completedLockInfos.addFirst(lockInfo);
}
}