microsoft / microsoft/durabletask-java
Functions - Terminating a running orchestrator throws IllegalStateException
未關閉
還沒有人認領這個 Issue。
P2
- 主要語言
- Java
- 星號
- 29
- 分支
- 18
- 平均合併
- 1 天 10 小時
- 30 天內合併 PR
- 2
描述
When using this repo with Azure Functions with the MSSQL backend, and using the client.terminate() API to terminate an orchestraton that is still running, the orchestration will throw an IllegalStateException:
[2025-08-22T16:32:56.240Z] Executed 'Functions.LongRunningOrchestrator' (Failed, Id=c6d1d1b9-32ee-4849-a841-5902bbbff2c6, Duration=51ms)
[2025-08-22T16:32:56.241Z] System.Private.CoreLib: Exception while executing function: Functions.LongRunningOrchestrator. System.Private.CoreLib: Result: Failure
Exception: IllegalStateException: The orchestrator has already completed
Stack: java.lang.IllegalStateException: The orchestrator has already completed
[2025-08-22T16:32:56.242Z] at com.microsoft.durabletask.Helpers.throwIfOrchestratorComplete(Helpers.java:31)
[2025-08-22T16:32:56.243Z] at com.microsoft.durabletask.TaskOrchestrationExecutor$ContextImplTask.completeInternal(TaskOrchestrationExecutor.java:799)
[2025-08-22T16:32:56.244Z] at com.microsoft.durabletask.TaskOrchestrationExecutor$ContextImplTask.fail(TaskOrchestrationExecutor.java:787)
[2025-08-22T16:32:56.244Z] at com.microsoft.durabletask.TaskOrchestrationExecutor.execute(TaskOrchestrationExecutor.java:71)
[2025-08-22T16:32:56.245Z] at com.microsoft.durabletask.OrchestrationRunner.loadAndRun(OrchestrationRunner.java:136)
[2025-08-22T16:32:56.247Z] at com.microsoft.durabletask.OrchestrationRunner.loadAndRun(OrchestrationRunner.java:69)
[2025-08-22T16:32:56.249Z] at com.microsoft.durabletask.OrchestrationRunner.loadAndRun(OrchestrationRunner.java:42)
[2025-08-22T16:32:56.249Z] at com.microsoft.durabletask.azurefunctions.internal.middleware.OrchestrationMiddleware.invoke(OrchestrationMiddleware.java:37)
[2025-08-22T16:32:56.250Z] at com.microsoft.azure.functions.worker.chain.InvocationChain.doNext(InvocationChain.java:21)
[2025-08-22T16:32:56.251Z] at com.microsoft.azure.functions.worker.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:125)
[2025-08-22T16:32:56.252Z] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:34)
[2025-08-22T16:32:56.253Z] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:10)
[2025-08-22T16:32:56.254Z] at com.microsoft.azure.functions.worker.handler.MessageHandler.handle(MessageHandler.java:44)
[2025-08-22T16:32:56.255Z] at com.microsoft.azure.functions.worker.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:94)
[2025-08-22T16:32:56.256Z] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
[2025-08-22T16:32:56.257Z] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[2025-08-22T16:32:56.258Z] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[2025-08-22T16:32:56.258Z] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[2025-08-22T16:32:56.259Z] at java.base/java.lang.Thread.run(Thread.java:842)
[2025-08-22T16:32:56.260Z] .
[2025-08-22T16:32:56.266Z] d88614d4-5cea-453a-9bbd-0a423a9059da: Function 'LongRunningOrchestrator (Orchestrator)' failed with an error. Reason: Microsoft.Azure.WebJobs.Host.FunctionInvocationException
Code:
/**
* Orchestration and activity functions for simulating long-running orchestration and termination.
*/
public class TerminateOrchestration {
/**
* This is the orchestrator function.
*/
@FunctionName("LongRunningOrchestrator")
public List<String> longRunningOrchestrator(
@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx,
final ExecutionContext context) {
Logger logger = context.getLogger();
logger.info("Starting long-running orchestration.");
List<String> outputs = new ArrayList<>();
// Call our fake activity 100,000 times to simulate an orchestration that might run for >= 10,000s (2.7 hours)
for (int i = 0; i < 100000; i++) {
outputs.add(ctx.callActivity("SimulatedWorkActivity", 100, String.class).await());
}
return outputs;
}
/**
* This is the activity function.
*/
@FunctionName("SimulatedWorkActivity")
public String simulatedWorkActivity(
@DurableActivityTrigger(name = "sleepMs") int sleepMs,
final ExecutionContext context) {
context.getLogger().info("Sleeping for " + sleepMs + "ms.");
try {
Thread.sleep(sleepMs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return "Sleep interrupted.";
}
return "Slept for " + sleepMs + "ms.";
}
/**
* HTTP-triggered function to terminate an orchestration instance.
*/
@FunctionName("TerminateInstance")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext,
@BindingName("instanceId") String instanceId,
final ExecutionContext context) {
DurableTaskClient client = durableContext.getClient();
String reason = "Long-running orchestration was terminated early.";
try {
client.terminate(instanceId, reason);
return request.createResponseBuilder(HttpStatus.OK).build();
} catch (Exception ex) {
context.getLogger().severe(ex.getMessage());
return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
.header("Content-Type", "text/plain")
.body(ex.getMessage())
.build();
}
}
}
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
首先按照堆疊追蹤所示,從 DurableTaskClient.terminate(instanceId, reason) 追蹤到 TaskOrchestrationExecutor.execute 的終止路徑,尤其關注 ContextImplTask.fail 和 Helpers.throwIfOrchestratorComplete。使用提供的 TerminateOrchestration 函式重現此問題,並驗證終止正在執行的 orchestration 不再導致 IllegalStateException。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- azure, java
- 領域
- backend, distributed-systems
- Issue 類型
- 缺陷
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 活躍度
- 停滯
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100