From a76190a6e49aed5deacda1f692b823ece507eef6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 07:25:24 +0000 Subject: [PATCH 1/3] Initial plan From 3c5294afcfe0e31b7529c1b4975f594003c3481d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 07:29:26 +0000 Subject: [PATCH 2/3] Add unit tests for DurableTaskGrpcClientFactory and fix compilation error Co-authored-by: sophiatev <38052607+sophiatev@users.noreply.github.com> --- .../durabletask/DurableTaskGrpcClient.java | 1 + .../DurableTaskGrpcClientFactoryTest.java | 74 ++++++++++ .../protos/orchestrator_service.proto | 133 ++++++++++++++++-- 3 files changed, 199 insertions(+), 9 deletions(-) create mode 100644 client/src/test/java/com/microsoft/durabletask/DurableTaskGrpcClientFactoryTest.java diff --git a/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java b/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java index 8f12b3ea..21de905c 100644 --- a/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java +++ b/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java @@ -63,6 +63,7 @@ public final class DurableTaskGrpcClient extends DurableTaskClient { DurableTaskGrpcClient(int port) { this.dataConverter = new JacksonDataConverter(); + this.defaultVersion = null; // Need to keep track of this channel so we can dispose it on close() this.managedSidecarChannel = ManagedChannelBuilder diff --git a/client/src/test/java/com/microsoft/durabletask/DurableTaskGrpcClientFactoryTest.java b/client/src/test/java/com/microsoft/durabletask/DurableTaskGrpcClientFactoryTest.java new file mode 100644 index 00000000..f77537ad --- /dev/null +++ b/client/src/test/java/com/microsoft/durabletask/DurableTaskGrpcClientFactoryTest.java @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.durabletask; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Unit tests for DurableTaskGrpcClientFactory. + */ +public class DurableTaskGrpcClientFactoryTest { + + @Test + void getClient_samePort_returnsSameInstance() { + // Arrange + int port = 5001; + + // Act + DurableTaskClient client1 = DurableTaskGrpcClientFactory.getClient(port); + DurableTaskClient client2 = DurableTaskGrpcClientFactory.getClient(port); + + // Assert + assertNotNull(client1, "First client should not be null"); + assertNotNull(client2, "Second client should not be null"); + assertSame(client1, client2, "getClient should return the same instance for the same port"); + } + + @Test + void getClient_differentPorts_returnsDifferentInstances() { + // Arrange + int port1 = 5002; + int port2 = 5003; + + // Act + DurableTaskClient client1 = DurableTaskGrpcClientFactory.getClient(port1); + DurableTaskClient client2 = DurableTaskGrpcClientFactory.getClient(port2); + + // Assert + assertNotNull(client1, "Client for port1 should not be null"); + assertNotNull(client2, "Client for port2 should not be null"); + assertNotSame(client1, client2, "getClient should return different instances for different ports"); + } + + @Test + void getClient_multiplePorts_maintainsCorrectMapping() { + // Arrange + int port1 = 5004; + int port2 = 5005; + int port3 = 5006; + + // Act + DurableTaskClient client1 = DurableTaskGrpcClientFactory.getClient(port1); + DurableTaskClient client2 = DurableTaskGrpcClientFactory.getClient(port2); + DurableTaskClient client3 = DurableTaskGrpcClientFactory.getClient(port3); + + // Request the same ports again + DurableTaskClient client1Again = DurableTaskGrpcClientFactory.getClient(port1); + DurableTaskClient client2Again = DurableTaskGrpcClientFactory.getClient(port2); + DurableTaskClient client3Again = DurableTaskGrpcClientFactory.getClient(port3); + + // Assert + // Verify each port returns the same instance + assertSame(client1, client1Again, "Port " + port1 + " should return the same instance"); + assertSame(client2, client2Again, "Port " + port2 + " should return the same instance"); + assertSame(client3, client3Again, "Port " + port3 + " should return the same instance"); + + // Verify all instances are different from each other + assertNotSame(client1, client2, "Client for port1 and port2 should be different"); + assertNotSame(client1, client3, "Client for port1 and port3 should be different"); + assertNotSame(client2, client3, "Client for port2 and port3 should be different"); + } +} diff --git a/internal/durabletask-protobuf/protos/orchestrator_service.proto b/internal/durabletask-protobuf/protos/orchestrator_service.proto index 88928c3b..8ef46a4a 100644 --- a/internal/durabletask-protobuf/protos/orchestrator_service.proto +++ b/internal/durabletask-protobuf/protos/orchestrator_service.proto @@ -41,6 +41,7 @@ message TaskFailureDetails { google.protobuf.StringValue stackTrace = 3; TaskFailureDetails innerFailure = 4; bool isNonRetriable = 5; + map properties = 6; } enum OrchestrationStatus { @@ -95,6 +96,7 @@ message TaskScheduledEvent { google.protobuf.StringValue version = 2; google.protobuf.StringValue input = 3; TraceContext parentTraceContext = 4; + map tags = 5; } message TaskCompletedEvent { @@ -113,6 +115,7 @@ message SubOrchestrationInstanceCreatedEvent { google.protobuf.StringValue version = 3; google.protobuf.StringValue input = 4; TraceContext parentTraceContext = 5; + map tags = 6; } message SubOrchestrationInstanceCompletedEvent { @@ -192,7 +195,7 @@ message EntityOperationCalledEvent { } message EntityLockRequestedEvent { - string criticalSectionId = 1; + string criticalSectionId = 1; repeated string lockSet = 2; int32 position = 3; google.protobuf.StringValue parentInstanceId = 4; // used only within messages, null in histories @@ -217,7 +220,19 @@ message EntityUnlockSentEvent { message EntityLockGrantedEvent { string criticalSectionId = 1; } - + +message ExecutionRewoundEvent { + google.protobuf.StringValue reason = 1; + google.protobuf.StringValue parentExecutionId = 2; // used only for rewinding suborchestrations, null otherwise + google.protobuf.StringValue instanceId = 3; // used only for rewinding suborchestrations, null otherwise + TraceContext parentTraceContext = 4; // used only for rewinding suborchestrations, null otherwise + google.protobuf.StringValue name = 5; // used by DTS backend only + google.protobuf.StringValue version = 6; // used by DTS backend only + google.protobuf.StringValue input = 7; // used by DTS backend only + ParentInstanceInfo parentInstance = 8; // used by DTS backend only + map tags = 9; // used by DTS backend only +} + message HistoryEvent { int32 eventId = 1; google.protobuf.Timestamp timestamp = 2; @@ -244,11 +259,12 @@ message HistoryEvent { ExecutionResumedEvent executionResumed = 22; EntityOperationSignaledEvent entityOperationSignaled = 23; EntityOperationCalledEvent entityOperationCalled = 24; - EntityOperationCompletedEvent entityOperationCompleted = 25; - EntityOperationFailedEvent entityOperationFailed = 26; + EntityOperationCompletedEvent entityOperationCompleted = 25; + EntityOperationFailedEvent entityOperationFailed = 26; EntityLockRequestedEvent entityLockRequested = 27; EntityLockGrantedEvent entityLockGranted = 28; EntityUnlockSentEvent entityUnlockSent = 29; + ExecutionRewoundEvent executionRewound = 30; } } @@ -256,6 +272,8 @@ message ScheduleTaskAction { string name = 1; google.protobuf.StringValue version = 2; google.protobuf.StringValue input = 3; + map tags = 4; + TraceContext parentTraceContext = 5; } message CreateSubOrchestrationAction { @@ -263,6 +281,8 @@ message CreateSubOrchestrationAction { string name = 2; google.protobuf.StringValue version = 3; google.protobuf.StringValue input = 4; + TraceContext parentTraceContext = 5; + map tags = 6; } message CreateTimerAction { @@ -282,6 +302,7 @@ message CompleteOrchestrationAction { google.protobuf.StringValue newVersion = 4; repeated HistoryEvent carryoverEvents = 5; TaskFailureDetails failureDetails = 6; + map tags = 7; } message TerminateOrchestrationAction { @@ -312,6 +333,11 @@ message OrchestratorAction { } } +message OrchestrationTraceContext { + google.protobuf.StringValue spanID = 1; + google.protobuf.Timestamp spanStartTime = 2; +} + message OrchestratorRequest { string instanceId = 1; google.protobuf.StringValue executionId = 2; @@ -320,6 +346,8 @@ message OrchestratorRequest { OrchestratorEntityParameters entityParameters = 5; bool requiresHistoryStreaming = 6; map properties = 7; + + OrchestrationTraceContext orchestrationTraceContext = 8; } message OrchestratorResponse { @@ -331,6 +359,17 @@ message OrchestratorResponse { // The number of work item events that were processed by the orchestrator. // This field is optional. If not set, the service should assume that the orchestrator processed all events. google.protobuf.Int32Value numEventsProcessed = 5; + OrchestrationTraceContext orchestrationTraceContext = 6; + + // Whether or not a history is required to complete the original OrchestratorRequest and none was provided. + bool requiresHistory = 7; + + // True if this is a partial (chunked) completion. The backend must keep the work item open until the final chunk (isPartial=false). + bool isPartial = 8; + + // Zero-based position of the current chunk within a chunked completion sequence. + // This field is omitted for non-chunked completions. + google.protobuf.Int32Value chunkIndex = 9; } message CreateInstanceRequest { @@ -343,6 +382,7 @@ message CreateInstanceRequest { google.protobuf.StringValue executionId = 7; map tags = 8; TraceContext parentTraceContext = 9; + google.protobuf.Timestamp requestTime = 10; } message OrchestrationIdReusePolicy { @@ -449,12 +489,28 @@ message QueryInstancesResponse { google.protobuf.StringValue continuationToken = 2; } +message ListInstanceIdsRequest { + repeated OrchestrationStatus runtimeStatus = 1; + google.protobuf.Timestamp completedTimeFrom = 2; + google.protobuf.Timestamp completedTimeTo = 3; + int32 pageSize = 4; + google.protobuf.StringValue lastInstanceKey = 5; +} + +message ListInstanceIdsResponse { + repeated string instanceIds = 1; + google.protobuf.StringValue lastInstanceKey = 2; +} + message PurgeInstancesRequest { oneof request { string instanceId = 1; PurgeInstanceFilter purgeInstanceFilter = 2; + InstanceBatch instanceBatch = 4; } bool recursive = 3; + // used in the case when an instanceId is specified to determine if the purge request is for an orchestration (as opposed to an entity) + bool isOrchestration = 5; } message PurgeInstanceFilter { @@ -468,6 +524,15 @@ message PurgeInstancesResponse { google.protobuf.BoolValue isComplete = 2; } +message RestartInstanceRequest { + string instanceId = 1; + bool restartWithNewInstanceId = 2; +} + +message RestartInstanceResponse { + string instanceId = 1; +} + message CreateTaskHubRequest { bool recreateIfExists = 1; } @@ -490,10 +555,12 @@ message SignalEntityRequest { google.protobuf.StringValue input = 3; string requestId = 4; google.protobuf.Timestamp scheduledTime = 5; + TraceContext parentTraceContext = 6; + google.protobuf.Timestamp requestTime = 7; } message SignalEntityResponse { - // no payload + // no payload } message GetEntityRequest { @@ -553,6 +620,7 @@ message EntityBatchRequest { string instanceId = 1; google.protobuf.StringValue entityState = 2; repeated OperationRequest operations = 3; + map properties = 4; } message EntityBatchResult { @@ -562,6 +630,8 @@ message EntityBatchResult { TaskFailureDetails failureDetails = 4; string completionToken = 5; repeated OperationInfo operationInfos = 6; // used only with DTS + // Whether or not an entity state is required to complete the original EntityBatchRequest and none was provided. + bool requiresState = 7; } message EntityRequest { @@ -575,6 +645,7 @@ message OperationRequest { string operation = 1; string requestId = 2; google.protobuf.StringValue input = 3; + TraceContext traceContext = 4; } message OperationResult { @@ -591,10 +662,14 @@ message OperationInfo { message OperationResultSuccess { google.protobuf.StringValue result = 1; + google.protobuf.Timestamp startTimeUtc = 2; + google.protobuf.Timestamp endTimeUtc = 3; } message OperationResultFailure { TaskFailureDetails failureDetails = 1; + google.protobuf.Timestamp startTimeUtc = 2; + google.protobuf.Timestamp endTimeUtc = 3; } message OperationAction { @@ -610,6 +685,8 @@ message SendSignalAction { string name = 2; google.protobuf.StringValue input = 3; google.protobuf.Timestamp scheduledTime = 4; + google.protobuf.Timestamp requestTime = 5; + TraceContext parentTraceContext = 6; } message StartNewOrchestrationAction { @@ -618,6 +695,8 @@ message StartNewOrchestrationAction { google.protobuf.StringValue version = 3; google.protobuf.StringValue input = 4; google.protobuf.Timestamp scheduledTime = 5; + google.protobuf.Timestamp requestTime = 6; + TraceContext parentTraceContext = 7; } message AbandonActivityTaskRequest { @@ -644,6 +723,17 @@ message AbandonEntityTaskResponse { // Empty. } +message SkipGracefulOrchestrationTerminationsRequest { + InstanceBatch instanceBatch = 1; + google.protobuf.StringValue reason = 2; +} + +message SkipGracefulOrchestrationTerminationsResponse { + // Those instances which could not be terminated because they had locked entities at the time of this termination call, + // are already in a terminal state (completed, failed, terminated, etc.), are not orchestrations, or do not exist (i.e. have been purged) + repeated string unterminatedInstanceIds = 1; +} + service TaskHubSidecarService { // Sends a hello request to the sidecar service. rpc Hello(google.protobuf.Empty) returns (google.protobuf.Empty); @@ -657,18 +747,21 @@ service TaskHubSidecarService { // Rewinds an orchestration instance to last known good state and replays from there. rpc RewindInstance(RewindInstanceRequest) returns (RewindInstanceResponse); + // Restarts an orchestration instance. + rpc RestartInstance(RestartInstanceRequest) returns (RestartInstanceResponse); + // Waits for an orchestration instance to reach a running or completion state. rpc WaitForInstanceStart(GetInstanceRequest) returns (GetInstanceResponse); - + // Waits for an orchestration instance to reach a completion state (completed, failed, terminated, etc.). rpc WaitForInstanceCompletion(GetInstanceRequest) returns (GetInstanceResponse); // Raises an event to a running orchestration instance. rpc RaiseEvent(RaiseEventRequest) returns (RaiseEventResponse); - + // Terminates a running orchestration instance. rpc TerminateInstance(TerminateRequest) returns (TerminateResponse); - + // Suspends a running orchestration instance. rpc SuspendInstance(SuspendRequest) returns (SuspendResponse); @@ -678,6 +771,9 @@ service TaskHubSidecarService { // rpc DeleteInstance(DeleteInstanceRequest) returns (DeleteInstanceResponse); rpc QueryInstances(QueryInstancesRequest) returns (QueryInstancesResponse); + + rpc ListInstanceIds(ListInstanceIdsRequest) returns (ListInstanceIdsResponse); + rpc PurgeInstances(PurgeInstancesRequest) returns (PurgeInstancesResponse); rpc GetWorkItems(GetWorkItemsRequest) returns (stream WorkItem); @@ -714,6 +810,10 @@ service TaskHubSidecarService { // Abandon an entity work item rpc AbandonTaskEntityWorkItem(AbandonEntityTaskRequest) returns (AbandonEntityTaskResponse); + + // "Skip" graceful termination of orchestrations by immediately changing their status in storage to "terminated". + // Note that a maximum of 500 orchestrations can be terminated at a time using this method. + rpc SkipGracefulOrchestrationTerminations(SkipGracefulOrchestrationTerminationsRequest) returns (SkipGracefulOrchestrationTerminationsResponse); } message GetWorkItemsRequest { @@ -732,6 +832,16 @@ enum WorkerCapability { // When set, the service may return work items without any history events as an optimization. // It is strongly recommended that all SDKs support this capability. WORKER_CAPABILITY_HISTORY_STREAMING = 1; + + // Indicates that the worker supports scheduled tasks. + // The service may send schedule-triggered orchestration work items, + // and the worker must handle them, including the scheduledTime field. + WORKER_CAPABILITY_SCHEDULED_TASKS = 2; + + // Signals that the worker can handle large payloads stored externally (e.g., Blob Storage). + // Work items may contain URI references instead of inline data, and the worker must fetch them. + // This avoids message size limits and reduces network overhead. + WORKER_CAPABILITY_LARGE_PAYLOADS = 3; } message WorkItem { @@ -750,7 +860,7 @@ message CompleteTaskResponse { } message HealthPing { - // No payload + // No payload } message StreamInstanceHistoryRequest { @@ -764,3 +874,8 @@ message StreamInstanceHistoryRequest { message HistoryChunk { repeated HistoryEvent events = 1; } + +message InstanceBatch { + // A maximum of 500 instance IDs can be provided in this list. + repeated string instanceIds = 1; +} From e87e98f4207eed3bc57c28bc4c53786420d75f73 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:12:14 +0000 Subject: [PATCH 3/3] Remove changes to DurableTaskGrpcClient.java and proto file, keep only test file Co-authored-by: sophiatev <38052607+sophiatev@users.noreply.github.com> --- .../durabletask/DurableTaskGrpcClient.java | 1 - .../protos/orchestrator_service.proto | 133 ++---------------- 2 files changed, 9 insertions(+), 125 deletions(-) diff --git a/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java b/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java index 21de905c..8f12b3ea 100644 --- a/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java +++ b/client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java @@ -63,7 +63,6 @@ public final class DurableTaskGrpcClient extends DurableTaskClient { DurableTaskGrpcClient(int port) { this.dataConverter = new JacksonDataConverter(); - this.defaultVersion = null; // Need to keep track of this channel so we can dispose it on close() this.managedSidecarChannel = ManagedChannelBuilder diff --git a/internal/durabletask-protobuf/protos/orchestrator_service.proto b/internal/durabletask-protobuf/protos/orchestrator_service.proto index 8ef46a4a..88928c3b 100644 --- a/internal/durabletask-protobuf/protos/orchestrator_service.proto +++ b/internal/durabletask-protobuf/protos/orchestrator_service.proto @@ -41,7 +41,6 @@ message TaskFailureDetails { google.protobuf.StringValue stackTrace = 3; TaskFailureDetails innerFailure = 4; bool isNonRetriable = 5; - map properties = 6; } enum OrchestrationStatus { @@ -96,7 +95,6 @@ message TaskScheduledEvent { google.protobuf.StringValue version = 2; google.protobuf.StringValue input = 3; TraceContext parentTraceContext = 4; - map tags = 5; } message TaskCompletedEvent { @@ -115,7 +113,6 @@ message SubOrchestrationInstanceCreatedEvent { google.protobuf.StringValue version = 3; google.protobuf.StringValue input = 4; TraceContext parentTraceContext = 5; - map tags = 6; } message SubOrchestrationInstanceCompletedEvent { @@ -195,7 +192,7 @@ message EntityOperationCalledEvent { } message EntityLockRequestedEvent { - string criticalSectionId = 1; + string criticalSectionId = 1; repeated string lockSet = 2; int32 position = 3; google.protobuf.StringValue parentInstanceId = 4; // used only within messages, null in histories @@ -220,19 +217,7 @@ message EntityUnlockSentEvent { message EntityLockGrantedEvent { string criticalSectionId = 1; } - -message ExecutionRewoundEvent { - google.protobuf.StringValue reason = 1; - google.protobuf.StringValue parentExecutionId = 2; // used only for rewinding suborchestrations, null otherwise - google.protobuf.StringValue instanceId = 3; // used only for rewinding suborchestrations, null otherwise - TraceContext parentTraceContext = 4; // used only for rewinding suborchestrations, null otherwise - google.protobuf.StringValue name = 5; // used by DTS backend only - google.protobuf.StringValue version = 6; // used by DTS backend only - google.protobuf.StringValue input = 7; // used by DTS backend only - ParentInstanceInfo parentInstance = 8; // used by DTS backend only - map tags = 9; // used by DTS backend only -} - + message HistoryEvent { int32 eventId = 1; google.protobuf.Timestamp timestamp = 2; @@ -259,12 +244,11 @@ message HistoryEvent { ExecutionResumedEvent executionResumed = 22; EntityOperationSignaledEvent entityOperationSignaled = 23; EntityOperationCalledEvent entityOperationCalled = 24; - EntityOperationCompletedEvent entityOperationCompleted = 25; - EntityOperationFailedEvent entityOperationFailed = 26; + EntityOperationCompletedEvent entityOperationCompleted = 25; + EntityOperationFailedEvent entityOperationFailed = 26; EntityLockRequestedEvent entityLockRequested = 27; EntityLockGrantedEvent entityLockGranted = 28; EntityUnlockSentEvent entityUnlockSent = 29; - ExecutionRewoundEvent executionRewound = 30; } } @@ -272,8 +256,6 @@ message ScheduleTaskAction { string name = 1; google.protobuf.StringValue version = 2; google.protobuf.StringValue input = 3; - map tags = 4; - TraceContext parentTraceContext = 5; } message CreateSubOrchestrationAction { @@ -281,8 +263,6 @@ message CreateSubOrchestrationAction { string name = 2; google.protobuf.StringValue version = 3; google.protobuf.StringValue input = 4; - TraceContext parentTraceContext = 5; - map tags = 6; } message CreateTimerAction { @@ -302,7 +282,6 @@ message CompleteOrchestrationAction { google.protobuf.StringValue newVersion = 4; repeated HistoryEvent carryoverEvents = 5; TaskFailureDetails failureDetails = 6; - map tags = 7; } message TerminateOrchestrationAction { @@ -333,11 +312,6 @@ message OrchestratorAction { } } -message OrchestrationTraceContext { - google.protobuf.StringValue spanID = 1; - google.protobuf.Timestamp spanStartTime = 2; -} - message OrchestratorRequest { string instanceId = 1; google.protobuf.StringValue executionId = 2; @@ -346,8 +320,6 @@ message OrchestratorRequest { OrchestratorEntityParameters entityParameters = 5; bool requiresHistoryStreaming = 6; map properties = 7; - - OrchestrationTraceContext orchestrationTraceContext = 8; } message OrchestratorResponse { @@ -359,17 +331,6 @@ message OrchestratorResponse { // The number of work item events that were processed by the orchestrator. // This field is optional. If not set, the service should assume that the orchestrator processed all events. google.protobuf.Int32Value numEventsProcessed = 5; - OrchestrationTraceContext orchestrationTraceContext = 6; - - // Whether or not a history is required to complete the original OrchestratorRequest and none was provided. - bool requiresHistory = 7; - - // True if this is a partial (chunked) completion. The backend must keep the work item open until the final chunk (isPartial=false). - bool isPartial = 8; - - // Zero-based position of the current chunk within a chunked completion sequence. - // This field is omitted for non-chunked completions. - google.protobuf.Int32Value chunkIndex = 9; } message CreateInstanceRequest { @@ -382,7 +343,6 @@ message CreateInstanceRequest { google.protobuf.StringValue executionId = 7; map tags = 8; TraceContext parentTraceContext = 9; - google.protobuf.Timestamp requestTime = 10; } message OrchestrationIdReusePolicy { @@ -489,28 +449,12 @@ message QueryInstancesResponse { google.protobuf.StringValue continuationToken = 2; } -message ListInstanceIdsRequest { - repeated OrchestrationStatus runtimeStatus = 1; - google.protobuf.Timestamp completedTimeFrom = 2; - google.protobuf.Timestamp completedTimeTo = 3; - int32 pageSize = 4; - google.protobuf.StringValue lastInstanceKey = 5; -} - -message ListInstanceIdsResponse { - repeated string instanceIds = 1; - google.protobuf.StringValue lastInstanceKey = 2; -} - message PurgeInstancesRequest { oneof request { string instanceId = 1; PurgeInstanceFilter purgeInstanceFilter = 2; - InstanceBatch instanceBatch = 4; } bool recursive = 3; - // used in the case when an instanceId is specified to determine if the purge request is for an orchestration (as opposed to an entity) - bool isOrchestration = 5; } message PurgeInstanceFilter { @@ -524,15 +468,6 @@ message PurgeInstancesResponse { google.protobuf.BoolValue isComplete = 2; } -message RestartInstanceRequest { - string instanceId = 1; - bool restartWithNewInstanceId = 2; -} - -message RestartInstanceResponse { - string instanceId = 1; -} - message CreateTaskHubRequest { bool recreateIfExists = 1; } @@ -555,12 +490,10 @@ message SignalEntityRequest { google.protobuf.StringValue input = 3; string requestId = 4; google.protobuf.Timestamp scheduledTime = 5; - TraceContext parentTraceContext = 6; - google.protobuf.Timestamp requestTime = 7; } message SignalEntityResponse { - // no payload + // no payload } message GetEntityRequest { @@ -620,7 +553,6 @@ message EntityBatchRequest { string instanceId = 1; google.protobuf.StringValue entityState = 2; repeated OperationRequest operations = 3; - map properties = 4; } message EntityBatchResult { @@ -630,8 +562,6 @@ message EntityBatchResult { TaskFailureDetails failureDetails = 4; string completionToken = 5; repeated OperationInfo operationInfos = 6; // used only with DTS - // Whether or not an entity state is required to complete the original EntityBatchRequest and none was provided. - bool requiresState = 7; } message EntityRequest { @@ -645,7 +575,6 @@ message OperationRequest { string operation = 1; string requestId = 2; google.protobuf.StringValue input = 3; - TraceContext traceContext = 4; } message OperationResult { @@ -662,14 +591,10 @@ message OperationInfo { message OperationResultSuccess { google.protobuf.StringValue result = 1; - google.protobuf.Timestamp startTimeUtc = 2; - google.protobuf.Timestamp endTimeUtc = 3; } message OperationResultFailure { TaskFailureDetails failureDetails = 1; - google.protobuf.Timestamp startTimeUtc = 2; - google.protobuf.Timestamp endTimeUtc = 3; } message OperationAction { @@ -685,8 +610,6 @@ message SendSignalAction { string name = 2; google.protobuf.StringValue input = 3; google.protobuf.Timestamp scheduledTime = 4; - google.protobuf.Timestamp requestTime = 5; - TraceContext parentTraceContext = 6; } message StartNewOrchestrationAction { @@ -695,8 +618,6 @@ message StartNewOrchestrationAction { google.protobuf.StringValue version = 3; google.protobuf.StringValue input = 4; google.protobuf.Timestamp scheduledTime = 5; - google.protobuf.Timestamp requestTime = 6; - TraceContext parentTraceContext = 7; } message AbandonActivityTaskRequest { @@ -723,17 +644,6 @@ message AbandonEntityTaskResponse { // Empty. } -message SkipGracefulOrchestrationTerminationsRequest { - InstanceBatch instanceBatch = 1; - google.protobuf.StringValue reason = 2; -} - -message SkipGracefulOrchestrationTerminationsResponse { - // Those instances which could not be terminated because they had locked entities at the time of this termination call, - // are already in a terminal state (completed, failed, terminated, etc.), are not orchestrations, or do not exist (i.e. have been purged) - repeated string unterminatedInstanceIds = 1; -} - service TaskHubSidecarService { // Sends a hello request to the sidecar service. rpc Hello(google.protobuf.Empty) returns (google.protobuf.Empty); @@ -747,21 +657,18 @@ service TaskHubSidecarService { // Rewinds an orchestration instance to last known good state and replays from there. rpc RewindInstance(RewindInstanceRequest) returns (RewindInstanceResponse); - // Restarts an orchestration instance. - rpc RestartInstance(RestartInstanceRequest) returns (RestartInstanceResponse); - // Waits for an orchestration instance to reach a running or completion state. rpc WaitForInstanceStart(GetInstanceRequest) returns (GetInstanceResponse); - + // Waits for an orchestration instance to reach a completion state (completed, failed, terminated, etc.). rpc WaitForInstanceCompletion(GetInstanceRequest) returns (GetInstanceResponse); // Raises an event to a running orchestration instance. rpc RaiseEvent(RaiseEventRequest) returns (RaiseEventResponse); - + // Terminates a running orchestration instance. rpc TerminateInstance(TerminateRequest) returns (TerminateResponse); - + // Suspends a running orchestration instance. rpc SuspendInstance(SuspendRequest) returns (SuspendResponse); @@ -771,9 +678,6 @@ service TaskHubSidecarService { // rpc DeleteInstance(DeleteInstanceRequest) returns (DeleteInstanceResponse); rpc QueryInstances(QueryInstancesRequest) returns (QueryInstancesResponse); - - rpc ListInstanceIds(ListInstanceIdsRequest) returns (ListInstanceIdsResponse); - rpc PurgeInstances(PurgeInstancesRequest) returns (PurgeInstancesResponse); rpc GetWorkItems(GetWorkItemsRequest) returns (stream WorkItem); @@ -810,10 +714,6 @@ service TaskHubSidecarService { // Abandon an entity work item rpc AbandonTaskEntityWorkItem(AbandonEntityTaskRequest) returns (AbandonEntityTaskResponse); - - // "Skip" graceful termination of orchestrations by immediately changing their status in storage to "terminated". - // Note that a maximum of 500 orchestrations can be terminated at a time using this method. - rpc SkipGracefulOrchestrationTerminations(SkipGracefulOrchestrationTerminationsRequest) returns (SkipGracefulOrchestrationTerminationsResponse); } message GetWorkItemsRequest { @@ -832,16 +732,6 @@ enum WorkerCapability { // When set, the service may return work items without any history events as an optimization. // It is strongly recommended that all SDKs support this capability. WORKER_CAPABILITY_HISTORY_STREAMING = 1; - - // Indicates that the worker supports scheduled tasks. - // The service may send schedule-triggered orchestration work items, - // and the worker must handle them, including the scheduledTime field. - WORKER_CAPABILITY_SCHEDULED_TASKS = 2; - - // Signals that the worker can handle large payloads stored externally (e.g., Blob Storage). - // Work items may contain URI references instead of inline data, and the worker must fetch them. - // This avoids message size limits and reduces network overhead. - WORKER_CAPABILITY_LARGE_PAYLOADS = 3; } message WorkItem { @@ -860,7 +750,7 @@ message CompleteTaskResponse { } message HealthPing { - // No payload + // No payload } message StreamInstanceHistoryRequest { @@ -874,8 +764,3 @@ message StreamInstanceHistoryRequest { message HistoryChunk { repeated HistoryEvent events = 1; } - -message InstanceBatch { - // A maximum of 500 instance IDs can be provided in this list. - repeated string instanceIds = 1; -}