microsoft / microsoft/durabletask-java
`TaskOrchestrationContext.waitForExternalEvent` Timeout "Removed" After Attempting to Schedule Duplicate Orchestration
还没有人认领这个 Issue。
- 主要语言
- Java
- 星标
- 29
- 派生
- 18
- 平均合并
- 1 天 10 小时
- 30 天内合并 PR
- 2
描述
Summary
An orchestration which specifies a timeout for waiting on an external event will seemingly have that timeout "removed"/ignored after another attempt is made to schedule an orchestration instance with the same ID.
Steps to Reproduce
- Copy the example below.
- Execute the
orchestrator-triggerfunction via HTTP.
@FunctionName("orchestrator-trigger")
public HttpResponseMessage triggerOrchestrator(
@HttpTrigger(
name = "request",
methods = { HttpMethod.GET },
authLevel = AuthorizationLevel.FUNCTION,
route = "orchestrator/trigger"
)
HttpRequestMessage<String> request,
@DurableClientInput(name = "durableContext")
DurableClientContext durableContext,
ExecutionContext context
) throws InterruptedException {
DurableTaskClient client = durableContext.getClient();
String instanceId = "the-only-instance";
client.scheduleNewOrchestrationInstance("orchestrator", null, instanceId);
client.raiseEvent(instanceId, "first", 1);
// Attempting to schedule another orchestration instance with the same instance ID results
// in the event timeout within the existing orchestrator instance from triggering.
try {
client.scheduleNewOrchestrationInstance("orchestrator", null, instanceId);
} catch (RuntimeException ignored) { }
Thread.sleep(10_000);
client.raiseEvent(instanceId, "second", 2);
return request.createResponseBuilder(HttpStatus.OK).build();
}
@FunctionName("orchestrator")
public void orchestrator(
@DurableOrchestrationTrigger(name = "orchestration")
TaskOrchestrationContext orchestration,
ExecutionContext context
) {
Task<Integer> firstTask =
orchestration.waitForExternalEvent("first", Duration.ofSeconds(1), Integer.class);
Task<Integer> secondTask =
orchestration.waitForExternalEvent("second", Duration.ofSeconds(1), Integer.class);
List<Integer> results = orchestration.allOf(firstTask, secondTask).await();
int first = results.get(0);
int second = results.get(1);
System.out.printf("Triggered! First: %s, Second: %s\n", first, second);
}
Expected Result
The orchestration throws an exception due to the second event not arriving within one second.
Actual Result
After ten seconds, the orchestration prints Triggered! First: 1, Second: 2.
Additional Context
Deleting the entire try/catch block that contains the second scheduleNewOrchestrationInstance call results in the expected outcome - the orchestration throws.
This test case is contrived - my actual use case is:
- A process operates on the combination of a ZIP file and a CSV file.
- These two files are provided to the application separately, in any order, but at roughly the same time.
- Whichever file arrives first needs to start an orchestration instance that will wait for both files.
- We need to avoid a race condition that would result in two separate orchestration instances being created, each waiting for the opposite file. So we'll create a deterministic instance ID based on other data, have the CSV/ZIP receivers always attempt to schedule an orchestration instance with that ID, and ignore the "already exists" error when it occurs.
- The CSV/ZIP receivers then simply send their own single event to the orchestration instance.
- The orchestration instance needs to have a timeout in the situation where the second file never arrives.
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 issue 中的 Java 复现开始,重点关注 TaskOrchestrationContext.waitForExternalEvent 和重复的 scheduleNewOrchestrationInstance 调用。运行 orchestrator 触发场景,并验证即使再次尝试调度相同的实例 ID,第二个外部事件也会在一秒后超时。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- java
- 领域
- backend, distributed-systems
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 35/100