test server: retrying activity never times out by ScheduleToClose when its expiration falls on a whole second (`getNanos() != 0` guard in `TestServiceRetryState`)
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
Hướng nghiên cứu
Đọc TestServiceRetryState.getBackoffIntervalInSeconds trong máy chủ kiểm thử Java, đặc biệt là phần kiểm tra hết hạn được mô tả trong issue. So sánh thời điểm thử lại tiếp theo với thời điểm hết hạn ngay cả khi giá trị nano giây bằng không, sau đó chạy các bài kiểm thử trạng thái thử lại liên quan. Hoàn thành khi một hoạt động bị timeout tại ScheduleToClose, bất kể thời điểm hết hạn có rơi đúng vào một giây tròn hay không.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
In the Java test server (temporal-test-server), an activity that keeps failing with a retryable error is supposed to stop retrying once the next attempt would start after its ScheduleToClose deadline. In TestServiceRetryState.getBackoffIntervalInSeconds this check is guarded by expirationTime.getNanos() != 0:
if (expirationTime.getNanos() != 0
&& Timestamps.compare(nextScheduleTime, expirationTime) > 0) {
return new BackoffInterval(RetryState.RETRY_STATE_TIMEOUT);
}
The test server's clock has millisecond precision, so the expiration timestamp has nanos == 0 whenever the activity was scheduled exactly on a whole second (≈1 in 1000 schedules). In that case the check is skipped, and nothing else closes the activity: the ScheduleToClose timer is bound to the attempt number at scheduling time and is discarded as outdated after the first retry. The activity then retries forever (we observed 362 attempts at 20 s intervals well past a 2 h deadline), and the workflow never completes.
The guard looks unnecessary: the constructor already maps "no expiration" to Timestamps.MAX_VALUE, so comparing against it is safe.
Reproduction
Minimal workflow (Kotlin, SDK 1.25.1, TestWorkflowEnvironment with time skipping):
- activity always throws a retryable
ApplicationFailure; ScheduleToCloseTimeout = 2h,RetryOptions(initialInterval = 20m, backoffCoefficient = 1.0), nomaximumAttempts;- workflow catches
ActivityFailureand returns.
Running many independent executions and waiting 5 s (wall clock) for each result:
| test server | executions | never completed | ActivityTaskScheduled.eventTime.nanos of the stuck ones |
|---|---|---|---|
| 1.25.1 | 4514 | 4 | 0 in all 4 |
| 1.40.0 | 409 | 1 | 0 |
1.25.1 with the getNanos() != 0 && part removed |
12000 | 0 (11 schedules had nanos = 0) | — |
A deterministic reproduction is possible by freezing the test server clock on a whole second (we did it with a test-scoped TestServicesStarter variant using Clock.fixed(...)): without the change the activity never closes; with it, it closes by RETRY_STATE_TIMEOUT.
Expected
RETRY_STATE_TIMEOUT whenever the next attempt would be scheduled after the expiration time, regardless of the sub-second part of the expiration timestamp.
Suggested fix
if (Timestamps.compare(nextScheduleTime, expirationTime) > 0) {
return new BackoffInterval(RetryState.RETRY_STATE_TIMEOUT);
}
Versions checked: 1.25.1, 1.26.0, 1.28.0, 1.30.0, 1.34.0, 1.36.0, 1.40.0 — the same condition is present. We currently work around it by shadowing the class in our test classpath.
- Ngôn ngữ chính
- Java
- Star
- 433
- Fork
- 257
- Merge trung bình
- 2 ngày 18 giờ
- Pull request đã merge (30 ngày)
- 24
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của temporalio/sdk-java
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
temporalio/sdk-java#1825 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
temporalio/sdk-java#3132 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 54/100
temporalio/sdk-java#3125 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 55/100
temporalio/sdk-java#3124 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
temporalio/sdk-java#3122 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của temporalio/sdk-java
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
liquid-java/liquidjava#373 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
NationalSecurityAgency/ghidra#9748 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày
-
spring-mcp-tools
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
explyt/spring-plugin#591 ·
Maintainer thường phản hồi trong vòng 1 ngày