Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Prepare applications for Azure deployment by generating infrastructure code, Dockerfiles, and config files.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/durable-task-scheduler/java.md
1# Durable Task Scheduler โ Java23## Learn More45- [Durable Task Scheduler documentation](https://learn.microsoft.com/azure/durable-task-scheduler/)6- [Durable Functions Java guide](https://learn.microsoft.com/azure/azure-functions/durable/durable-functions-overview?tabs=java)78## Durable Functions Setup910### Required Maven Dependencies1112```xml13<dependencies>14<dependency>15<groupId>com.microsoft.azure.functions</groupId>16<artifactId>azure-functions-java-library</artifactId>17<version>3.2.3</version>18</dependency>19<dependency>20<groupId>com.microsoft</groupId>21<artifactId>durabletask-azure-functions</artifactId>22<version>1.7.0</version>23</dependency>24</dependencies>25```2627> **๐ก Finding latest versions**: Search [Maven Central](https://central.sonatype.com/) for `durabletask-azure-functions` (group: `com.microsoft`) to find the current stable version.2829### host.json3031```json32{33"version": "2.0",34"extensions": {35"durableTask": {36"hubName": "default",37"storageProvider": {38"type": "durabletask-scheduler",39"connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"40}41}42},43"extensionBundle": {44"id": "Microsoft.Azure.Functions.ExtensionBundle",45"version": "[4.*, 5.0.0)"46}47}48```4950### local.settings.json5152```json53{54"IsEncrypted": false,55"Values": {56"FUNCTIONS_WORKER_RUNTIME": "java",57"AzureWebJobsStorage": "UseDevelopmentStorage=true",58"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"59}60}61```6263## Minimal Example6465```java66import com.microsoft.azure.functions.*;67import com.microsoft.azure.functions.annotation.*;68import com.microsoft.durabletask.*;69import com.microsoft.durabletask.azurefunctions.*;7071public class DurableFunctionsApp {7273@FunctionName("HttpStart")74public HttpResponseMessage httpStart(75@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)76HttpRequestMessage<Void> request,77@DurableClientInput(name = "durableContext") DurableClientContext durableContext) {78DurableTaskClient client = durableContext.getClient();79String instanceId = client.scheduleNewOrchestrationInstance("MyOrchestration");80return durableContext.createCheckStatusResponse(request, instanceId);81}8283@FunctionName("MyOrchestration")84public String myOrchestration(85@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {86String result1 = ctx.callActivity("SayHello", "Tokyo", String.class).await();87String result2 = ctx.callActivity("SayHello", "Seattle", String.class).await();88return result1 + ", " + result2;89}9091@FunctionName("SayHello")92public String sayHello(@DurableActivityTrigger(name = "name") String name) {93return "Hello " + name + "!";94}95}96```9798## Workflow Patterns99100### Fan-Out/Fan-In101102```java103@FunctionName("FanOutFanIn")104public List<String> fanOutFanIn(105@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {106String[] cities = {"Tokyo", "Seattle", "London", "Paris", "Berlin"};107List<Task<String>> parallelTasks = new ArrayList<>();108109// Fan-out: schedule all activities in parallel110for (String city : cities) {111parallelTasks.add(ctx.callActivity("SayHello", city, String.class));112}113114// Fan-in: wait for all to complete115List<String> results = new ArrayList<>();116for (Task<String> task : parallelTasks) {117results.add(task.await());118}119120return results;121}122```123124### Human Interaction125126```java127@FunctionName("ApprovalWorkflow")128public String approvalWorkflow(129@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {130ctx.callActivity("SendApprovalRequest", ctx.getInput(String.class)).await();131132// Wait for approval event with timeout133Task<Boolean> approvalTask = ctx.waitForExternalEvent("ApprovalEvent", Boolean.class);134Task<Void> timeoutTask = ctx.createTimer(Duration.ofDays(3));135136Task<?> winner = ctx.anyOf(approvalTask, timeoutTask).await();137138if (winner == approvalTask) {139return approvalTask.await() ? "Approved" : "Rejected";140}141return "Timed out";142}143```144145## Orchestration Determinism146147| โ NEVER | โ ALWAYS USE |148|----------|--------------|149| `System.currentTimeMillis()` | `ctx.getCurrentInstant()` |150| `UUID.randomUUID()` | Pass random values from activities |151| `Thread.sleep()` | `ctx.createTimer()` |152| Direct I/O, HTTP, database | `ctx.callActivity()` |153154### Replay-Safe Logging155156```java157private static final java.util.logging.Logger logger =158java.util.logging.Logger.getLogger("MyOrchestration");159160@FunctionName("MyOrchestration")161public String myOrchestration(162@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {163// Use isReplaying to avoid duplicate logs164if (!ctx.getIsReplaying()) {165logger.info("Started"); // Only logs once, not on replay166}167return ctx.callActivity("MyActivity", "input", String.class).await();168}169```170171## Error Handling & Retry172173```java174@FunctionName("WorkflowWithRetry")175public String workflowWithRetry(176@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {177TaskOptions retryOptions = new TaskOptions(new RetryPolicy(1783, // maxNumberOfAttempts179Duration.ofSeconds(5) // firstRetryInterval180));181182try {183return ctx.callActivity("UnreliableService", ctx.getInput(String.class),184retryOptions, String.class).await();185} catch (TaskFailedException ex) {186ctx.setCustomStatus(Map.of("Error", ex.getMessage()));187ctx.callActivity("CompensationActivity", ctx.getInput(String.class)).await();188return "Compensated";189}190}191```192193## Durable Task SDK (Non-Functions)194195For applications running outside Azure Functions (containers, VMs, Azure Container Apps, Azure Kubernetes Service):196197```java198import com.microsoft.durabletask.*;199import com.microsoft.durabletask.azuremanaged.DurableTaskSchedulerWorkerExtensions;200import com.microsoft.durabletask.azuremanaged.DurableTaskSchedulerClientExtensions;201202import java.time.Duration;203204public class App {205public static void main(String[] args) throws Exception {206String connectionString = "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";207208// Worker209DurableTaskGrpcWorker worker = DurableTaskSchedulerWorkerExtensions210.createWorkerBuilder(connectionString)211.addOrchestration(new TaskOrchestrationFactory() {212@Override public String getName() { return "MyOrchestration"; }213@Override public TaskOrchestration create() {214return ctx -> {215String result = ctx.callActivity("SayHello",216ctx.getInput(String.class), String.class).await();217ctx.complete(result);218};219}220})221.addActivity(new TaskActivityFactory() {222@Override public String getName() { return "SayHello"; }223@Override public TaskActivity create() {224return ctx -> "Hello " + ctx.getInput(String.class) + "!";225}226})227.build();228229worker.start();230231// Client232DurableTaskClient client = DurableTaskSchedulerClientExtensions233.createClientBuilder(connectionString).build();234String instanceId = client.scheduleNewOrchestrationInstance("MyOrchestration", "World");235OrchestrationMetadata result = client.waitForInstanceCompletion(236instanceId, Duration.ofSeconds(30), true);237System.out.println("Output: " + result.readOutputAs(String.class));238239worker.stop();240}241}242```243244