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();
}
}
}
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:
Code: