Skip to content

Commit 6e23861

Browse files
authored
Fix deadlock detection error message to reflect user-configured timeout (#2934)
1 parent 3da1f1d commit 6e23861

3 files changed

Lines changed: 21 additions & 4 deletions

File tree

temporal-sdk/src/main/java/io/temporal/internal/sync/PotentialDeadlockException.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,30 @@ public class PotentialDeadlockException extends RuntimeException {
2626
* @param threadName name of the thread that is in a potential deadlock state
2727
* @param workflowThreadContext context of the thread that is in a potential deadlock state
2828
* @param detectionTimestamp a timestamp the deadlock was detected
29+
* @param timeoutMillis configured deadlock detection timeout in milliseconds
2930
*/
3031
PotentialDeadlockException(
31-
String threadName, WorkflowThreadContext workflowThreadContext, long detectionTimestamp) {
32+
String threadName,
33+
WorkflowThreadContext workflowThreadContext,
34+
long detectionTimestamp,
35+
long timeoutMillis) {
3236
super(
3337
"[TMPRL1101] Potential deadlock detected. Workflow thread \""
3438
+ threadName
35-
+ "\" didn't yield control for over a second.");
39+
+ "\" didn't yield control for over "
40+
+ formatTimeout(timeoutMillis)
41+
+ ".");
3642
this.workflowThreadContext = workflowThreadContext;
3743
this.detectionTimestamp = detectionTimestamp;
3844
}
3945

46+
private static String formatTimeout(long timeoutMillis) {
47+
if (timeoutMillis % 1000 == 0) {
48+
return timeoutMillis / 1000 + "s";
49+
}
50+
return timeoutMillis + "ms";
51+
}
52+
4053
/**
4154
* @param triggerThreadStackTrace stacktrace of the thread that triggered the Deadlock Detector
4255
* @param otherThreadsDump stack dump of other threads of the workflow excluding the thread that

temporal-sdk/src/main/java/io/temporal/internal/sync/WorkflowThreadContext.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,16 @@ public boolean runUntilBlocked(long deadlockDetectionTimeoutMs) {
238238
if (WorkflowThreadScheduler.WaitForYieldResult.DEADLOCK_DETECTED.equals(yieldResult)) {
239239
long detectionTimestamp = System.currentTimeMillis();
240240
if (currentThread != null) {
241-
throw new PotentialDeadlockException(currentThread.getName(), this, detectionTimestamp);
241+
throw new PotentialDeadlockException(
242+
currentThread.getName(), this, detectionTimestamp, deadlockDetectionTimeoutMs);
242243
} else {
243244
// This should never happen.
244245
// We clear currentThread only after setting the status to DONE.
245246
// And we check for it by the status condition check after waking up on the condition
246247
// and acquiring the lock back
247248
log.warn("Illegal State: WorkflowThreadContext has no currentThread in {} state", status);
248-
throw new PotentialDeadlockException("UnknownThread", this, detectionTimestamp);
249+
throw new PotentialDeadlockException(
250+
"UnknownThread", this, detectionTimestamp, deadlockDetectionTimeoutMs);
249251
}
250252
}
251253
Preconditions.checkState(

temporal-sdk/src/test/java/io/temporal/workflow/deadlockdetector/DeadlockDetectorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public void testDefaultDeadlockDetector() {
7878
failure = failure.getCause();
7979
}
8080
assertTrue(failure.getMessage().contains("Potential deadlock detected"));
81+
assertTrue(failure.getMessage().contains("1s"));
8182
assertTrue(failure.getMessage().contains("Workflow.await"));
8283
}
8384
}
@@ -100,6 +101,7 @@ public void testSetDeadlockDetector() {
100101
failure = failure.getCause();
101102
}
102103
assertTrue(failure.getMessage().contains("Potential deadlock detected"));
104+
assertTrue(failure.getMessage().contains("500ms"));
103105
assertTrue(failure.getMessage().contains("Workflow.await"));
104106
}
105107
}

0 commit comments

Comments
 (0)