diff --git a/dapr/ext/workflow/_durabletask/aio/client.py b/dapr/ext/workflow/_durabletask/aio/client.py index a5da39b14..35f44c646 100644 --- a/dapr/ext/workflow/_durabletask/aio/client.py +++ b/dapr/ext/workflow/_durabletask/aio/client.py @@ -40,6 +40,7 @@ WorkflowState, _TransientTimeout, new_orchestration_state, + new_task_router, ) # If `opentelemetry-instrumentation-grpc` is available, enable the gRPC client interceptor @@ -114,6 +115,7 @@ async def schedule_new_orchestration( instance_id: Optional[str] = None, start_at: Optional[datetime] = None, reuse_id_policy: Optional[WorkflowIdReusePolicy] = None, + app_id: Optional[str] = None, ) -> str: name = orchestrator if isinstance(orchestrator, str) else task.get_name(orchestrator) @@ -125,6 +127,7 @@ async def schedule_new_orchestration( else None, scheduledStartTimestamp=helpers.new_timestamp(start_at) if start_at else None, version=helpers.get_string_value(None), + router=new_task_router(app_id), ) self._logger.info(f"Starting new '{name}' instance with ID = '{req.instanceId}'.") @@ -132,16 +135,33 @@ async def schedule_new_orchestration( return res.instanceId async def get_orchestration_state( - self, instance_id: str, *, fetch_payloads: bool = True + self, + instance_id: str, + *, + fetch_payloads: bool = True, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: - req = pb.GetInstanceRequest(instanceId=instance_id, getInputsAndOutputs=fetch_payloads) + req = pb.GetInstanceRequest( + instanceId=instance_id, + getInputsAndOutputs=fetch_payloads, + router=new_task_router(app_id), + ) res: pb.GetInstanceResponse = await self._get_stub().GetInstance(req) return new_orchestration_state(req.instanceId, res) async def wait_for_orchestration_start( - self, instance_id: str, *, fetch_payloads: bool = False, timeout: Optional[int] = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = False, + timeout: Optional[int] = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: - req = pb.GetInstanceRequest(instanceId=instance_id, getInputsAndOutputs=fetch_payloads) + req = pb.GetInstanceRequest( + instanceId=instance_id, + getInputsAndOutputs=fetch_payloads, + router=new_task_router(app_id), + ) self._logger.info( f"Waiting {'indefinitely' if timeout in (0, None) else f'up to {timeout}s'} for instance '{instance_id}' to start." ) @@ -158,9 +178,18 @@ async def _call(grpc_timeout): raise TimeoutError('Timed-out waiting for the orchestration to start') async def wait_for_orchestration_completion( - self, instance_id: str, *, fetch_payloads: bool = True, timeout: Optional[int] = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = True, + timeout: Optional[int] = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: - req = pb.GetInstanceRequest(instanceId=instance_id, getInputsAndOutputs=fetch_payloads) + req = pb.GetInstanceRequest( + instanceId=instance_id, + getInputsAndOutputs=fetch_payloads, + router=new_task_router(app_id), + ) self._logger.info( f"Waiting {'indefinitely' if timeout in (0, None) else f'up to {timeout}s'} for instance '{instance_id}' to complete." ) @@ -270,40 +299,78 @@ async def _call_with_transient_retry(self, instance_id, timeout, call_fn): raise _TransientTimeout() async def raise_orchestration_event( - self, instance_id: str, event_name: str, *, data: Optional[Any] = None + self, + instance_id: str, + event_name: str, + *, + data: Optional[Any] = None, + app_id: Optional[str] = None, ): req = pb.RaiseEventRequest( instanceId=instance_id, name=event_name, input=wrappers_pb2.StringValue(value=shared.to_json(data)) if data else None, + router=new_task_router(app_id), ) self._logger.info(f"Raising event '{event_name}' for instance '{instance_id}'.") await self._get_stub().RaiseEvent(req) async def terminate_orchestration( - self, instance_id: str, *, output: Optional[Any] = None, recursive: bool = True + self, + instance_id: str, + *, + output: Optional[Any] = None, + recursive: bool = True, + app_id: Optional[str] = None, ): req = pb.TerminateRequest( instanceId=instance_id, output=wrappers_pb2.StringValue(value=shared.to_json(output)) if output else None, recursive=recursive, + router=new_task_router(app_id), ) self._logger.info(f"Terminating instance '{instance_id}'.") await self._get_stub().TerminateInstance(req) - async def suspend_orchestration(self, instance_id: str): - req = pb.SuspendRequest(instanceId=instance_id) + async def suspend_orchestration( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ): + req = pb.SuspendRequest( + instanceId=instance_id, + router=new_task_router(app_id), + ) self._logger.info(f"Suspending instance '{instance_id}'.") await self._get_stub().SuspendInstance(req) - async def resume_orchestration(self, instance_id: str): - req = pb.ResumeRequest(instanceId=instance_id) + async def resume_orchestration( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ): + req = pb.ResumeRequest( + instanceId=instance_id, + router=new_task_router(app_id), + ) self._logger.info(f"Resuming instance '{instance_id}'.") await self._get_stub().ResumeInstance(req) - async def purge_orchestration(self, instance_id: str, recursive: bool = True): - req = pb.PurgeInstancesRequest(instanceId=instance_id, recursive=recursive) + async def purge_orchestration( + self, + instance_id: str, + recursive: bool = True, + *, + app_id: Optional[str] = None, + ): + req = pb.PurgeInstancesRequest( + instanceId=instance_id, + recursive=recursive, + router=new_task_router(app_id), + ) self._logger.info(f"Purging instance '{instance_id}'.") await self._get_stub().PurgeInstances(req) diff --git a/dapr/ext/workflow/_durabletask/client.py b/dapr/ext/workflow/_durabletask/client.py index 07e63d4a7..e3d11704d 100644 --- a/dapr/ext/workflow/_durabletask/client.py +++ b/dapr/ext/workflow/_durabletask/client.py @@ -109,6 +109,16 @@ def raise_if_failed(self): ) +def new_task_router(app_id: Optional[str]) -> Optional[pb.TaskRouter]: + """Builds a TaskRouter targeting another app, or None when no routing is requested. + + Only the target app ID is set; the sidecar stamps sourceAppID. + """ + if app_id is None: + return None + return pb.TaskRouter(targetAppID=app_id) + + class OrchestrationFailedError(Exception): def __init__(self, message: str, failure_details: task.FailureDetails): super().__init__(message) @@ -210,6 +220,7 @@ def schedule_new_orchestration( instance_id: Optional[str] = None, start_at: Optional[datetime] = None, reuse_id_policy: Optional[WorkflowIdReusePolicy] = None, + app_id: Optional[str] = None, ) -> str: name = orchestrator if isinstance(orchestrator, str) else task.get_name(orchestrator) @@ -223,6 +234,7 @@ def schedule_new_orchestration( input=input_pb, scheduledStartTimestamp=helpers.new_timestamp(start_at) if start_at else None, version=wrappers_pb2.StringValue(value=''), + router=new_task_router(app_id), ) self._logger.info(f"Starting new '{name}' instance with ID = '{req.instanceId}'.") @@ -230,16 +242,33 @@ def schedule_new_orchestration( return res.instanceId def get_orchestration_state( - self, instance_id: str, *, fetch_payloads: bool = True + self, + instance_id: str, + *, + fetch_payloads: bool = True, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: - req = pb.GetInstanceRequest(instanceId=instance_id, getInputsAndOutputs=fetch_payloads) + req = pb.GetInstanceRequest( + instanceId=instance_id, + getInputsAndOutputs=fetch_payloads, + router=new_task_router(app_id), + ) res: pb.GetInstanceResponse = self._stub.GetInstance(req) return new_orchestration_state(req.instanceId, res) def wait_for_orchestration_start( - self, instance_id: str, *, fetch_payloads: bool = False, timeout: Optional[int] = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = False, + timeout: Optional[int] = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: - req = pb.GetInstanceRequest(instanceId=instance_id, getInputsAndOutputs=fetch_payloads) + req = pb.GetInstanceRequest( + instanceId=instance_id, + getInputsAndOutputs=fetch_payloads, + router=new_task_router(app_id), + ) self._logger.info( f"Waiting {'indefinitely' if timeout in (0, None) else f'up to {timeout}s'} for instance '{instance_id}' to start." ) @@ -254,9 +283,18 @@ def _call(grpc_timeout): raise TimeoutError('Timed-out waiting for the orchestration to start') def wait_for_orchestration_completion( - self, instance_id: str, *, fetch_payloads: bool = True, timeout: Optional[int] = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = True, + timeout: Optional[int] = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: - req = pb.GetInstanceRequest(instanceId=instance_id, getInputsAndOutputs=fetch_payloads) + req = pb.GetInstanceRequest( + instanceId=instance_id, + getInputsAndOutputs=fetch_payloads, + router=new_task_router(app_id), + ) self._logger.info( f"Waiting {'indefinitely' if timeout in (0, None) else f'up to {timeout}s'} for instance '{instance_id}' to complete." ) @@ -393,40 +431,78 @@ def _call_with_transient_retry(self, instance_id, timeout, call_fn): raise _TransientTimeout() def raise_orchestration_event( - self, instance_id: str, event_name: str, *, data: Optional[Any] = None + self, + instance_id: str, + event_name: str, + *, + data: Optional[Any] = None, + app_id: Optional[str] = None, ): req = pb.RaiseEventRequest( instanceId=instance_id, name=event_name, input=wrappers_pb2.StringValue(value=shared.to_json(data)) if data else None, + router=new_task_router(app_id), ) self._logger.info(f"Raising event '{event_name}' for instance '{instance_id}'.") self._stub.RaiseEvent(req) def terminate_orchestration( - self, instance_id: str, *, output: Optional[Any] = None, recursive: bool = True + self, + instance_id: str, + *, + output: Optional[Any] = None, + recursive: bool = True, + app_id: Optional[str] = None, ): req = pb.TerminateRequest( instanceId=instance_id, output=wrappers_pb2.StringValue(value=shared.to_json(output)) if output else None, recursive=recursive, + router=new_task_router(app_id), ) self._logger.info(f"Terminating instance '{instance_id}'.") self._stub.TerminateInstance(req) - def suspend_orchestration(self, instance_id: str): - req = pb.SuspendRequest(instanceId=instance_id) + def suspend_orchestration( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ): + req = pb.SuspendRequest( + instanceId=instance_id, + router=new_task_router(app_id), + ) self._logger.info(f"Suspending instance '{instance_id}'.") self._stub.SuspendInstance(req) - def resume_orchestration(self, instance_id: str): - req = pb.ResumeRequest(instanceId=instance_id) + def resume_orchestration( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ): + req = pb.ResumeRequest( + instanceId=instance_id, + router=new_task_router(app_id), + ) self._logger.info(f"Resuming instance '{instance_id}'.") self._stub.ResumeInstance(req) - def purge_orchestration(self, instance_id: str, recursive: bool = True): - req = pb.PurgeInstancesRequest(instanceId=instance_id, recursive=recursive) + def purge_orchestration( + self, + instance_id: str, + recursive: bool = True, + *, + app_id: Optional[str] = None, + ): + req = pb.PurgeInstancesRequest( + instanceId=instance_id, + recursive=recursive, + router=new_task_router(app_id), + ) self._logger.info(f"Purging instance '{instance_id}'.") self._stub.PurgeInstances(req) diff --git a/dapr/ext/workflow/_durabletask/internal/PROTO_SOURCE_COMMIT_HASH b/dapr/ext/workflow/_durabletask/internal/PROTO_SOURCE_COMMIT_HASH index 08691e6da..41af5e2a0 100644 --- a/dapr/ext/workflow/_durabletask/internal/PROTO_SOURCE_COMMIT_HASH +++ b/dapr/ext/workflow/_durabletask/internal/PROTO_SOURCE_COMMIT_HASH @@ -1 +1 @@ -9d3681cb82a03aad057f361102d3a7e0ae638462 +f31a2a0523e01feda8f41cc22512ed70ee59b3ad diff --git a/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.py b/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.py index 7b43827ed..cae2467d1 100644 --- a/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.py +++ b/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.py @@ -28,7 +28,7 @@ from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x62\x61\x63kend_service.proto\x12\x1d\x64urabletask.protos.backend.v1\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"T\n\x0f\x41\x64\x64\x45ventRequest\x12#\n\x08instance\x18\x01 \x01(\x0b\x32\x11.WorkflowInstance\x12\x1c\n\x05\x65vent\x18\x02 \x01(\x0b\x32\r.HistoryEvent\"\x12\n\x10\x41\x64\x64\x45ventResponse\"`\n\x1f\x43ompleteActivityWorkItemRequest\x12\x17\n\x0f\x63ompletionToken\x18\x01 \x01(\t\x12$\n\rresponseEvent\x18\x02 \x01(\x0b\x32\r.HistoryEvent\"\"\n CompleteActivityWorkItemResponse\"\xa4\x03\n\x1f\x43ompleteWorkflowWorkItemRequest\x12\x17\n\x0f\x63ompletionToken\x18\x01 \x01(\t\x12#\n\x08instance\x18\x02 \x01(\x0b\x32\x11.WorkflowInstance\x12+\n\rruntimeStatus\x18\x03 \x01(\x0e\x32\x14.OrchestrationStatus\x12\x32\n\x0c\x63ustomStatus\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12!\n\nnewHistory\x18\x05 \x03(\x0b\x32\r.HistoryEvent\x12\x1f\n\x08newTasks\x18\x06 \x03(\x0b\x32\r.HistoryEvent\x12 \n\tnewTimers\x18\x07 \x03(\x0b\x32\r.HistoryEvent\x12\x43\n\x0bnewMessages\x18\x08 \x03(\x0b\x32..durabletask.protos.backend.v1.WorkflowMessage\x12\x37\n\x12numEventsProcessed\x18\t \x01(\x0b\x32\x1b.google.protobuf.Int32Value\"\"\n CompleteWorkflowWorkItemResponse\"T\n\x0fWorkflowMessage\x12#\n\x08instance\x18\x01 \x01(\x0b\x32\x11.WorkflowInstance\x12\x1c\n\x05\x65vent\x18\x02 \x01(\x0b\x32\r.HistoryEvent\"\x9c\x01\n\x14\x42\x61\x63kendWorkflowState\x12\x1c\n\x05inbox\x18\x01 \x03(\x0b\x32\r.HistoryEvent\x12\x1e\n\x07history\x18\x02 \x03(\x0b\x32\r.HistoryEvent\x12\x32\n\x0c\x63ustomStatus\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x12\n\ngeneration\x18\x04 \x01(\x04\"\x83\x01\n\x12\x41\x63tivityInvocation\x12#\n\x0chistoryEvent\x18\x01 \x01(\x0b\x32\r.HistoryEvent\x12\x32\n\x11propagatedHistory\x18\x02 \x01(\x0b\x32\x12.PropagatedHistoryH\x00\x88\x01\x01\x42\x14\n\x12_propagatedHistory\"\x9a\x01\n\x1d\x43reateWorkflowInstanceRequest\x12!\n\nstartEvent\x18\x01 \x01(\x0b\x32\r.HistoryEvent\x12\x32\n\x11propagatedHistory\x18\x03 \x01(\x0b\x32\x12.PropagatedHistoryH\x00\x88\x01\x01\x42\x14\n\x12_propagatedHistoryJ\x04\x08\x02\x10\x03R\x06policy\"\x94\x05\n\x10WorkflowMetadata\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12+\n\rruntimeStatus\x18\x03 \x01(\x0e\x32\x14.OrchestrationStatus\x12-\n\tcreatedAt\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rlastUpdatedAt\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x05input\x18\x06 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x06output\x18\x07 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0c\x63ustomStatus\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\t \x01(\x0b\x32\x13.TaskFailureDetails\x12/\n\x0b\x63ompletedAt\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x18\n\x10parentInstanceId\x18\x0b \x01(\t\x12\x32\n\x07version\x18\x0c \x01(\x0b\x32\x1c.google.protobuf.StringValueH\x00\x88\x01\x01\x12\x36\n\x0bparentAppId\x18\r \x01(\x0b\x32\x1c.google.protobuf.StringValueH\x01\x88\x01\x01\x12\x32\n\tstartedAt\x18\x0e \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02\x88\x01\x01\x42\n\n\x08_versionB\x0e\n\x0c_parentAppIdB\x0c\n\n_startedAt\"\xc3\x01\n\x1c\x42\x61\x63kendWorkflowStateMetadata\x12\x13\n\x0binboxLength\x18\x01 \x01(\x04\x12\x15\n\rhistoryLength\x18\x02 \x01(\x04\x12\x12\n\ngeneration\x18\x03 \x01(\x04\x12\x17\n\x0fsignatureLength\x18\x04 \x01(\x04\x12 \n\x18signingCertificateLength\x18\x05 \x01(\x04\x12(\n externalSigningCertificateLength\x18\x06 \x01(\x04\")\n\x12SigningCertificate\x12\x13\n\x0b\x63\x65rtificate\x18\x01 \x01(\x0c\"\xc4\x01\n\x10HistorySignature\x12\x17\n\x0fstartEventIndex\x18\x01 \x01(\x04\x12\x12\n\neventCount\x18\x02 \x01(\x04\x12$\n\x17previousSignatureDigest\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0c\x65ventsDigest\x18\x04 \x01(\x0c\x12\x18\n\x10\x63\x65rtificateIndex\x18\x05 \x01(\x04\x12\x11\n\tsignature\x18\x06 \x01(\x0c\x42\x1a\n\x18_previousSignatureDigest\"E\n\x0c\x44urableTimer\x12!\n\ntimerEvent\x18\x01 \x01(\x0b\x32\r.HistoryEvent\x12\x12\n\ngeneration\x18\x02 \x01(\x04\x42V\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x62\x61\x63kend_service.proto\x12\x1d\x64urabletask.protos.backend.v1\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"T\n\x0f\x41\x64\x64\x45ventRequest\x12#\n\x08instance\x18\x01 \x01(\x0b\x32\x11.WorkflowInstance\x12\x1c\n\x05\x65vent\x18\x02 \x01(\x0b\x32\r.HistoryEvent\"\x12\n\x10\x41\x64\x64\x45ventResponse\"`\n\x1f\x43ompleteActivityWorkItemRequest\x12\x17\n\x0f\x63ompletionToken\x18\x01 \x01(\t\x12$\n\rresponseEvent\x18\x02 \x01(\x0b\x32\r.HistoryEvent\"\"\n CompleteActivityWorkItemResponse\"\xa4\x03\n\x1f\x43ompleteWorkflowWorkItemRequest\x12\x17\n\x0f\x63ompletionToken\x18\x01 \x01(\t\x12#\n\x08instance\x18\x02 \x01(\x0b\x32\x11.WorkflowInstance\x12+\n\rruntimeStatus\x18\x03 \x01(\x0e\x32\x14.OrchestrationStatus\x12\x32\n\x0c\x63ustomStatus\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12!\n\nnewHistory\x18\x05 \x03(\x0b\x32\r.HistoryEvent\x12\x1f\n\x08newTasks\x18\x06 \x03(\x0b\x32\r.HistoryEvent\x12 \n\tnewTimers\x18\x07 \x03(\x0b\x32\r.HistoryEvent\x12\x43\n\x0bnewMessages\x18\x08 \x03(\x0b\x32..durabletask.protos.backend.v1.WorkflowMessage\x12\x37\n\x12numEventsProcessed\x18\t \x01(\x0b\x32\x1b.google.protobuf.Int32Value\"\"\n CompleteWorkflowWorkItemResponse\"T\n\x0fWorkflowMessage\x12#\n\x08instance\x18\x01 \x01(\x0b\x32\x11.WorkflowInstance\x12\x1c\n\x05\x65vent\x18\x02 \x01(\x0b\x32\r.HistoryEvent\"\x9c\x01\n\x14\x42\x61\x63kendWorkflowState\x12\x1c\n\x05inbox\x18\x01 \x03(\x0b\x32\r.HistoryEvent\x12\x1e\n\x07history\x18\x02 \x03(\x0b\x32\r.HistoryEvent\x12\x32\n\x0c\x63ustomStatus\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x12\n\ngeneration\x18\x04 \x01(\x04\"\x83\x01\n\x12\x41\x63tivityInvocation\x12#\n\x0chistoryEvent\x18\x01 \x01(\x0b\x32\r.HistoryEvent\x12\x32\n\x11propagatedHistory\x18\x02 \x01(\x0b\x32\x12.PropagatedHistoryH\x00\x88\x01\x01\x42\x14\n\x12_propagatedHistory\"\xbb\x01\n\x1d\x43reateWorkflowInstanceRequest\x12!\n\nstartEvent\x18\x01 \x01(\x0b\x32\r.HistoryEvent\x12\x32\n\x11propagatedHistory\x18\x03 \x01(\x0b\x32\x12.PropagatedHistoryH\x00\x88\x01\x01\x12\x1f\n\x17\x65nforceUniqueInstanceId\x18\x04 \x01(\x08\x42\x14\n\x12_propagatedHistoryJ\x04\x08\x02\x10\x03R\x06policy\"\x94\x05\n\x10WorkflowMetadata\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12+\n\rruntimeStatus\x18\x03 \x01(\x0e\x32\x14.OrchestrationStatus\x12-\n\tcreatedAt\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rlastUpdatedAt\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x05input\x18\x06 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x06output\x18\x07 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0c\x63ustomStatus\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\t \x01(\x0b\x32\x13.TaskFailureDetails\x12/\n\x0b\x63ompletedAt\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x18\n\x10parentInstanceId\x18\x0b \x01(\t\x12\x32\n\x07version\x18\x0c \x01(\x0b\x32\x1c.google.protobuf.StringValueH\x00\x88\x01\x01\x12\x36\n\x0bparentAppId\x18\r \x01(\x0b\x32\x1c.google.protobuf.StringValueH\x01\x88\x01\x01\x12\x32\n\tstartedAt\x18\x0e \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x02\x88\x01\x01\x42\n\n\x08_versionB\x0e\n\x0c_parentAppIdB\x0c\n\n_startedAt\"\xc3\x01\n\x1c\x42\x61\x63kendWorkflowStateMetadata\x12\x13\n\x0binboxLength\x18\x01 \x01(\x04\x12\x15\n\rhistoryLength\x18\x02 \x01(\x04\x12\x12\n\ngeneration\x18\x03 \x01(\x04\x12\x17\n\x0fsignatureLength\x18\x04 \x01(\x04\x12 \n\x18signingCertificateLength\x18\x05 \x01(\x04\x12(\n externalSigningCertificateLength\x18\x06 \x01(\x04\")\n\x12SigningCertificate\x12\x13\n\x0b\x63\x65rtificate\x18\x01 \x01(\x0c\"\xc4\x01\n\x10HistorySignature\x12\x17\n\x0fstartEventIndex\x18\x01 \x01(\x04\x12\x12\n\neventCount\x18\x02 \x01(\x04\x12$\n\x17previousSignatureDigest\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0c\x65ventsDigest\x18\x04 \x01(\x0c\x12\x18\n\x10\x63\x65rtificateIndex\x18\x05 \x01(\x04\x12\x11\n\tsignature\x18\x06 \x01(\x0c\x42\x1a\n\x18_previousSignatureDigest\"E\n\x0c\x44urableTimer\x12!\n\ntimerEvent\x18\x01 \x01(\x0b\x32\r.HistoryEvent\x12\x12\n\ngeneration\x18\x02 \x01(\x04\x42V\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -55,15 +55,15 @@ _globals['_ACTIVITYINVOCATION']._serialized_start=1109 _globals['_ACTIVITYINVOCATION']._serialized_end=1240 _globals['_CREATEWORKFLOWINSTANCEREQUEST']._serialized_start=1243 - _globals['_CREATEWORKFLOWINSTANCEREQUEST']._serialized_end=1397 - _globals['_WORKFLOWMETADATA']._serialized_start=1400 - _globals['_WORKFLOWMETADATA']._serialized_end=2060 - _globals['_BACKENDWORKFLOWSTATEMETADATA']._serialized_start=2063 - _globals['_BACKENDWORKFLOWSTATEMETADATA']._serialized_end=2258 - _globals['_SIGNINGCERTIFICATE']._serialized_start=2260 - _globals['_SIGNINGCERTIFICATE']._serialized_end=2301 - _globals['_HISTORYSIGNATURE']._serialized_start=2304 - _globals['_HISTORYSIGNATURE']._serialized_end=2500 - _globals['_DURABLETIMER']._serialized_start=2502 - _globals['_DURABLETIMER']._serialized_end=2571 + _globals['_CREATEWORKFLOWINSTANCEREQUEST']._serialized_end=1430 + _globals['_WORKFLOWMETADATA']._serialized_start=1433 + _globals['_WORKFLOWMETADATA']._serialized_end=2093 + _globals['_BACKENDWORKFLOWSTATEMETADATA']._serialized_start=2096 + _globals['_BACKENDWORKFLOWSTATEMETADATA']._serialized_end=2291 + _globals['_SIGNINGCERTIFICATE']._serialized_start=2293 + _globals['_SIGNINGCERTIFICATE']._serialized_end=2334 + _globals['_HISTORYSIGNATURE']._serialized_start=2337 + _globals['_HISTORYSIGNATURE']._serialized_end=2533 + _globals['_DURABLETIMER']._serialized_start=2535 + _globals['_DURABLETIMER']._serialized_end=2604 # @@protoc_insertion_point(module_scope) diff --git a/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.pyi b/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.pyi index 08f6d2d58..c4d2739ab 100644 --- a/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.pyi +++ b/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.pyi @@ -277,6 +277,12 @@ class CreateWorkflowInstanceRequest(_message.Message): STARTEVENT_FIELD_NUMBER: _builtins.int PROPAGATEDHISTORY_FIELD_NUMBER: _builtins.int + ENFORCEUNIQUEINSTANCEID_FIELD_NUMBER: _builtins.int + enforceUniqueInstanceId: _builtins.bool + """When true, the request fails with an ALREADY_EXISTS error if a workflow + instance with the same instanceId already exists, whether active or + completed. When false, an existing completed instance is restarted. + """ @_builtins.property def startEvent(self) -> _history_events_pb2.HistoryEvent: ... @_builtins.property @@ -288,10 +294,11 @@ class CreateWorkflowInstanceRequest(_message.Message): *, startEvent: _history_events_pb2.HistoryEvent | None = ..., propagatedHistory: _history_events_pb2.PropagatedHistory | None = ..., + enforceUniqueInstanceId: _builtins.bool = ..., ) -> None: ... _HasFieldArgType: _TypeAlias = _typing.Literal["_propagatedHistory", b"_propagatedHistory", "propagatedHistory", b"propagatedHistory", "startEvent", b"startEvent"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["_propagatedHistory", b"_propagatedHistory", "propagatedHistory", b"propagatedHistory", "startEvent", b"startEvent"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_propagatedHistory", b"_propagatedHistory", "enforceUniqueInstanceId", b"enforceUniqueInstanceId", "propagatedHistory", b"propagatedHistory", "startEvent", b"startEvent"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... _WhichOneofReturnType__propagatedHistory: _TypeAlias = _typing.Literal["propagatedHistory"] # noqa: Y015 _WhichOneofArgType__propagatedHistory: _TypeAlias = _typing.Literal["_propagatedHistory", b"_propagatedHistory"] # noqa: Y015 diff --git a/dapr/ext/workflow/_durabletask/internal/helpers.py b/dapr/ext/workflow/_durabletask/internal/helpers.py index 387a9ee10..56ab04461 100644 --- a/dapr/ext/workflow/_durabletask/internal/helpers.py +++ b/dapr/ext/workflow/_durabletask/internal/helpers.py @@ -200,10 +200,11 @@ def new_schedule_task_action( task_execution_id: str = '', propagation_scope: Optional[int] = None, ) -> pb.WorkflowAction: + # Routing is carried by the enclosing WorkflowAction.router; the inner + # ScheduleTaskAction router field is reserved in the protos. schedule = pb.ScheduleTaskAction( name=name, input=get_string_value(encoded_input), - router=router, taskExecutionId=task_execution_id, ) if propagation_scope is not None: @@ -229,11 +230,12 @@ def new_create_child_workflow_action( router: Optional[pb.TaskRouter] = None, propagation_scope: Optional[int] = None, ) -> pb.WorkflowAction: + # Routing is carried by the enclosing WorkflowAction.router; the inner + # CreateChildWorkflowAction router field is reserved in the protos. child = pb.CreateChildWorkflowAction( name=name, instanceId=instance_id, input=get_string_value(encoded_input), - router=router, ) if propagation_scope is not None: child.historyPropagationScope = propagation_scope diff --git a/dapr/ext/workflow/_durabletask/internal/history_events_pb2.py b/dapr/ext/workflow/_durabletask/internal/history_events_pb2.py index b70c3a5f5..472616d37 100644 --- a/dapr/ext/workflow/_durabletask/internal/history_events_pb2.py +++ b/dapr/ext/workflow/_durabletask/internal/history_events_pb2.py @@ -28,7 +28,7 @@ from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14history_events.proto\x1a\x13orchestration.proto\x1a\x11\x61ttestation.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xd6\x03\n\x15\x45xecutionStartedEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12+\n\x0eparentInstance\x18\x05 \x01(\x0b\x32\x13.ParentInstanceInfo\x12;\n\x17scheduledStartTimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x12parentTraceContext\x18\x07 \x01(\x0b\x32\r.TraceContext\x12\x34\n\x0eworkflowSpanID\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x04tags\x18\t \x03(\x0b\x32 .ExecutionStartedEvent.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa2\x01\n\x17\x45xecutionCompletedEvent\x12,\n\x0eworkflowStatus\x18\x01 \x01(\x0e\x32\x14.OrchestrationStatus\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x03 \x01(\x0b\x32\x13.TaskFailureDetails\"X\n\x18\x45xecutionTerminatedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x0f\n\x07recurse\x18\x02 \x01(\x08\"\xfa\x02\n\x12TaskScheduledEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x04 \x01(\x0b\x32\r.TraceContext\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\t\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x12>\n\x17historyPropagationScope\x18\x07 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x01\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfoB\x1a\n\x18_historyPropagationScope\"\xf4\x01\n\x12TaskCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\x12\x38\n\x0b\x61ttestation\x18\x04 \x01(\x0b\x32\x1e.ActivityCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\"\xf0\x01\n\x0fTaskFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\x12\x38\n\x0b\x61ttestation\x18\x04 \x01(\x0b\x32\x1e.ActivityCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\"\x84\x03\n!ChildWorkflowInstanceCreatedEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x05 \x01(\x0b\x32\r.TraceContext\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x12>\n\x17historyPropagationScope\x18\x07 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x01\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfoB\x1a\n\x18_historyPropagationScope\"\xe9\x01\n#ChildWorkflowInstanceCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0b\x61ttestation\x18\x03 \x01(\x0b\x32\x1b.ChildCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x04 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\"\xe5\x01\n ChildWorkflowInstanceFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x35\n\x0b\x61ttestation\x18\x03 \x01(\x0b\x32\x1b.ChildCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x04 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\":\n$DetachedWorkflowInstanceCreatedEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\"\x18\n\x16TimerOriginCreateTimer\"(\n\x18TimerOriginExternalEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"3\n\x18TimerOriginActivityRetry\x12\x17\n\x0ftaskExecutionId\x18\x01 \x01(\t\"3\n\x1dTimerOriginChildWorkflowRetry\x12\x12\n\ninstanceId\x18\x01 \x01(\t\"\x97\x03\n\x11TimerCreatedEvent\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12>\n\x17rerunParentInstanceInfo\x18\x03 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x02\x88\x01\x01\x12.\n\x0b\x63reateTimer\x18\x04 \x01(\x0b\x32\x17.TimerOriginCreateTimerH\x00\x12\x32\n\rexternalEvent\x18\x05 \x01(\x0b\x32\x19.TimerOriginExternalEventH\x00\x12\x32\n\ractivityRetry\x18\x06 \x01(\x0b\x32\x19.TimerOriginActivityRetryH\x00\x12<\n\x12\x63hildWorkflowRetry\x18\x07 \x01(\x0b\x32\x1e.TimerOriginChildWorkflowRetryH\x00\x42\x08\n\x06originB\x07\n\x05_nameB\x1a\n\x18_rerunParentInstanceInfo\"N\n\x0fTimerFiredEvent\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07timerId\x18\x02 \x01(\x05\"J\n\x14WorkflowStartedEvent\x12&\n\x07version\x18\x01 \x01(\x0b\x32\x10.WorkflowVersionH\x00\x88\x01\x01\x42\n\n\x08_version\"\x18\n\x16WorkflowCompletedEvent\"_\n\x0e\x45ventSentEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"M\n\x10\x45ventRaisedEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x05input\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"A\n\x12\x43ontinueAsNewEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"F\n\x17\x45xecutionSuspendedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"D\n\x15\x45xecutionResumedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"a\n\x15\x45xecutionStalledEvent\x12\x1e\n\x06reason\x18\x01 \x01(\x0e\x32\x0e.StalledReason\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xfa\t\n\x0cHistoryEvent\x12\x0f\n\x07\x65ventId\x18\x01 \x01(\x05\x12-\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x10\x65xecutionStarted\x18\x03 \x01(\x0b\x32\x16.ExecutionStartedEventH\x00\x12\x36\n\x12\x65xecutionCompleted\x18\x04 \x01(\x0b\x32\x18.ExecutionCompletedEventH\x00\x12\x38\n\x13\x65xecutionTerminated\x18\x05 \x01(\x0b\x32\x19.ExecutionTerminatedEventH\x00\x12,\n\rtaskScheduled\x18\x06 \x01(\x0b\x32\x13.TaskScheduledEventH\x00\x12,\n\rtaskCompleted\x18\x07 \x01(\x0b\x32\x13.TaskCompletedEventH\x00\x12&\n\ntaskFailed\x18\x08 \x01(\x0b\x32\x10.TaskFailedEventH\x00\x12J\n\x1c\x63hildWorkflowInstanceCreated\x18\t \x01(\x0b\x32\".ChildWorkflowInstanceCreatedEventH\x00\x12N\n\x1e\x63hildWorkflowInstanceCompleted\x18\n \x01(\x0b\x32$.ChildWorkflowInstanceCompletedEventH\x00\x12H\n\x1b\x63hildWorkflowInstanceFailed\x18\x0b \x01(\x0b\x32!.ChildWorkflowInstanceFailedEventH\x00\x12*\n\x0ctimerCreated\x18\x0c \x01(\x0b\x32\x12.TimerCreatedEventH\x00\x12&\n\ntimerFired\x18\r \x01(\x0b\x32\x10.TimerFiredEventH\x00\x12\x30\n\x0fworkflowStarted\x18\x0e \x01(\x0b\x32\x15.WorkflowStartedEventH\x00\x12\x34\n\x11workflowCompleted\x18\x0f \x01(\x0b\x32\x17.WorkflowCompletedEventH\x00\x12$\n\teventSent\x18\x10 \x01(\x0b\x32\x0f.EventSentEventH\x00\x12(\n\x0b\x65ventRaised\x18\x11 \x01(\x0b\x32\x11.EventRaisedEventH\x00\x12,\n\rcontinueAsNew\x18\x14 \x01(\x0b\x32\x13.ContinueAsNewEventH\x00\x12\x36\n\x12\x65xecutionSuspended\x18\x15 \x01(\x0b\x32\x18.ExecutionSuspendedEventH\x00\x12\x32\n\x10\x65xecutionResumed\x18\x16 \x01(\x0b\x32\x16.ExecutionResumedEventH\x00\x12\x32\n\x10\x65xecutionStalled\x18\x1f \x01(\x0b\x32\x16.ExecutionStalledEventH\x00\x12P\n\x1f\x64\x65tachedWorkflowInstanceCreated\x18 \x01(\x0b\x32%.DetachedWorkflowInstanceCreatedEventH\x00\x12 \n\x06router\x18\x1e \x01(\x0b\x32\x0b.TaskRouterH\x01\x88\x01\x01\x42\x0b\n\teventTypeB\t\n\x07_routerJ\x04\x08\x12\x10\x13J\x04\x08\x13\x10\x14J\x04\x08\x17\x10\x18J\x04\x08\x18\x10\x19J\x04\x08\x19\x10\x1aJ\x04\x08\x1a\x10\x1bJ\x04\x08\x1b\x10\x1cJ\x04\x08\x1c\x10\x1dJ\x04\x08\x1d\x10\x1e\"\x96\x01\n\x16PropagatedHistoryChunk\x12\x11\n\trawEvents\x18\x01 \x03(\x0c\x12\r\n\x05\x61ppId\x18\x02 \x01(\t\x12\x12\n\ninstanceId\x18\x03 \x01(\t\x12\x14\n\x0cworkflowName\x18\x04 \x01(\t\x12\x15\n\rrawSignatures\x18\x05 \x03(\x0c\x12\x19\n\x11signingCertChains\x18\x06 \x03(\x0c\"e\n\x11PropagatedHistory\x12\'\n\x05scope\x18\x01 \x01(\x0e\x32\x18.HistoryPropagationScope\x12\'\n\x06\x63hunks\x18\x02 \x03(\x0b\x32\x17.PropagatedHistoryChunkBV\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14history_events.proto\x1a\x13orchestration.proto\x1a\x11\x61ttestation.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xd6\x03\n\x15\x45xecutionStartedEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12+\n\x0eparentInstance\x18\x05 \x01(\x0b\x32\x13.ParentInstanceInfo\x12;\n\x17scheduledStartTimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x12parentTraceContext\x18\x07 \x01(\x0b\x32\r.TraceContext\x12\x34\n\x0eworkflowSpanID\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x04tags\x18\t \x03(\x0b\x32 .ExecutionStartedEvent.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa2\x01\n\x17\x45xecutionCompletedEvent\x12,\n\x0eworkflowStatus\x18\x01 \x01(\x0e\x32\x14.OrchestrationStatus\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x03 \x01(\x0b\x32\x13.TaskFailureDetails\"X\n\x18\x45xecutionTerminatedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x0f\n\x07recurse\x18\x02 \x01(\x08\"\xfa\x02\n\x12TaskScheduledEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x04 \x01(\x0b\x32\r.TraceContext\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\t\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x12>\n\x17historyPropagationScope\x18\x07 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x01\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfoB\x1a\n\x18_historyPropagationScope\"\xf4\x01\n\x12TaskCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\x12\x38\n\x0b\x61ttestation\x18\x04 \x01(\x0b\x32\x1e.ActivityCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\"\xf0\x01\n\x0fTaskFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\x12\x38\n\x0b\x61ttestation\x18\x04 \x01(\x0b\x32\x1e.ActivityCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\"\xe0\x03\n!ChildWorkflowInstanceCreatedEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x05 \x01(\x0b\x32\r.TraceContext\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x12>\n\x17historyPropagationScope\x18\x07 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x01\x88\x01\x01\x12>\n\x17retryParentInstanceInfo\x18\x08 \x01(\x0b\x32\x18.RetryParentInstanceInfoH\x02\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfoB\x1a\n\x18_historyPropagationScopeB\x1a\n\x18_retryParentInstanceInfo\"\xe9\x01\n#ChildWorkflowInstanceCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x0b\x61ttestation\x18\x03 \x01(\x0b\x32\x1b.ChildCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x04 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\"\xe5\x01\n ChildWorkflowInstanceFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x35\n\x0b\x61ttestation\x18\x03 \x01(\x0b\x32\x1b.ChildCompletionAttestationH\x00\x88\x01\x01\x12\x1e\n\x11signerCertificate\x18\x04 \x01(\x0cH\x01\x88\x01\x01\x42\x0e\n\x0c_attestationB\x14\n\x12_signerCertificate\":\n$DetachedWorkflowInstanceCreatedEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\"\x18\n\x16TimerOriginCreateTimer\"(\n\x18TimerOriginExternalEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"3\n\x18TimerOriginActivityRetry\x12\x17\n\x0ftaskExecutionId\x18\x01 \x01(\t\"3\n\x1dTimerOriginChildWorkflowRetry\x12\x12\n\ninstanceId\x18\x01 \x01(\t\"\x97\x03\n\x11TimerCreatedEvent\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12>\n\x17rerunParentInstanceInfo\x18\x03 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x02\x88\x01\x01\x12.\n\x0b\x63reateTimer\x18\x04 \x01(\x0b\x32\x17.TimerOriginCreateTimerH\x00\x12\x32\n\rexternalEvent\x18\x05 \x01(\x0b\x32\x19.TimerOriginExternalEventH\x00\x12\x32\n\ractivityRetry\x18\x06 \x01(\x0b\x32\x19.TimerOriginActivityRetryH\x00\x12<\n\x12\x63hildWorkflowRetry\x18\x07 \x01(\x0b\x32\x1e.TimerOriginChildWorkflowRetryH\x00\x42\x08\n\x06originB\x07\n\x05_nameB\x1a\n\x18_rerunParentInstanceInfo\"N\n\x0fTimerFiredEvent\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07timerId\x18\x02 \x01(\x05\"J\n\x14WorkflowStartedEvent\x12&\n\x07version\x18\x01 \x01(\x0b\x32\x10.WorkflowVersionH\x00\x88\x01\x01\x42\n\n\x08_version\"\x18\n\x16WorkflowCompletedEvent\"_\n\x0e\x45ventSentEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"M\n\x10\x45ventRaisedEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x05input\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"A\n\x12\x43ontinueAsNewEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"F\n\x17\x45xecutionSuspendedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"D\n\x15\x45xecutionResumedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"a\n\x15\x45xecutionStalledEvent\x12\x1e\n\x06reason\x18\x01 \x01(\x0e\x32\x0e.StalledReason\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xfa\t\n\x0cHistoryEvent\x12\x0f\n\x07\x65ventId\x18\x01 \x01(\x05\x12-\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x10\x65xecutionStarted\x18\x03 \x01(\x0b\x32\x16.ExecutionStartedEventH\x00\x12\x36\n\x12\x65xecutionCompleted\x18\x04 \x01(\x0b\x32\x18.ExecutionCompletedEventH\x00\x12\x38\n\x13\x65xecutionTerminated\x18\x05 \x01(\x0b\x32\x19.ExecutionTerminatedEventH\x00\x12,\n\rtaskScheduled\x18\x06 \x01(\x0b\x32\x13.TaskScheduledEventH\x00\x12,\n\rtaskCompleted\x18\x07 \x01(\x0b\x32\x13.TaskCompletedEventH\x00\x12&\n\ntaskFailed\x18\x08 \x01(\x0b\x32\x10.TaskFailedEventH\x00\x12J\n\x1c\x63hildWorkflowInstanceCreated\x18\t \x01(\x0b\x32\".ChildWorkflowInstanceCreatedEventH\x00\x12N\n\x1e\x63hildWorkflowInstanceCompleted\x18\n \x01(\x0b\x32$.ChildWorkflowInstanceCompletedEventH\x00\x12H\n\x1b\x63hildWorkflowInstanceFailed\x18\x0b \x01(\x0b\x32!.ChildWorkflowInstanceFailedEventH\x00\x12*\n\x0ctimerCreated\x18\x0c \x01(\x0b\x32\x12.TimerCreatedEventH\x00\x12&\n\ntimerFired\x18\r \x01(\x0b\x32\x10.TimerFiredEventH\x00\x12\x30\n\x0fworkflowStarted\x18\x0e \x01(\x0b\x32\x15.WorkflowStartedEventH\x00\x12\x34\n\x11workflowCompleted\x18\x0f \x01(\x0b\x32\x17.WorkflowCompletedEventH\x00\x12$\n\teventSent\x18\x10 \x01(\x0b\x32\x0f.EventSentEventH\x00\x12(\n\x0b\x65ventRaised\x18\x11 \x01(\x0b\x32\x11.EventRaisedEventH\x00\x12,\n\rcontinueAsNew\x18\x14 \x01(\x0b\x32\x13.ContinueAsNewEventH\x00\x12\x36\n\x12\x65xecutionSuspended\x18\x15 \x01(\x0b\x32\x18.ExecutionSuspendedEventH\x00\x12\x32\n\x10\x65xecutionResumed\x18\x16 \x01(\x0b\x32\x16.ExecutionResumedEventH\x00\x12\x32\n\x10\x65xecutionStalled\x18\x1f \x01(\x0b\x32\x16.ExecutionStalledEventH\x00\x12P\n\x1f\x64\x65tachedWorkflowInstanceCreated\x18 \x01(\x0b\x32%.DetachedWorkflowInstanceCreatedEventH\x00\x12 \n\x06router\x18\x1e \x01(\x0b\x32\x0b.TaskRouterH\x01\x88\x01\x01\x42\x0b\n\teventTypeB\t\n\x07_routerJ\x04\x08\x12\x10\x13J\x04\x08\x13\x10\x14J\x04\x08\x17\x10\x18J\x04\x08\x18\x10\x19J\x04\x08\x19\x10\x1aJ\x04\x08\x1a\x10\x1bJ\x04\x08\x1b\x10\x1cJ\x04\x08\x1c\x10\x1dJ\x04\x08\x1d\x10\x1e\"\x96\x01\n\x16PropagatedHistoryChunk\x12\x11\n\trawEvents\x18\x01 \x03(\x0c\x12\r\n\x05\x61ppId\x18\x02 \x01(\t\x12\x12\n\ninstanceId\x18\x03 \x01(\t\x12\x14\n\x0cworkflowName\x18\x04 \x01(\t\x12\x15\n\rrawSignatures\x18\x05 \x03(\x0c\x12\x19\n\x11signingCertChains\x18\x06 \x03(\x0c\"e\n\x11PropagatedHistory\x12\'\n\x05scope\x18\x01 \x01(\x0e\x32\x18.HistoryPropagationScope\x12\'\n\x06\x63hunks\x18\x02 \x03(\x0b\x32\x17.PropagatedHistoryChunkBV\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -53,45 +53,45 @@ _globals['_TASKFAILEDEVENT']._serialized_start=1486 _globals['_TASKFAILEDEVENT']._serialized_end=1726 _globals['_CHILDWORKFLOWINSTANCECREATEDEVENT']._serialized_start=1729 - _globals['_CHILDWORKFLOWINSTANCECREATEDEVENT']._serialized_end=2117 - _globals['_CHILDWORKFLOWINSTANCECOMPLETEDEVENT']._serialized_start=2120 - _globals['_CHILDWORKFLOWINSTANCECOMPLETEDEVENT']._serialized_end=2353 - _globals['_CHILDWORKFLOWINSTANCEFAILEDEVENT']._serialized_start=2356 - _globals['_CHILDWORKFLOWINSTANCEFAILEDEVENT']._serialized_end=2585 - _globals['_DETACHEDWORKFLOWINSTANCECREATEDEVENT']._serialized_start=2587 - _globals['_DETACHEDWORKFLOWINSTANCECREATEDEVENT']._serialized_end=2645 - _globals['_TIMERORIGINCREATETIMER']._serialized_start=2647 - _globals['_TIMERORIGINCREATETIMER']._serialized_end=2671 - _globals['_TIMERORIGINEXTERNALEVENT']._serialized_start=2673 - _globals['_TIMERORIGINEXTERNALEVENT']._serialized_end=2713 - _globals['_TIMERORIGINACTIVITYRETRY']._serialized_start=2715 - _globals['_TIMERORIGINACTIVITYRETRY']._serialized_end=2766 - _globals['_TIMERORIGINCHILDWORKFLOWRETRY']._serialized_start=2768 - _globals['_TIMERORIGINCHILDWORKFLOWRETRY']._serialized_end=2819 - _globals['_TIMERCREATEDEVENT']._serialized_start=2822 - _globals['_TIMERCREATEDEVENT']._serialized_end=3229 - _globals['_TIMERFIREDEVENT']._serialized_start=3231 - _globals['_TIMERFIREDEVENT']._serialized_end=3309 - _globals['_WORKFLOWSTARTEDEVENT']._serialized_start=3311 - _globals['_WORKFLOWSTARTEDEVENT']._serialized_end=3385 - _globals['_WORKFLOWCOMPLETEDEVENT']._serialized_start=3387 - _globals['_WORKFLOWCOMPLETEDEVENT']._serialized_end=3411 - _globals['_EVENTSENTEVENT']._serialized_start=3413 - _globals['_EVENTSENTEVENT']._serialized_end=3508 - _globals['_EVENTRAISEDEVENT']._serialized_start=3510 - _globals['_EVENTRAISEDEVENT']._serialized_end=3587 - _globals['_CONTINUEASNEWEVENT']._serialized_start=3589 - _globals['_CONTINUEASNEWEVENT']._serialized_end=3654 - _globals['_EXECUTIONSUSPENDEDEVENT']._serialized_start=3656 - _globals['_EXECUTIONSUSPENDEDEVENT']._serialized_end=3726 - _globals['_EXECUTIONRESUMEDEVENT']._serialized_start=3728 - _globals['_EXECUTIONRESUMEDEVENT']._serialized_end=3796 - _globals['_EXECUTIONSTALLEDEVENT']._serialized_start=3798 - _globals['_EXECUTIONSTALLEDEVENT']._serialized_end=3895 - _globals['_HISTORYEVENT']._serialized_start=3898 - _globals['_HISTORYEVENT']._serialized_end=5172 - _globals['_PROPAGATEDHISTORYCHUNK']._serialized_start=5175 - _globals['_PROPAGATEDHISTORYCHUNK']._serialized_end=5325 - _globals['_PROPAGATEDHISTORY']._serialized_start=5327 - _globals['_PROPAGATEDHISTORY']._serialized_end=5428 + _globals['_CHILDWORKFLOWINSTANCECREATEDEVENT']._serialized_end=2209 + _globals['_CHILDWORKFLOWINSTANCECOMPLETEDEVENT']._serialized_start=2212 + _globals['_CHILDWORKFLOWINSTANCECOMPLETEDEVENT']._serialized_end=2445 + _globals['_CHILDWORKFLOWINSTANCEFAILEDEVENT']._serialized_start=2448 + _globals['_CHILDWORKFLOWINSTANCEFAILEDEVENT']._serialized_end=2677 + _globals['_DETACHEDWORKFLOWINSTANCECREATEDEVENT']._serialized_start=2679 + _globals['_DETACHEDWORKFLOWINSTANCECREATEDEVENT']._serialized_end=2737 + _globals['_TIMERORIGINCREATETIMER']._serialized_start=2739 + _globals['_TIMERORIGINCREATETIMER']._serialized_end=2763 + _globals['_TIMERORIGINEXTERNALEVENT']._serialized_start=2765 + _globals['_TIMERORIGINEXTERNALEVENT']._serialized_end=2805 + _globals['_TIMERORIGINACTIVITYRETRY']._serialized_start=2807 + _globals['_TIMERORIGINACTIVITYRETRY']._serialized_end=2858 + _globals['_TIMERORIGINCHILDWORKFLOWRETRY']._serialized_start=2860 + _globals['_TIMERORIGINCHILDWORKFLOWRETRY']._serialized_end=2911 + _globals['_TIMERCREATEDEVENT']._serialized_start=2914 + _globals['_TIMERCREATEDEVENT']._serialized_end=3321 + _globals['_TIMERFIREDEVENT']._serialized_start=3323 + _globals['_TIMERFIREDEVENT']._serialized_end=3401 + _globals['_WORKFLOWSTARTEDEVENT']._serialized_start=3403 + _globals['_WORKFLOWSTARTEDEVENT']._serialized_end=3477 + _globals['_WORKFLOWCOMPLETEDEVENT']._serialized_start=3479 + _globals['_WORKFLOWCOMPLETEDEVENT']._serialized_end=3503 + _globals['_EVENTSENTEVENT']._serialized_start=3505 + _globals['_EVENTSENTEVENT']._serialized_end=3600 + _globals['_EVENTRAISEDEVENT']._serialized_start=3602 + _globals['_EVENTRAISEDEVENT']._serialized_end=3679 + _globals['_CONTINUEASNEWEVENT']._serialized_start=3681 + _globals['_CONTINUEASNEWEVENT']._serialized_end=3746 + _globals['_EXECUTIONSUSPENDEDEVENT']._serialized_start=3748 + _globals['_EXECUTIONSUSPENDEDEVENT']._serialized_end=3818 + _globals['_EXECUTIONRESUMEDEVENT']._serialized_start=3820 + _globals['_EXECUTIONRESUMEDEVENT']._serialized_end=3888 + _globals['_EXECUTIONSTALLEDEVENT']._serialized_start=3890 + _globals['_EXECUTIONSTALLEDEVENT']._serialized_end=3987 + _globals['_HISTORYEVENT']._serialized_start=3990 + _globals['_HISTORYEVENT']._serialized_end=5264 + _globals['_PROPAGATEDHISTORYCHUNK']._serialized_start=5267 + _globals['_PROPAGATEDHISTORYCHUNK']._serialized_end=5417 + _globals['_PROPAGATEDHISTORY']._serialized_start=5419 + _globals['_PROPAGATEDHISTORY']._serialized_end=5520 # @@protoc_insertion_point(module_scope) diff --git a/dapr/ext/workflow/_durabletask/internal/history_events_pb2.pyi b/dapr/ext/workflow/_durabletask/internal/history_events_pb2.pyi index c2676d8a7..e4e066155 100644 --- a/dapr/ext/workflow/_durabletask/internal/history_events_pb2.pyi +++ b/dapr/ext/workflow/_durabletask/internal/history_events_pb2.pyi @@ -303,6 +303,7 @@ class ChildWorkflowInstanceCreatedEvent(_message.Message): PARENTTRACECONTEXT_FIELD_NUMBER: _builtins.int RERUNPARENTINSTANCEINFO_FIELD_NUMBER: _builtins.int HISTORYPROPAGATIONSCOPE_FIELD_NUMBER: _builtins.int + RETRYPARENTINSTANCEINFO_FIELD_NUMBER: _builtins.int instanceId: _builtins.str name: _builtins.str historyPropagationScope: _orchestration_pb2.HistoryPropagationScope.ValueType @@ -322,6 +323,15 @@ class ChildWorkflowInstanceCreatedEvent(_message.Message): workflow execution as the result of a rerun operation. """ + @_builtins.property + def retryParentInstanceInfo(self) -> _orchestration_pb2.RetryParentInstanceInfo: + """If defined, indicates that this child workflow is a retry attempt and + links it back to the first attempt in the retry chain. Absent on the + first attempt. Consumers correlate retry attempts by grouping on + retryParentInstanceInfo.instanceID when present, otherwise on this + event's own instanceId. + """ + def __init__( self, *, @@ -332,19 +342,24 @@ class ChildWorkflowInstanceCreatedEvent(_message.Message): parentTraceContext: _orchestration_pb2.TraceContext | None = ..., rerunParentInstanceInfo: _orchestration_pb2.RerunParentInstanceInfo | None = ..., historyPropagationScope: _orchestration_pb2.HistoryPropagationScope.ValueType | None = ..., + retryParentInstanceInfo: _orchestration_pb2.RetryParentInstanceInfo | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "parentTraceContext", b"parentTraceContext", "rerunParentInstanceInfo", b"rerunParentInstanceInfo", "version", b"version"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "_retryParentInstanceInfo", b"_retryParentInstanceInfo", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "parentTraceContext", b"parentTraceContext", "rerunParentInstanceInfo", b"rerunParentInstanceInfo", "retryParentInstanceInfo", b"retryParentInstanceInfo", "version", b"version"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "instanceId", b"instanceId", "name", b"name", "parentTraceContext", b"parentTraceContext", "rerunParentInstanceInfo", b"rerunParentInstanceInfo", "version", b"version"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "_retryParentInstanceInfo", b"_retryParentInstanceInfo", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "instanceId", b"instanceId", "name", b"name", "parentTraceContext", b"parentTraceContext", "rerunParentInstanceInfo", b"rerunParentInstanceInfo", "retryParentInstanceInfo", b"retryParentInstanceInfo", "version", b"version"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... _WhichOneofReturnType__historyPropagationScope: _TypeAlias = _typing.Literal["historyPropagationScope"] # noqa: Y015 _WhichOneofArgType__historyPropagationScope: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope"] # noqa: Y015 _WhichOneofReturnType__rerunParentInstanceInfo: _TypeAlias = _typing.Literal["rerunParentInstanceInfo"] # noqa: Y015 _WhichOneofArgType__rerunParentInstanceInfo: _TypeAlias = _typing.Literal["_rerunParentInstanceInfo", b"_rerunParentInstanceInfo"] # noqa: Y015 + _WhichOneofReturnType__retryParentInstanceInfo: _TypeAlias = _typing.Literal["retryParentInstanceInfo"] # noqa: Y015 + _WhichOneofArgType__retryParentInstanceInfo: _TypeAlias = _typing.Literal["_retryParentInstanceInfo", b"_retryParentInstanceInfo"] # noqa: Y015 @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__historyPropagationScope) -> _WhichOneofReturnType__historyPropagationScope | None: ... @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__rerunParentInstanceInfo) -> _WhichOneofReturnType__rerunParentInstanceInfo | None: ... + @_typing.overload + def WhichOneof(self, oneof_group: _WhichOneofArgType__retryParentInstanceInfo) -> _WhichOneofReturnType__retryParentInstanceInfo | None: ... Global___ChildWorkflowInstanceCreatedEvent: _TypeAlias = ChildWorkflowInstanceCreatedEvent # noqa: Y015 diff --git a/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.py b/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.py index c5719c1a7..45f573eb9 100644 --- a/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.py +++ b/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.py @@ -26,7 +26,7 @@ from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13orchestration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\x83\x01\n\nTaskRouter\x12\x13\n\x0bsourceAppID\x18\x01 \x01(\t\x12\x18\n\x0btargetAppID\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x1f\n\x12targetAppNamespace\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x0e\n\x0c_targetAppIDB\x15\n\x13_targetAppNamespace\">\n\x0fWorkflowVersion\x12\x0f\n\x07patches\x18\x01 \x03(\t\x12\x11\n\x04name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x07\n\x05_name\"Y\n\x10WorkflowInstance\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x31\n\x0b\x65xecutionId\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\xb2\x01\n\x12TaskFailureDetails\x12\x11\n\terrorType\x18\x01 \x01(\t\x12\x14\n\x0c\x65rrorMessage\x18\x02 \x01(\t\x12\x30\n\nstackTrace\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x0cinnerFailure\x18\x04 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x16\n\x0eisNonRetriable\x18\x05 \x01(\x08\"\xff\x01\n\x12ParentInstanceInfo\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12*\n\x04name\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12\x12\n\x05\x61ppID\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0c\x61ppNamespace\x18\x06 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_appIDB\x0f\n\r_appNamespace\"-\n\x17RerunParentInstanceInfo\x12\x12\n\ninstanceID\x18\x01 \x01(\t\"i\n\x0cTraceContext\x12\x13\n\x0btraceParent\x18\x01 \x01(\t\x12\x12\n\x06spanID\x18\x02 \x01(\tB\x02\x18\x01\x12\x30\n\ntraceState\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\xef\x05\n\rWorkflowState\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x0eworkflowStatus\x18\x04 \x01(\x0e\x32\x14.OrchestrationStatus\x12;\n\x17scheduledStartTimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x34\n\x10\x63reatedTimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x38\n\x14lastUpdatedTimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x05input\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x06output\x18\t \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0c\x63ustomStatus\x18\n \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x0b \x01(\x0b\x32\x13.TaskFailureDetails\x12\x31\n\x0b\x65xecutionId\x18\x0c \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x12\x63ompletedTimestamp\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x10parentInstanceId\x18\x0e \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12&\n\x04tags\x18\x0f \x03(\x0b\x32\x18.WorkflowState.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01*Y\n\rStalledReason\x12\x12\n\x0ePATCH_MISMATCH\x10\x00\x12\x19\n\x15VERSION_NOT_AVAILABLE\x10\x01\x12\x19\n\x15PAYLOAD_SIZE_EXCEEDED\x10\x02*\xd7\x02\n\x13OrchestrationStatus\x12 \n\x1cORCHESTRATION_STATUS_RUNNING\x10\x00\x12\"\n\x1eORCHESTRATION_STATUS_COMPLETED\x10\x01\x12)\n%ORCHESTRATION_STATUS_CONTINUED_AS_NEW\x10\x02\x12\x1f\n\x1bORCHESTRATION_STATUS_FAILED\x10\x03\x12!\n\x1dORCHESTRATION_STATUS_CANCELED\x10\x04\x12#\n\x1fORCHESTRATION_STATUS_TERMINATED\x10\x05\x12 \n\x1cORCHESTRATION_STATUS_PENDING\x10\x06\x12\"\n\x1eORCHESTRATION_STATUS_SUSPENDED\x10\x07\x12 \n\x1cORCHESTRATION_STATUS_STALLED\x10\x08*\x8f\x01\n\x17HistoryPropagationScope\x12\"\n\x1eHISTORY_PROPAGATION_SCOPE_NONE\x10\x00\x12)\n%HISTORY_PROPAGATION_SCOPE_OWN_HISTORY\x10\x01\x12%\n!HISTORY_PROPAGATION_SCOPE_LINEAGE\x10\x02\x42V\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13orchestration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\x83\x01\n\nTaskRouter\x12\x13\n\x0bsourceAppID\x18\x01 \x01(\t\x12\x18\n\x0btargetAppID\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x1f\n\x12targetAppNamespace\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x0e\n\x0c_targetAppIDB\x15\n\x13_targetAppNamespace\">\n\x0fWorkflowVersion\x12\x0f\n\x07patches\x18\x01 \x03(\t\x12\x11\n\x04name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x07\n\x05_name\"Y\n\x10WorkflowInstance\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x31\n\x0b\x65xecutionId\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\xb2\x01\n\x12TaskFailureDetails\x12\x11\n\terrorType\x18\x01 \x01(\t\x12\x14\n\x0c\x65rrorMessage\x18\x02 \x01(\t\x12\x30\n\nstackTrace\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x0cinnerFailure\x18\x04 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x16\n\x0eisNonRetriable\x18\x05 \x01(\x08\"\xff\x01\n\x12ParentInstanceInfo\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12*\n\x04name\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12\x12\n\x05\x61ppID\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0c\x61ppNamespace\x18\x06 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_appIDB\x0f\n\r_appNamespace\"-\n\x17RerunParentInstanceInfo\x12\x12\n\ninstanceID\x18\x01 \x01(\t\"-\n\x17RetryParentInstanceInfo\x12\x12\n\ninstanceID\x18\x01 \x01(\t\"i\n\x0cTraceContext\x12\x13\n\x0btraceParent\x18\x01 \x01(\t\x12\x12\n\x06spanID\x18\x02 \x01(\tB\x02\x18\x01\x12\x30\n\ntraceState\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\xe4\x06\n\rWorkflowState\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x0eworkflowStatus\x18\x04 \x01(\x0e\x32\x14.OrchestrationStatus\x12;\n\x17scheduledStartTimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x34\n\x10\x63reatedTimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x38\n\x14lastUpdatedTimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x05input\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12,\n\x06output\x18\t \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\x0c\x63ustomStatus\x18\n \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x0b \x01(\x0b\x32\x13.TaskFailureDetails\x12\x31\n\x0b\x65xecutionId\x18\x0c \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x36\n\x12\x63ompletedTimestamp\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x36\n\x10parentInstanceId\x18\x0e \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12&\n\x04tags\x18\x0f \x03(\x0b\x32\x18.WorkflowState.TagsEntry\x12\x31\n\x0bparentAppId\x18\x10 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x32\n\tstartedAt\x18\x11 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0c\n\n_startedAt*Y\n\rStalledReason\x12\x12\n\x0ePATCH_MISMATCH\x10\x00\x12\x19\n\x15VERSION_NOT_AVAILABLE\x10\x01\x12\x19\n\x15PAYLOAD_SIZE_EXCEEDED\x10\x02*\xd7\x02\n\x13OrchestrationStatus\x12 \n\x1cORCHESTRATION_STATUS_RUNNING\x10\x00\x12\"\n\x1eORCHESTRATION_STATUS_COMPLETED\x10\x01\x12)\n%ORCHESTRATION_STATUS_CONTINUED_AS_NEW\x10\x02\x12\x1f\n\x1bORCHESTRATION_STATUS_FAILED\x10\x03\x12!\n\x1dORCHESTRATION_STATUS_CANCELED\x10\x04\x12#\n\x1fORCHESTRATION_STATUS_TERMINATED\x10\x05\x12 \n\x1cORCHESTRATION_STATUS_PENDING\x10\x06\x12\"\n\x1eORCHESTRATION_STATUS_SUSPENDED\x10\x07\x12 \n\x1cORCHESTRATION_STATUS_STALLED\x10\x08*\x8f\x01\n\x17HistoryPropagationScope\x12\"\n\x1eHISTORY_PROPAGATION_SCOPE_NONE\x10\x00\x12)\n%HISTORY_PROPAGATION_SCOPE_OWN_HISTORY\x10\x01\x12%\n!HISTORY_PROPAGATION_SCOPE_LINEAGE\x10\x02\x42V\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -38,12 +38,12 @@ _globals['_TRACECONTEXT'].fields_by_name['spanID']._serialized_options = b'\030\001' _globals['_WORKFLOWSTATE_TAGSENTRY']._loaded_options = None _globals['_WORKFLOWSTATE_TAGSENTRY']._serialized_options = b'8\001' - _globals['_STALLEDREASON']._serialized_start=1724 - _globals['_STALLEDREASON']._serialized_end=1813 - _globals['_ORCHESTRATIONSTATUS']._serialized_start=1816 - _globals['_ORCHESTRATIONSTATUS']._serialized_end=2159 - _globals['_HISTORYPROPAGATIONSCOPE']._serialized_start=2162 - _globals['_HISTORYPROPAGATIONSCOPE']._serialized_end=2305 + _globals['_STALLEDREASON']._serialized_start=1888 + _globals['_STALLEDREASON']._serialized_end=1977 + _globals['_ORCHESTRATIONSTATUS']._serialized_start=1980 + _globals['_ORCHESTRATIONSTATUS']._serialized_end=2323 + _globals['_HISTORYPROPAGATIONSCOPE']._serialized_start=2326 + _globals['_HISTORYPROPAGATIONSCOPE']._serialized_end=2469 _globals['_TASKROUTER']._serialized_start=89 _globals['_TASKROUTER']._serialized_end=220 _globals['_WORKFLOWVERSION']._serialized_start=222 @@ -56,10 +56,12 @@ _globals['_PARENTINSTANCEINFO']._serialized_end=814 _globals['_RERUNPARENTINSTANCEINFO']._serialized_start=816 _globals['_RERUNPARENTINSTANCEINFO']._serialized_end=861 - _globals['_TRACECONTEXT']._serialized_start=863 - _globals['_TRACECONTEXT']._serialized_end=968 - _globals['_WORKFLOWSTATE']._serialized_start=971 - _globals['_WORKFLOWSTATE']._serialized_end=1722 - _globals['_WORKFLOWSTATE_TAGSENTRY']._serialized_start=1679 - _globals['_WORKFLOWSTATE_TAGSENTRY']._serialized_end=1722 + _globals['_RETRYPARENTINSTANCEINFO']._serialized_start=863 + _globals['_RETRYPARENTINSTANCEINFO']._serialized_end=908 + _globals['_TRACECONTEXT']._serialized_start=910 + _globals['_TRACECONTEXT']._serialized_end=1015 + _globals['_WORKFLOWSTATE']._serialized_start=1018 + _globals['_WORKFLOWSTATE']._serialized_end=1886 + _globals['_WORKFLOWSTATE_TAGSENTRY']._serialized_start=1829 + _globals['_WORKFLOWSTATE_TAGSENTRY']._serialized_end=1872 # @@protoc_insertion_point(module_scope) diff --git a/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.pyi b/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.pyi index 10b22698f..8e2cbb88c 100644 --- a/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.pyi +++ b/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.pyi @@ -294,6 +294,39 @@ class RerunParentInstanceInfo(_message.Message): Global___RerunParentInstanceInfo: _TypeAlias = RerunParentInstanceInfo # noqa: Y015 +@_typing.final +class RetryParentInstanceInfo(_message.Message): + """RetryParentInstanceInfo correlates a child-workflow retry attempt with the + initial attempt that spawned it. When a child workflow is scheduled with a + retry policy, each retry executes as a separate child workflow instance with + its own auto-generated instance ID. This message provides an explicit, + first-class link back to the first attempt so consumers no longer need to + reconstruct the relationship from event ordering and timer origins. + + Semantics: the first attempt carries no RetryParentInstanceInfo. Retry + attempts (2nd onward) carry RetryParentInstanceInfo with instanceID set to + the first attempt's instance ID. Consumers group attempts by reading the + parent workflow's history; the group key is retryParentInstanceInfo.instanceID + when present, otherwise the event's own instanceId. + """ + + DESCRIPTOR: _descriptor.Descriptor + + INSTANCEID_FIELD_NUMBER: _builtins.int + instanceID: _builtins.str + """instanceID is the instance ID of the first attempt in this child-workflow + retry chain. + """ + def __init__( + self, + *, + instanceID: _builtins.str = ..., + ) -> None: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["instanceID", b"instanceID"] # noqa: Y015 + def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + +Global___RetryParentInstanceInfo: _TypeAlias = RetryParentInstanceInfo # noqa: Y015 + @_typing.final class TraceContext(_message.Message): DESCRIPTOR: _descriptor.Descriptor @@ -360,6 +393,8 @@ class WorkflowState(_message.Message): COMPLETEDTIMESTAMP_FIELD_NUMBER: _builtins.int PARENTINSTANCEID_FIELD_NUMBER: _builtins.int TAGS_FIELD_NUMBER: _builtins.int + PARENTAPPID_FIELD_NUMBER: _builtins.int + STARTEDAT_FIELD_NUMBER: _builtins.int instanceId: _builtins.str name: _builtins.str workflowStatus: Global___OrchestrationStatus.ValueType @@ -387,6 +422,10 @@ class WorkflowState(_message.Message): def parentInstanceId(self) -> _wrappers_pb2.StringValue: ... @_builtins.property def tags(self) -> _containers.ScalarMap[_builtins.str, _builtins.str]: ... + @_builtins.property + def parentAppId(self) -> _wrappers_pb2.StringValue: ... + @_builtins.property + def startedAt(self) -> _timestamp_pb2.Timestamp: ... def __init__( self, *, @@ -405,10 +444,15 @@ class WorkflowState(_message.Message): completedTimestamp: _timestamp_pb2.Timestamp | None = ..., parentInstanceId: _wrappers_pb2.StringValue | None = ..., tags: _abc.Mapping[_builtins.str, _builtins.str] | None = ..., + parentAppId: _wrappers_pb2.StringValue | None = ..., + startedAt: _timestamp_pb2.Timestamp | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["completedTimestamp", b"completedTimestamp", "createdTimestamp", b"createdTimestamp", "customStatus", b"customStatus", "executionId", b"executionId", "failureDetails", b"failureDetails", "input", b"input", "lastUpdatedTimestamp", b"lastUpdatedTimestamp", "output", b"output", "parentInstanceId", b"parentInstanceId", "scheduledStartTimestamp", b"scheduledStartTimestamp", "version", b"version"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_startedAt", b"_startedAt", "completedTimestamp", b"completedTimestamp", "createdTimestamp", b"createdTimestamp", "customStatus", b"customStatus", "executionId", b"executionId", "failureDetails", b"failureDetails", "input", b"input", "lastUpdatedTimestamp", b"lastUpdatedTimestamp", "output", b"output", "parentAppId", b"parentAppId", "parentInstanceId", b"parentInstanceId", "scheduledStartTimestamp", b"scheduledStartTimestamp", "startedAt", b"startedAt", "version", b"version"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["completedTimestamp", b"completedTimestamp", "createdTimestamp", b"createdTimestamp", "customStatus", b"customStatus", "executionId", b"executionId", "failureDetails", b"failureDetails", "input", b"input", "instanceId", b"instanceId", "lastUpdatedTimestamp", b"lastUpdatedTimestamp", "name", b"name", "output", b"output", "parentInstanceId", b"parentInstanceId", "scheduledStartTimestamp", b"scheduledStartTimestamp", "tags", b"tags", "version", b"version", "workflowStatus", b"workflowStatus"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_startedAt", b"_startedAt", "completedTimestamp", b"completedTimestamp", "createdTimestamp", b"createdTimestamp", "customStatus", b"customStatus", "executionId", b"executionId", "failureDetails", b"failureDetails", "input", b"input", "instanceId", b"instanceId", "lastUpdatedTimestamp", b"lastUpdatedTimestamp", "name", b"name", "output", b"output", "parentAppId", b"parentAppId", "parentInstanceId", b"parentInstanceId", "scheduledStartTimestamp", b"scheduledStartTimestamp", "startedAt", b"startedAt", "tags", b"tags", "version", b"version", "workflowStatus", b"workflowStatus"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType__startedAt: _TypeAlias = _typing.Literal["startedAt"] # noqa: Y015 + _WhichOneofArgType__startedAt: _TypeAlias = _typing.Literal["_startedAt", b"_startedAt"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType__startedAt) -> _WhichOneofReturnType__startedAt | None: ... Global___WorkflowState: _TypeAlias = WorkflowState # noqa: Y015 diff --git a/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.py b/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.py index 9af283e56..503b5773e 100644 --- a/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.py +++ b/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.py @@ -28,7 +28,7 @@ from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aorchestrator_actions.proto\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xa0\x02\n\x12ScheduleTaskAction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x04 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\t\x12>\n\x17historyPropagationScope\x18\x06 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x01\x88\x01\x01\x42\t\n\x07_routerB\x1a\n\x18_historyPropagationScope\"\xa2\x02\n\x19\x43reateChildWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x05 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x12>\n\x17historyPropagationScope\x18\x06 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x01\x88\x01\x01\x42\t\n\x07_routerB\x1a\n\x18_historyPropagationScope\"\x85\x04\n\x1c\x43reateDetachedWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12@\n\x17scheduledStartTimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12\x31\n\x0b\x65xecutionId\x18\x06 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x04tags\x18\x07 \x03(\x0b\x32\'.CreateDetachedWorkflowAction.TagsEntry\x12.\n\x12parentTraceContext\x18\x08 \x01(\x0b\x32\r.TraceContextH\x01\x88\x01\x01\x12 \n\x06router\x18\t \x01(\x0b\x32\x0b.TaskRouterH\x02\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x1a\n\x18_scheduledStartTimestampB\x15\n\x13_parentTraceContextB\t\n\x07_router\"\xbb\x02\n\x11\x43reateTimerAction\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12.\n\x0b\x63reateTimer\x18\x03 \x01(\x0b\x32\x17.TimerOriginCreateTimerH\x00\x12\x32\n\rexternalEvent\x18\x04 \x01(\x0b\x32\x19.TimerOriginExternalEventH\x00\x12\x32\n\ractivityRetry\x18\x05 \x01(\x0b\x32\x19.TimerOriginActivityRetryH\x00\x12<\n\x12\x63hildWorkflowRetry\x18\x06 \x01(\x0b\x32\x1e.TimerOriginChildWorkflowRetryH\x00\x42\x08\n\x06originB\x07\n\x05_name\"p\n\x0fSendEventAction\x12#\n\x08instance\x18\x01 \x01(\x0b\x32\x11.WorkflowInstance\x12\x0c\n\x04name\x18\x02 \x01(\t\x12*\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\xaa\x02\n\x16\x43ompleteWorkflowAction\x12,\n\x0eworkflowStatus\x18\x01 \x01(\x0e\x32\x14.OrchestrationStatus\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07\x64\x65tails\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\nnewVersion\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12&\n\x0f\x63\x61rryoverEvents\x18\x05 \x03(\x0b\x32\r.HistoryEvent\x12+\n\x0e\x66\x61ilureDetails\x18\x06 \x01(\x0b\x32\x13.TaskFailureDetails\"l\n\x17TerminateWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06reason\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x0f\n\x07recurse\x18\x03 \x01(\x08\"#\n!WorkflowVersionNotAvailableAction\"\x97\x04\n\x0eWorkflowAction\x12\n\n\x02id\x18\x01 \x01(\x05\x12+\n\x0cscheduleTask\x18\x02 \x01(\x0b\x32\x13.ScheduleTaskActionH\x00\x12\x39\n\x13\x63reateChildWorkflow\x18\x03 \x01(\x0b\x32\x1a.CreateChildWorkflowActionH\x00\x12)\n\x0b\x63reateTimer\x18\x04 \x01(\x0b\x32\x12.CreateTimerActionH\x00\x12%\n\tsendEvent\x18\x05 \x01(\x0b\x32\x10.SendEventActionH\x00\x12\x33\n\x10\x63ompleteWorkflow\x18\x06 \x01(\x0b\x32\x17.CompleteWorkflowActionH\x00\x12\x35\n\x11terminateWorkflow\x18\x07 \x01(\x0b\x32\x18.TerminateWorkflowActionH\x00\x12I\n\x1bworkflowVersionNotAvailable\x18\n \x01(\x0b\x32\".WorkflowVersionNotAvailableActionH\x00\x12?\n\x16\x63reateDetachedWorkflow\x18\x0b \x01(\x0b\x32\x1d.CreateDetachedWorkflowActionH\x00\x12 \n\x06router\x18\t \x01(\x0b\x32\x0b.TaskRouterH\x01\x88\x01\x01\x42\x14\n\x12workflowActionTypeB\t\n\x07_routerJ\x04\x08\x08\x10\tBV\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aorchestrator_actions.proto\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xf9\x01\n\x12ScheduleTaskAction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\t\x12>\n\x17historyPropagationScope\x18\x06 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x00\x88\x01\x01\x42\x1a\n\x18_historyPropagationScopeJ\x04\x08\x04\x10\x05\"\xd7\x02\n\x19\x43reateChildWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12>\n\x17historyPropagationScope\x18\x06 \x01(\x0e\x32\x18.HistoryPropagationScopeH\x00\x88\x01\x01\x12>\n\x17retryParentInstanceInfo\x18\x07 \x01(\x0b\x32\x18.RetryParentInstanceInfoH\x01\x88\x01\x01\x42\x1a\n\x18_historyPropagationScopeB\x1a\n\x18_retryParentInstanceInfoJ\x04\x08\x05\x10\x06\"\xde\x03\n\x1c\x43reateDetachedWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12@\n\x17scheduledStartTimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x12\x31\n\x0b\x65xecutionId\x18\x06 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x35\n\x04tags\x18\x07 \x03(\x0b\x32\'.CreateDetachedWorkflowAction.TagsEntry\x12.\n\x12parentTraceContext\x18\x08 \x01(\x0b\x32\r.TraceContextH\x01\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x1a\n\x18_scheduledStartTimestampB\x15\n\x13_parentTraceContextJ\x04\x08\t\x10\n\"\xbb\x02\n\x11\x43reateTimerAction\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12.\n\x0b\x63reateTimer\x18\x03 \x01(\x0b\x32\x17.TimerOriginCreateTimerH\x00\x12\x32\n\rexternalEvent\x18\x04 \x01(\x0b\x32\x19.TimerOriginExternalEventH\x00\x12\x32\n\ractivityRetry\x18\x05 \x01(\x0b\x32\x19.TimerOriginActivityRetryH\x00\x12<\n\x12\x63hildWorkflowRetry\x18\x06 \x01(\x0b\x32\x1e.TimerOriginChildWorkflowRetryH\x00\x42\x08\n\x06originB\x07\n\x05_name\"p\n\x0fSendEventAction\x12#\n\x08instance\x18\x01 \x01(\x0b\x32\x11.WorkflowInstance\x12\x0c\n\x04name\x18\x02 \x01(\t\x12*\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\xaa\x02\n\x16\x43ompleteWorkflowAction\x12,\n\x0eworkflowStatus\x18\x01 \x01(\x0e\x32\x14.OrchestrationStatus\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07\x64\x65tails\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\nnewVersion\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12&\n\x0f\x63\x61rryoverEvents\x18\x05 \x03(\x0b\x32\r.HistoryEvent\x12+\n\x0e\x66\x61ilureDetails\x18\x06 \x01(\x0b\x32\x13.TaskFailureDetails\"l\n\x17TerminateWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06reason\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x0f\n\x07recurse\x18\x03 \x01(\x08\"#\n!WorkflowVersionNotAvailableAction\"\x97\x04\n\x0eWorkflowAction\x12\n\n\x02id\x18\x01 \x01(\x05\x12+\n\x0cscheduleTask\x18\x02 \x01(\x0b\x32\x13.ScheduleTaskActionH\x00\x12\x39\n\x13\x63reateChildWorkflow\x18\x03 \x01(\x0b\x32\x1a.CreateChildWorkflowActionH\x00\x12)\n\x0b\x63reateTimer\x18\x04 \x01(\x0b\x32\x12.CreateTimerActionH\x00\x12%\n\tsendEvent\x18\x05 \x01(\x0b\x32\x10.SendEventActionH\x00\x12\x33\n\x10\x63ompleteWorkflow\x18\x06 \x01(\x0b\x32\x17.CompleteWorkflowActionH\x00\x12\x35\n\x11terminateWorkflow\x18\x07 \x01(\x0b\x32\x18.TerminateWorkflowActionH\x00\x12I\n\x1bworkflowVersionNotAvailable\x18\n \x01(\x0b\x32\".WorkflowVersionNotAvailableActionH\x00\x12?\n\x16\x63reateDetachedWorkflow\x18\x0b \x01(\x0b\x32\x1d.CreateDetachedWorkflowActionH\x00\x12 \n\x06router\x18\t \x01(\x0b\x32\x0b.TaskRouterH\x01\x88\x01\x01\x42\x14\n\x12workflowActionTypeB\t\n\x07_routerJ\x04\x08\x08\x10\tBV\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -39,23 +39,23 @@ _globals['_CREATEDETACHEDWORKFLOWACTION_TAGSENTRY']._loaded_options = None _globals['_CREATEDETACHEDWORKFLOWACTION_TAGSENTRY']._serialized_options = b'8\001' _globals['_SCHEDULETASKACTION']._serialized_start=139 - _globals['_SCHEDULETASKACTION']._serialized_end=427 - _globals['_CREATECHILDWORKFLOWACTION']._serialized_start=430 - _globals['_CREATECHILDWORKFLOWACTION']._serialized_end=720 - _globals['_CREATEDETACHEDWORKFLOWACTION']._serialized_start=723 - _globals['_CREATEDETACHEDWORKFLOWACTION']._serialized_end=1240 - _globals['_CREATEDETACHEDWORKFLOWACTION_TAGSENTRY']._serialized_start=1135 - _globals['_CREATEDETACHEDWORKFLOWACTION_TAGSENTRY']._serialized_end=1178 - _globals['_CREATETIMERACTION']._serialized_start=1243 - _globals['_CREATETIMERACTION']._serialized_end=1558 - _globals['_SENDEVENTACTION']._serialized_start=1560 - _globals['_SENDEVENTACTION']._serialized_end=1672 - _globals['_COMPLETEWORKFLOWACTION']._serialized_start=1675 - _globals['_COMPLETEWORKFLOWACTION']._serialized_end=1973 - _globals['_TERMINATEWORKFLOWACTION']._serialized_start=1975 - _globals['_TERMINATEWORKFLOWACTION']._serialized_end=2083 - _globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_start=2085 - _globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_end=2120 - _globals['_WORKFLOWACTION']._serialized_start=2123 - _globals['_WORKFLOWACTION']._serialized_end=2658 + _globals['_SCHEDULETASKACTION']._serialized_end=388 + _globals['_CREATECHILDWORKFLOWACTION']._serialized_start=391 + _globals['_CREATECHILDWORKFLOWACTION']._serialized_end=734 + _globals['_CREATEDETACHEDWORKFLOWACTION']._serialized_start=737 + _globals['_CREATEDETACHEDWORKFLOWACTION']._serialized_end=1215 + _globals['_CREATEDETACHEDWORKFLOWACTION_TAGSENTRY']._serialized_start=1115 + _globals['_CREATEDETACHEDWORKFLOWACTION_TAGSENTRY']._serialized_end=1158 + _globals['_CREATETIMERACTION']._serialized_start=1218 + _globals['_CREATETIMERACTION']._serialized_end=1533 + _globals['_SENDEVENTACTION']._serialized_start=1535 + _globals['_SENDEVENTACTION']._serialized_end=1647 + _globals['_COMPLETEWORKFLOWACTION']._serialized_start=1650 + _globals['_COMPLETEWORKFLOWACTION']._serialized_end=1948 + _globals['_TERMINATEWORKFLOWACTION']._serialized_start=1950 + _globals['_TERMINATEWORKFLOWACTION']._serialized_end=2058 + _globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_start=2060 + _globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_end=2095 + _globals['_WORKFLOWACTION']._serialized_start=2098 + _globals['_WORKFLOWACTION']._serialized_end=2633 # @@protoc_insertion_point(module_scope) diff --git a/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.pyi b/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.pyi index 1934c960f..9e4e3deb0 100644 --- a/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.pyi +++ b/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.pyi @@ -31,7 +31,6 @@ class ScheduleTaskAction(_message.Message): NAME_FIELD_NUMBER: _builtins.int VERSION_FIELD_NUMBER: _builtins.int INPUT_FIELD_NUMBER: _builtins.int - ROUTER_FIELD_NUMBER: _builtins.int TASKEXECUTIONID_FIELD_NUMBER: _builtins.int HISTORYPROPAGATIONSCOPE_FIELD_NUMBER: _builtins.int name: _builtins.str @@ -42,30 +41,22 @@ class ScheduleTaskAction(_message.Message): def version(self) -> _wrappers_pb2.StringValue: ... @_builtins.property def input(self) -> _wrappers_pb2.StringValue: ... - @_builtins.property - def router(self) -> _orchestration_pb2.TaskRouter: ... def __init__( self, *, name: _builtins.str = ..., version: _wrappers_pb2.StringValue | None = ..., input: _wrappers_pb2.StringValue | None = ..., - router: _orchestration_pb2.TaskRouter | None = ..., taskExecutionId: _builtins.str = ..., historyPropagationScope: _orchestration_pb2.HistoryPropagationScope.ValueType | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_router", b"_router", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "router", b"router", "version", b"version"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "version", b"version"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_router", b"_router", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "name", b"name", "router", b"router", "taskExecutionId", b"taskExecutionId", "version", b"version"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "name", b"name", "taskExecutionId", b"taskExecutionId", "version", b"version"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... _WhichOneofReturnType__historyPropagationScope: _TypeAlias = _typing.Literal["historyPropagationScope"] # noqa: Y015 _WhichOneofArgType__historyPropagationScope: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope"] # noqa: Y015 - _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 - _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 - @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__historyPropagationScope) -> _WhichOneofReturnType__historyPropagationScope | None: ... - @_typing.overload - def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___ScheduleTaskAction: _TypeAlias = ScheduleTaskAction # noqa: Y015 @@ -77,8 +68,8 @@ class CreateChildWorkflowAction(_message.Message): NAME_FIELD_NUMBER: _builtins.int VERSION_FIELD_NUMBER: _builtins.int INPUT_FIELD_NUMBER: _builtins.int - ROUTER_FIELD_NUMBER: _builtins.int HISTORYPROPAGATIONSCOPE_FIELD_NUMBER: _builtins.int + RETRYPARENTINSTANCEINFO_FIELD_NUMBER: _builtins.int instanceId: _builtins.str name: _builtins.str historyPropagationScope: _orchestration_pb2.HistoryPropagationScope.ValueType @@ -88,7 +79,15 @@ class CreateChildWorkflowAction(_message.Message): @_builtins.property def input(self) -> _wrappers_pb2.StringValue: ... @_builtins.property - def router(self) -> _orchestration_pb2.TaskRouter: ... + def retryParentInstanceInfo(self) -> _orchestration_pb2.RetryParentInstanceInfo: + """If defined, indicates that this child workflow is a retry attempt and + links it back to the first attempt in the retry chain. Absent on the + first attempt. The runtime persists this onto the resulting + ChildWorkflowInstanceCreatedEvent so consumers can correlate retry + attempts by grouping on retryParentInstanceInfo.instanceID when present, + otherwise on the created instance's own instanceId. + """ + def __init__( self, *, @@ -96,21 +95,21 @@ class CreateChildWorkflowAction(_message.Message): name: _builtins.str = ..., version: _wrappers_pb2.StringValue | None = ..., input: _wrappers_pb2.StringValue | None = ..., - router: _orchestration_pb2.TaskRouter | None = ..., historyPropagationScope: _orchestration_pb2.HistoryPropagationScope.ValueType | None = ..., + retryParentInstanceInfo: _orchestration_pb2.RetryParentInstanceInfo | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_router", b"_router", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "router", b"router", "version", b"version"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_retryParentInstanceInfo", b"_retryParentInstanceInfo", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "retryParentInstanceInfo", b"retryParentInstanceInfo", "version", b"version"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_router", b"_router", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "instanceId", b"instanceId", "name", b"name", "router", b"router", "version", b"version"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope", "_retryParentInstanceInfo", b"_retryParentInstanceInfo", "historyPropagationScope", b"historyPropagationScope", "input", b"input", "instanceId", b"instanceId", "name", b"name", "retryParentInstanceInfo", b"retryParentInstanceInfo", "version", b"version"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... _WhichOneofReturnType__historyPropagationScope: _TypeAlias = _typing.Literal["historyPropagationScope"] # noqa: Y015 _WhichOneofArgType__historyPropagationScope: _TypeAlias = _typing.Literal["_historyPropagationScope", b"_historyPropagationScope"] # noqa: Y015 - _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 - _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 + _WhichOneofReturnType__retryParentInstanceInfo: _TypeAlias = _typing.Literal["retryParentInstanceInfo"] # noqa: Y015 + _WhichOneofArgType__retryParentInstanceInfo: _TypeAlias = _typing.Literal["_retryParentInstanceInfo", b"_retryParentInstanceInfo"] # noqa: Y015 @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__historyPropagationScope) -> _WhichOneofReturnType__historyPropagationScope | None: ... @_typing.overload - def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... + def WhichOneof(self, oneof_group: _WhichOneofArgType__retryParentInstanceInfo) -> _WhichOneofReturnType__retryParentInstanceInfo | None: ... Global___CreateChildWorkflowAction: _TypeAlias = CreateChildWorkflowAction # noqa: Y015 @@ -153,7 +152,6 @@ class CreateDetachedWorkflowAction(_message.Message): EXECUTIONID_FIELD_NUMBER: _builtins.int TAGS_FIELD_NUMBER: _builtins.int PARENTTRACECONTEXT_FIELD_NUMBER: _builtins.int - ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str """instanceId is the ID assigned to the new workflow. It is mandatory: implementors must set a stable, deterministic ID so that on replay the @@ -179,8 +177,6 @@ class CreateDetachedWorkflowAction(_message.Message): def tags(self) -> _containers.ScalarMap[_builtins.str, _builtins.str]: ... @_builtins.property def parentTraceContext(self) -> _orchestration_pb2.TraceContext: ... - @_builtins.property - def router(self) -> _orchestration_pb2.TaskRouter: ... def __init__( self, *, @@ -192,23 +188,18 @@ class CreateDetachedWorkflowAction(_message.Message): executionId: _wrappers_pb2.StringValue | None = ..., tags: _abc.Mapping[_builtins.str, _builtins.str] | None = ..., parentTraceContext: _orchestration_pb2.TraceContext | None = ..., - router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["_parentTraceContext", b"_parentTraceContext", "_router", b"_router", "_scheduledStartTimestamp", b"_scheduledStartTimestamp", "executionId", b"executionId", "input", b"input", "parentTraceContext", b"parentTraceContext", "router", b"router", "scheduledStartTimestamp", b"scheduledStartTimestamp", "version", b"version"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_parentTraceContext", b"_parentTraceContext", "_scheduledStartTimestamp", b"_scheduledStartTimestamp", "executionId", b"executionId", "input", b"input", "parentTraceContext", b"parentTraceContext", "scheduledStartTimestamp", b"scheduledStartTimestamp", "version", b"version"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["_parentTraceContext", b"_parentTraceContext", "_router", b"_router", "_scheduledStartTimestamp", b"_scheduledStartTimestamp", "executionId", b"executionId", "input", b"input", "instanceId", b"instanceId", "name", b"name", "parentTraceContext", b"parentTraceContext", "router", b"router", "scheduledStartTimestamp", b"scheduledStartTimestamp", "tags", b"tags", "version", b"version"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_parentTraceContext", b"_parentTraceContext", "_scheduledStartTimestamp", b"_scheduledStartTimestamp", "executionId", b"executionId", "input", b"input", "instanceId", b"instanceId", "name", b"name", "parentTraceContext", b"parentTraceContext", "scheduledStartTimestamp", b"scheduledStartTimestamp", "tags", b"tags", "version", b"version"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... _WhichOneofReturnType__parentTraceContext: _TypeAlias = _typing.Literal["parentTraceContext"] # noqa: Y015 _WhichOneofArgType__parentTraceContext: _TypeAlias = _typing.Literal["_parentTraceContext", b"_parentTraceContext"] # noqa: Y015 - _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 - _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 _WhichOneofReturnType__scheduledStartTimestamp: _TypeAlias = _typing.Literal["scheduledStartTimestamp"] # noqa: Y015 _WhichOneofArgType__scheduledStartTimestamp: _TypeAlias = _typing.Literal["_scheduledStartTimestamp", b"_scheduledStartTimestamp"] # noqa: Y015 @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__parentTraceContext) -> _WhichOneofReturnType__parentTraceContext | None: ... @_typing.overload - def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... - @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__scheduledStartTimestamp) -> _WhichOneofReturnType__scheduledStartTimestamp | None: ... Global___CreateDetachedWorkflowAction: _TypeAlias = CreateDetachedWorkflowAction # noqa: Y015 diff --git a/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.py b/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.py index 443535186..80f69c149 100644 --- a/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.py +++ b/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.py @@ -30,7 +30,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aorchestrator_service.proto\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1aorchestrator_actions.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x1bgoogle/protobuf/empty.proto\"\xc6\x02\n\x0f\x41\x63tivityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12\x0e\n\x06taskId\x18\x05 \x01(\x05\x12)\n\x12parentTraceContext\x18\x06 \x01(\x0b\x32\r.TraceContext\x12\x17\n\x0ftaskExecutionId\x18\x07 \x01(\t\x12\x32\n\x11propagatedHistory\x18\x08 \x01(\x0b\x32\x12.PropagatedHistoryH\x00\x88\x01\x01\x42\x14\n\x12_propagatedHistory\"\xaa\x01\n\x10\x41\x63tivityResponse\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0e\n\x06taskId\x18\x02 \x01(\x05\x12,\n\x06result\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x04 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x17\n\x0f\x63ompletionToken\x18\x05 \x01(\t\"#\n\rCachedHistory\x12\x12\n\neventCount\x18\x01 \x01(\x05\"\xfa\x02\n\x0fWorkflowRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x31\n\x0b\x65xecutionId\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12!\n\npastEvents\x18\x03 \x03(\x0b\x32\r.HistoryEvent\x12 \n\tnewEvents\x18\x04 \x03(\x0b\x32\r.HistoryEvent\x12 \n\x18requiresHistoryStreaming\x18\x06 \x01(\x08\x12 \n\x06router\x18\x07 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x12\x32\n\x11propagatedHistory\x18\x08 \x01(\x0b\x32\x12.PropagatedHistoryH\x01\x88\x01\x01\x12*\n\rcachedHistory\x18\t \x01(\x0b\x32\x0e.CachedHistoryH\x02\x88\x01\x01\x42\t\n\x07_routerB\x14\n\x12_propagatedHistoryB\x10\n\x0e_cachedHistoryJ\x04\x08\x05\x10\x06\"\x82\x02\n\x10WorkflowResponse\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12 \n\x07\x61\x63tions\x18\x02 \x03(\x0b\x32\x0f.WorkflowAction\x12\x32\n\x0c\x63ustomStatus\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x17\n\x0f\x63ompletionToken\x18\x04 \x01(\t\x12\x37\n\x12numEventsProcessed\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12&\n\x07version\x18\x06 \x01(\x0b\x32\x10.WorkflowVersionH\x00\x88\x01\x01\x42\n\n\x08_version\"\xaf\x03\n\x15\x43reateInstanceRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12;\n\x17scheduledStartTimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\x0b\x65xecutionId\x18\x07 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x04tags\x18\x08 \x03(\x0b\x32 .CreateInstanceRequest.TagsEntry\x12)\n\x12parentTraceContext\x18\t \x01(\x0b\x32\r.TraceContext\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01J\x04\x08\x06\x10\x07R\x1aorchestrationIdReusePolicy\",\n\x16\x43reateInstanceResponse\x12\x12\n\ninstanceId\x18\x01 \x01(\t\"E\n\x12GetInstanceRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x1b\n\x13getInputsAndOutputs\x18\x02 \x01(\x08\"L\n\x13GetInstanceResponse\x12\x0e\n\x06\x65xists\x18\x01 \x01(\x08\x12%\n\rworkflowState\x18\x02 \x01(\x0b\x32\x0e.WorkflowState\"b\n\x11RaiseEventRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\x14\n\x12RaiseEventResponse\"g\n\x10TerminateRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06output\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x11\n\trecursive\x18\x03 \x01(\x08\"\x13\n\x11TerminateResponse\"R\n\x0eSuspendRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06reason\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\x11\n\x0fSuspendResponse\"Q\n\rResumeRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06reason\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\x10\n\x0eResumeResponse\"\x9e\x01\n\x15PurgeInstancesRequest\x12\x14\n\ninstanceId\x18\x01 \x01(\tH\x00\x12\x33\n\x13purgeInstanceFilter\x18\x02 \x01(\x0b\x32\x14.PurgeInstanceFilterH\x00\x12\x11\n\trecursive\x18\x03 \x01(\x08\x12\x12\n\x05\x66orce\x18\x04 \x01(\x08H\x01\x88\x01\x01\x42\t\n\x07requestB\x08\n\x06_force\"\xaa\x01\n\x13PurgeInstanceFilter\x12\x33\n\x0f\x63reatedTimeFrom\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rcreatedTimeTo\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\rruntimeStatus\x18\x03 \x03(\x0e\x32\x14.OrchestrationStatus\"f\n\x16PurgeInstancesResponse\x12\x1c\n\x14\x64\x65letedInstanceCount\x18\x01 \x01(\x05\x12.\n\nisComplete\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"V\n\x13GetWorkItemsRequest\x12\'\n\x0c\x63\x61pabilities\x18\x04 \x03(\x0e\x32\x11.WorkerCapabilityJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04J\x04\x08\n\x10\x0b\"\x9a\x01\n\x08WorkItem\x12+\n\x0fworkflowRequest\x18\x01 \x01(\x0b\x32\x10.WorkflowRequestH\x00\x12+\n\x0f\x61\x63tivityRequest\x18\x02 \x01(\x0b\x32\x10.ActivityRequestH\x00\x12\x17\n\x0f\x63ompletionToken\x18\n \x01(\tB\t\n\x07requestJ\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06\"\x16\n\x14\x43ompleteTaskResponse\"\x85\x02\n\x1dRerunWorkflowFromEventRequest\x12\x18\n\x10sourceInstanceID\x18\x01 \x01(\t\x12\x0f\n\x07\x65ventID\x18\x02 \x01(\r\x12\x1a\n\rnewInstanceID\x18\x03 \x01(\tH\x00\x88\x01\x01\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x16\n\x0eoverwriteInput\x18\x05 \x01(\x08\x12\'\n\x1anewChildWorkflowInstanceID\x18\x06 \x01(\tH\x01\x88\x01\x01\x42\x10\n\x0e_newInstanceIDB\x1d\n\x1b_newChildWorkflowInstanceID\"7\n\x1eRerunWorkflowFromEventResponse\x12\x15\n\rnewInstanceID\x18\x01 \x01(\t\"r\n\x16ListInstanceIDsRequest\x12\x1e\n\x11\x63ontinuationToken\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x15\n\x08pageSize\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x14\n\x12_continuationTokenB\x0b\n\t_pageSize\"d\n\x17ListInstanceIDsResponse\x12\x13\n\x0binstanceIds\x18\x01 \x03(\t\x12\x1e\n\x11\x63ontinuationToken\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x14\n\x12_continuationToken\"/\n\x19GetInstanceHistoryRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\";\n\x1aGetInstanceHistoryResponse\x12\x1d\n\x06\x65vents\x18\x01 \x03(\x0b\x32\r.HistoryEvent*\x88\x01\n\x10WorkerCapability\x12!\n\x1dWORKER_CAPABILITY_UNSPECIFIED\x10\x00\x12&\n\"WORKER_CAPABILITY_STATEFUL_HISTORY\x10\x02\"\x04\x08\x01\x10\x01*#WORKER_CAPABILITY_HISTORY_STREAMING2\xe8\x08\n\x15TaskHubSidecarService\x12\x37\n\x05Hello\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12@\n\rStartInstance\x12\x16.CreateInstanceRequest\x1a\x17.CreateInstanceResponse\x12\x38\n\x0bGetInstance\x12\x13.GetInstanceRequest\x1a\x14.GetInstanceResponse\x12\x41\n\x14WaitForInstanceStart\x12\x13.GetInstanceRequest\x1a\x14.GetInstanceResponse\x12\x46\n\x19WaitForInstanceCompletion\x12\x13.GetInstanceRequest\x1a\x14.GetInstanceResponse\x12\x35\n\nRaiseEvent\x12\x12.RaiseEventRequest\x1a\x13.RaiseEventResponse\x12:\n\x11TerminateInstance\x12\x11.TerminateRequest\x1a\x12.TerminateResponse\x12\x34\n\x0fSuspendInstance\x12\x0f.SuspendRequest\x1a\x10.SuspendResponse\x12\x31\n\x0eResumeInstance\x12\x0e.ResumeRequest\x1a\x0f.ResumeResponse\x12\x41\n\x0ePurgeInstances\x12\x16.PurgeInstancesRequest\x1a\x17.PurgeInstancesResponse\x12\x31\n\x0cGetWorkItems\x12\x14.GetWorkItemsRequest\x1a\t.WorkItem0\x01\x12@\n\x14\x43ompleteActivityTask\x12\x11.ActivityResponse\x1a\x15.CompleteTaskResponse\x12I\n\x18\x43ompleteOrchestratorTask\x12\x11.WorkflowResponse\x1a\x15.CompleteTaskResponse\"\x03\x88\x02\x01\x12@\n\x14\x43ompleteWorkflowTask\x12\x11.WorkflowResponse\x1a\x15.CompleteTaskResponse\x12Y\n\x16RerunWorkflowFromEvent\x12\x1e.RerunWorkflowFromEventRequest\x1a\x1f.RerunWorkflowFromEventResponse\x12\x44\n\x0fListInstanceIDs\x12\x17.ListInstanceIDsRequest\x1a\x18.ListInstanceIDsResponse\x12M\n\x12GetInstanceHistory\x12\x1a.GetInstanceHistoryRequest\x1a\x1b.GetInstanceHistoryResponseBV\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aorchestrator_service.proto\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1aorchestrator_actions.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x1bgoogle/protobuf/empty.proto\"\xc6\x02\n\x0f\x41\x63tivityRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12\x0e\n\x06taskId\x18\x05 \x01(\x05\x12)\n\x12parentTraceContext\x18\x06 \x01(\x0b\x32\r.TraceContext\x12\x17\n\x0ftaskExecutionId\x18\x07 \x01(\t\x12\x32\n\x11propagatedHistory\x18\x08 \x01(\x0b\x32\x12.PropagatedHistoryH\x00\x88\x01\x01\x42\x14\n\x12_propagatedHistory\"\xaa\x01\n\x10\x41\x63tivityResponse\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0e\n\x06taskId\x18\x02 \x01(\x05\x12,\n\x06result\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x04 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x17\n\x0f\x63ompletionToken\x18\x05 \x01(\t\"#\n\rCachedHistory\x12\x12\n\neventCount\x18\x01 \x01(\x05\"\xfa\x02\n\x0fWorkflowRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x31\n\x0b\x65xecutionId\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12!\n\npastEvents\x18\x03 \x03(\x0b\x32\r.HistoryEvent\x12 \n\tnewEvents\x18\x04 \x03(\x0b\x32\r.HistoryEvent\x12 \n\x18requiresHistoryStreaming\x18\x06 \x01(\x08\x12 \n\x06router\x18\x07 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x12\x32\n\x11propagatedHistory\x18\x08 \x01(\x0b\x32\x12.PropagatedHistoryH\x01\x88\x01\x01\x12*\n\rcachedHistory\x18\t \x01(\x0b\x32\x0e.CachedHistoryH\x02\x88\x01\x01\x42\t\n\x07_routerB\x14\n\x12_propagatedHistoryB\x10\n\x0e_cachedHistoryJ\x04\x08\x05\x10\x06\"\x82\x02\n\x10WorkflowResponse\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12 \n\x07\x61\x63tions\x18\x02 \x03(\x0b\x32\x0f.WorkflowAction\x12\x32\n\x0c\x63ustomStatus\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x17\n\x0f\x63ompletionToken\x18\x04 \x01(\t\x12\x37\n\x12numEventsProcessed\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12&\n\x07version\x18\x06 \x01(\x0b\x32\x10.WorkflowVersionH\x00\x88\x01\x01\x42\n\n\x08_version\"\xfd\x03\n\x15\x43reateInstanceRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12;\n\x17scheduledStartTimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\x0b\x65xecutionId\x18\x07 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x04tags\x18\x08 \x03(\x0b\x32 .CreateInstanceRequest.TagsEntry\x12)\n\x12parentTraceContext\x18\t \x01(\x0b\x32\r.TraceContext\x12\x1f\n\x17\x65nforceUniqueInstanceId\x18\n \x01(\x08\x12 \n\x06router\x18\x0b \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_routerJ\x04\x08\x06\x10\x07R\x1aorchestrationIdReusePolicy\",\n\x16\x43reateInstanceResponse\x12\x12\n\ninstanceId\x18\x01 \x01(\t\"r\n\x12GetInstanceRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x1b\n\x13getInputsAndOutputs\x18\x02 \x01(\x08\x12 \n\x06router\x18\x03 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x42\t\n\x07_router\"L\n\x13GetInstanceResponse\x12\x0e\n\x06\x65xists\x18\x01 \x01(\x08\x12%\n\rworkflowState\x18\x02 \x01(\x0b\x32\x0e.WorkflowState\"\x8f\x01\n\x11RaiseEventRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x04 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x42\t\n\x07_router\"\x14\n\x12RaiseEventResponse\"\x94\x01\n\x10TerminateRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06output\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x11\n\trecursive\x18\x03 \x01(\x08\x12 \n\x06router\x18\x04 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x42\t\n\x07_router\"\x13\n\x11TerminateResponse\"\x7f\n\x0eSuspendRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06reason\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x03 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x42\t\n\x07_router\"\x11\n\x0fSuspendResponse\"~\n\rResumeRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06reason\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x03 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x42\t\n\x07_router\"\x10\n\x0eResumeResponse\"\xcb\x01\n\x15PurgeInstancesRequest\x12\x14\n\ninstanceId\x18\x01 \x01(\tH\x00\x12\x33\n\x13purgeInstanceFilter\x18\x02 \x01(\x0b\x32\x14.PurgeInstanceFilterH\x00\x12\x11\n\trecursive\x18\x03 \x01(\x08\x12\x12\n\x05\x66orce\x18\x04 \x01(\x08H\x01\x88\x01\x01\x12 \n\x06router\x18\x05 \x01(\x0b\x32\x0b.TaskRouterH\x02\x88\x01\x01\x42\t\n\x07requestB\x08\n\x06_forceB\t\n\x07_router\"\xaa\x01\n\x13PurgeInstanceFilter\x12\x33\n\x0f\x63reatedTimeFrom\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x31\n\rcreatedTimeTo\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\rruntimeStatus\x18\x03 \x03(\x0e\x32\x14.OrchestrationStatus\"f\n\x16PurgeInstancesResponse\x12\x1c\n\x14\x64\x65letedInstanceCount\x18\x01 \x01(\x05\x12.\n\nisComplete\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"V\n\x13GetWorkItemsRequest\x12\'\n\x0c\x63\x61pabilities\x18\x04 \x03(\x0e\x32\x11.WorkerCapabilityJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04J\x04\x08\n\x10\x0b\"\x9a\x01\n\x08WorkItem\x12+\n\x0fworkflowRequest\x18\x01 \x01(\x0b\x32\x10.WorkflowRequestH\x00\x12+\n\x0f\x61\x63tivityRequest\x18\x02 \x01(\x0b\x32\x10.ActivityRequestH\x00\x12\x17\n\x0f\x63ompletionToken\x18\n \x01(\tB\t\n\x07requestJ\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06\"\x16\n\x14\x43ompleteTaskResponse\"\xb2\x02\n\x1dRerunWorkflowFromEventRequest\x12\x18\n\x10sourceInstanceID\x18\x01 \x01(\t\x12\x0f\n\x07\x65ventID\x18\x02 \x01(\r\x12\x1a\n\rnewInstanceID\x18\x03 \x01(\tH\x00\x88\x01\x01\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x16\n\x0eoverwriteInput\x18\x05 \x01(\x08\x12\'\n\x1anewChildWorkflowInstanceID\x18\x06 \x01(\tH\x01\x88\x01\x01\x12 \n\x06router\x18\x07 \x01(\x0b\x32\x0b.TaskRouterH\x02\x88\x01\x01\x42\x10\n\x0e_newInstanceIDB\x1d\n\x1b_newChildWorkflowInstanceIDB\t\n\x07_router\"7\n\x1eRerunWorkflowFromEventResponse\x12\x15\n\rnewInstanceID\x18\x01 \x01(\t\"r\n\x16ListInstanceIDsRequest\x12\x1e\n\x11\x63ontinuationToken\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x15\n\x08pageSize\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x14\n\x12_continuationTokenB\x0b\n\t_pageSize\"d\n\x17ListInstanceIDsResponse\x12\x13\n\x0binstanceIds\x18\x01 \x03(\t\x12\x1e\n\x11\x63ontinuationToken\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x14\n\x12_continuationToken\"/\n\x19GetInstanceHistoryRequest\x12\x12\n\ninstanceId\x18\x01 \x01(\t\";\n\x1aGetInstanceHistoryResponse\x12\x1d\n\x06\x65vents\x18\x01 \x03(\x0b\x32\r.HistoryEvent*\x88\x01\n\x10WorkerCapability\x12!\n\x1dWORKER_CAPABILITY_UNSPECIFIED\x10\x00\x12&\n\"WORKER_CAPABILITY_STATEFUL_HISTORY\x10\x02\"\x04\x08\x01\x10\x01*#WORKER_CAPABILITY_HISTORY_STREAMING2\xe8\x08\n\x15TaskHubSidecarService\x12\x37\n\x05Hello\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12@\n\rStartInstance\x12\x16.CreateInstanceRequest\x1a\x17.CreateInstanceResponse\x12\x38\n\x0bGetInstance\x12\x13.GetInstanceRequest\x1a\x14.GetInstanceResponse\x12\x41\n\x14WaitForInstanceStart\x12\x13.GetInstanceRequest\x1a\x14.GetInstanceResponse\x12\x46\n\x19WaitForInstanceCompletion\x12\x13.GetInstanceRequest\x1a\x14.GetInstanceResponse\x12\x35\n\nRaiseEvent\x12\x12.RaiseEventRequest\x1a\x13.RaiseEventResponse\x12:\n\x11TerminateInstance\x12\x11.TerminateRequest\x1a\x12.TerminateResponse\x12\x34\n\x0fSuspendInstance\x12\x0f.SuspendRequest\x1a\x10.SuspendResponse\x12\x31\n\x0eResumeInstance\x12\x0e.ResumeRequest\x1a\x0f.ResumeResponse\x12\x41\n\x0ePurgeInstances\x12\x16.PurgeInstancesRequest\x1a\x17.PurgeInstancesResponse\x12\x31\n\x0cGetWorkItems\x12\x14.GetWorkItemsRequest\x1a\t.WorkItem0\x01\x12@\n\x14\x43ompleteActivityTask\x12\x11.ActivityResponse\x1a\x15.CompleteTaskResponse\x12I\n\x18\x43ompleteOrchestratorTask\x12\x11.WorkflowResponse\x1a\x15.CompleteTaskResponse\"\x03\x88\x02\x01\x12@\n\x14\x43ompleteWorkflowTask\x12\x11.WorkflowResponse\x1a\x15.CompleteTaskResponse\x12Y\n\x16RerunWorkflowFromEvent\x12\x1e.RerunWorkflowFromEventRequest\x1a\x1f.RerunWorkflowFromEventResponse\x12\x44\n\x0fListInstanceIDs\x12\x17.ListInstanceIDsRequest\x1a\x18.ListInstanceIDsResponse\x12M\n\x12GetInstanceHistory\x12\x1a.GetInstanceHistoryRequest\x1a\x1b.GetInstanceHistoryResponseBV\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -42,8 +42,8 @@ _globals['_CREATEINSTANCEREQUEST_TAGSENTRY']._serialized_options = b'8\001' _globals['_TASKHUBSIDECARSERVICE'].methods_by_name['CompleteOrchestratorTask']._loaded_options = None _globals['_TASKHUBSIDECARSERVICE'].methods_by_name['CompleteOrchestratorTask']._serialized_options = b'\210\002\001' - _globals['_WORKERCAPABILITY']._serialized_start=3814 - _globals['_WORKERCAPABILITY']._serialized_end=3950 + _globals['_WORKERCAPABILITY']._serialized_start=4209 + _globals['_WORKERCAPABILITY']._serialized_end=4345 _globals['_ACTIVITYREQUEST']._serialized_start=196 _globals['_ACTIVITYREQUEST']._serialized_end=522 _globals['_ACTIVITYRESPONSE']._serialized_start=525 @@ -55,55 +55,55 @@ _globals['_WORKFLOWRESPONSE']._serialized_start=1116 _globals['_WORKFLOWRESPONSE']._serialized_end=1374 _globals['_CREATEINSTANCEREQUEST']._serialized_start=1377 - _globals['_CREATEINSTANCEREQUEST']._serialized_end=1808 - _globals['_CREATEINSTANCEREQUEST_TAGSENTRY']._serialized_start=1731 - _globals['_CREATEINSTANCEREQUEST_TAGSENTRY']._serialized_end=1774 - _globals['_CREATEINSTANCERESPONSE']._serialized_start=1810 - _globals['_CREATEINSTANCERESPONSE']._serialized_end=1854 - _globals['_GETINSTANCEREQUEST']._serialized_start=1856 - _globals['_GETINSTANCEREQUEST']._serialized_end=1925 - _globals['_GETINSTANCERESPONSE']._serialized_start=1927 - _globals['_GETINSTANCERESPONSE']._serialized_end=2003 - _globals['_RAISEEVENTREQUEST']._serialized_start=2005 - _globals['_RAISEEVENTREQUEST']._serialized_end=2103 - _globals['_RAISEEVENTRESPONSE']._serialized_start=2105 - _globals['_RAISEEVENTRESPONSE']._serialized_end=2125 - _globals['_TERMINATEREQUEST']._serialized_start=2127 - _globals['_TERMINATEREQUEST']._serialized_end=2230 - _globals['_TERMINATERESPONSE']._serialized_start=2232 - _globals['_TERMINATERESPONSE']._serialized_end=2251 - _globals['_SUSPENDREQUEST']._serialized_start=2253 - _globals['_SUSPENDREQUEST']._serialized_end=2335 - _globals['_SUSPENDRESPONSE']._serialized_start=2337 - _globals['_SUSPENDRESPONSE']._serialized_end=2354 - _globals['_RESUMEREQUEST']._serialized_start=2356 - _globals['_RESUMEREQUEST']._serialized_end=2437 - _globals['_RESUMERESPONSE']._serialized_start=2439 - _globals['_RESUMERESPONSE']._serialized_end=2455 - _globals['_PURGEINSTANCESREQUEST']._serialized_start=2458 - _globals['_PURGEINSTANCESREQUEST']._serialized_end=2616 - _globals['_PURGEINSTANCEFILTER']._serialized_start=2619 - _globals['_PURGEINSTANCEFILTER']._serialized_end=2789 - _globals['_PURGEINSTANCESRESPONSE']._serialized_start=2791 - _globals['_PURGEINSTANCESRESPONSE']._serialized_end=2893 - _globals['_GETWORKITEMSREQUEST']._serialized_start=2895 - _globals['_GETWORKITEMSREQUEST']._serialized_end=2981 - _globals['_WORKITEM']._serialized_start=2984 - _globals['_WORKITEM']._serialized_end=3138 - _globals['_COMPLETETASKRESPONSE']._serialized_start=3140 - _globals['_COMPLETETASKRESPONSE']._serialized_end=3162 - _globals['_RERUNWORKFLOWFROMEVENTREQUEST']._serialized_start=3165 - _globals['_RERUNWORKFLOWFROMEVENTREQUEST']._serialized_end=3426 - _globals['_RERUNWORKFLOWFROMEVENTRESPONSE']._serialized_start=3428 - _globals['_RERUNWORKFLOWFROMEVENTRESPONSE']._serialized_end=3483 - _globals['_LISTINSTANCEIDSREQUEST']._serialized_start=3485 - _globals['_LISTINSTANCEIDSREQUEST']._serialized_end=3599 - _globals['_LISTINSTANCEIDSRESPONSE']._serialized_start=3601 - _globals['_LISTINSTANCEIDSRESPONSE']._serialized_end=3701 - _globals['_GETINSTANCEHISTORYREQUEST']._serialized_start=3703 - _globals['_GETINSTANCEHISTORYREQUEST']._serialized_end=3750 - _globals['_GETINSTANCEHISTORYRESPONSE']._serialized_start=3752 - _globals['_GETINSTANCEHISTORYRESPONSE']._serialized_end=3811 - _globals['_TASKHUBSIDECARSERVICE']._serialized_start=3953 - _globals['_TASKHUBSIDECARSERVICE']._serialized_end=5081 + _globals['_CREATEINSTANCEREQUEST']._serialized_end=1886 + _globals['_CREATEINSTANCEREQUEST_TAGSENTRY']._serialized_start=1798 + _globals['_CREATEINSTANCEREQUEST_TAGSENTRY']._serialized_end=1841 + _globals['_CREATEINSTANCERESPONSE']._serialized_start=1888 + _globals['_CREATEINSTANCERESPONSE']._serialized_end=1932 + _globals['_GETINSTANCEREQUEST']._serialized_start=1934 + _globals['_GETINSTANCEREQUEST']._serialized_end=2048 + _globals['_GETINSTANCERESPONSE']._serialized_start=2050 + _globals['_GETINSTANCERESPONSE']._serialized_end=2126 + _globals['_RAISEEVENTREQUEST']._serialized_start=2129 + _globals['_RAISEEVENTREQUEST']._serialized_end=2272 + _globals['_RAISEEVENTRESPONSE']._serialized_start=2274 + _globals['_RAISEEVENTRESPONSE']._serialized_end=2294 + _globals['_TERMINATEREQUEST']._serialized_start=2297 + _globals['_TERMINATEREQUEST']._serialized_end=2445 + _globals['_TERMINATERESPONSE']._serialized_start=2447 + _globals['_TERMINATERESPONSE']._serialized_end=2466 + _globals['_SUSPENDREQUEST']._serialized_start=2468 + _globals['_SUSPENDREQUEST']._serialized_end=2595 + _globals['_SUSPENDRESPONSE']._serialized_start=2597 + _globals['_SUSPENDRESPONSE']._serialized_end=2614 + _globals['_RESUMEREQUEST']._serialized_start=2616 + _globals['_RESUMEREQUEST']._serialized_end=2742 + _globals['_RESUMERESPONSE']._serialized_start=2744 + _globals['_RESUMERESPONSE']._serialized_end=2760 + _globals['_PURGEINSTANCESREQUEST']._serialized_start=2763 + _globals['_PURGEINSTANCESREQUEST']._serialized_end=2966 + _globals['_PURGEINSTANCEFILTER']._serialized_start=2969 + _globals['_PURGEINSTANCEFILTER']._serialized_end=3139 + _globals['_PURGEINSTANCESRESPONSE']._serialized_start=3141 + _globals['_PURGEINSTANCESRESPONSE']._serialized_end=3243 + _globals['_GETWORKITEMSREQUEST']._serialized_start=3245 + _globals['_GETWORKITEMSREQUEST']._serialized_end=3331 + _globals['_WORKITEM']._serialized_start=3334 + _globals['_WORKITEM']._serialized_end=3488 + _globals['_COMPLETETASKRESPONSE']._serialized_start=3490 + _globals['_COMPLETETASKRESPONSE']._serialized_end=3512 + _globals['_RERUNWORKFLOWFROMEVENTREQUEST']._serialized_start=3515 + _globals['_RERUNWORKFLOWFROMEVENTREQUEST']._serialized_end=3821 + _globals['_RERUNWORKFLOWFROMEVENTRESPONSE']._serialized_start=3823 + _globals['_RERUNWORKFLOWFROMEVENTRESPONSE']._serialized_end=3878 + _globals['_LISTINSTANCEIDSREQUEST']._serialized_start=3880 + _globals['_LISTINSTANCEIDSREQUEST']._serialized_end=3994 + _globals['_LISTINSTANCEIDSRESPONSE']._serialized_start=3996 + _globals['_LISTINSTANCEIDSRESPONSE']._serialized_end=4096 + _globals['_GETINSTANCEHISTORYREQUEST']._serialized_start=4098 + _globals['_GETINSTANCEHISTORYREQUEST']._serialized_end=4145 + _globals['_GETINSTANCEHISTORYRESPONSE']._serialized_start=4147 + _globals['_GETINSTANCEHISTORYRESPONSE']._serialized_end=4206 + _globals['_TASKHUBSIDECARSERVICE']._serialized_start=4348 + _globals['_TASKHUBSIDECARSERVICE']._serialized_end=5476 # @@protoc_insertion_point(module_scope) diff --git a/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.pyi b/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.pyi index dcce421a4..40cc431b7 100644 --- a/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.pyi +++ b/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.pyi @@ -322,8 +322,15 @@ class CreateInstanceRequest(_message.Message): EXECUTIONID_FIELD_NUMBER: _builtins.int TAGS_FIELD_NUMBER: _builtins.int PARENTTRACECONTEXT_FIELD_NUMBER: _builtins.int + ENFORCEUNIQUEINSTANCEID_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str name: _builtins.str + enforceUniqueInstanceId: _builtins.bool + """When true, the request fails with an ALREADY_EXISTS error if a workflow + instance with the same instanceId already exists, whether active or + completed. When false, an existing completed instance is restarted. + """ @_builtins.property def version(self) -> _wrappers_pb2.StringValue: ... @_builtins.property @@ -336,6 +343,15 @@ class CreateInstanceRequest(_message.Message): def tags(self) -> _containers.ScalarMap[_builtins.str, _builtins.str]: ... @_builtins.property def parentTraceContext(self) -> _orchestration_pb2.TraceContext: ... + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. When targetAppID names a different app, the operation is + executed against that app's instance (same namespace unless + targetAppNamespace is set). sourceAppID is stamped by the sidecar, not + the client. + """ + def __init__( self, *, @@ -347,11 +363,16 @@ class CreateInstanceRequest(_message.Message): executionId: _wrappers_pb2.StringValue | None = ..., tags: _abc.Mapping[_builtins.str, _builtins.str] | None = ..., parentTraceContext: _orchestration_pb2.TraceContext | None = ..., + enforceUniqueInstanceId: _builtins.bool = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["executionId", b"executionId", "input", b"input", "parentTraceContext", b"parentTraceContext", "scheduledStartTimestamp", b"scheduledStartTimestamp", "version", b"version"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "executionId", b"executionId", "input", b"input", "parentTraceContext", b"parentTraceContext", "router", b"router", "scheduledStartTimestamp", b"scheduledStartTimestamp", "version", b"version"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["executionId", b"executionId", "input", b"input", "instanceId", b"instanceId", "name", b"name", "parentTraceContext", b"parentTraceContext", "scheduledStartTimestamp", b"scheduledStartTimestamp", "tags", b"tags", "version", b"version"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "enforceUniqueInstanceId", b"enforceUniqueInstanceId", "executionId", b"executionId", "input", b"input", "instanceId", b"instanceId", "name", b"name", "parentTraceContext", b"parentTraceContext", "router", b"router", "scheduledStartTimestamp", b"scheduledStartTimestamp", "tags", b"tags", "version", b"version"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___CreateInstanceRequest: _TypeAlias = CreateInstanceRequest # noqa: Y015 @@ -377,16 +398,29 @@ class GetInstanceRequest(_message.Message): INSTANCEID_FIELD_NUMBER: _builtins.int GETINPUTSANDOUTPUTS_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str getInputsAndOutputs: _builtins.bool + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. sourceAppID is stamped by the sidecar, not the client. + """ + def __init__( self, *, instanceId: _builtins.str = ..., getInputsAndOutputs: _builtins.bool = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["getInputsAndOutputs", b"getInputsAndOutputs", "instanceId", b"instanceId"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "router", b"router"] # noqa: Y015 + def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... + _ClearFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "getInputsAndOutputs", b"getInputsAndOutputs", "instanceId", b"instanceId", "router", b"router"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___GetInstanceRequest: _TypeAlias = GetInstanceRequest # noqa: Y015 @@ -419,21 +453,32 @@ class RaiseEventRequest(_message.Message): INSTANCEID_FIELD_NUMBER: _builtins.int NAME_FIELD_NUMBER: _builtins.int INPUT_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str name: _builtins.str @_builtins.property def input(self) -> _wrappers_pb2.StringValue: ... + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. sourceAppID is stamped by the sidecar, not the client. + """ + def __init__( self, *, instanceId: _builtins.str = ..., name: _builtins.str = ..., input: _wrappers_pb2.StringValue | None = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["input", b"input"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "input", b"input", "router", b"router"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["input", b"input", "instanceId", b"instanceId", "name", b"name"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "input", b"input", "instanceId", b"instanceId", "name", b"name", "router", b"router"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___RaiseEventRequest: _TypeAlias = RaiseEventRequest # noqa: Y015 @@ -456,21 +501,32 @@ class TerminateRequest(_message.Message): INSTANCEID_FIELD_NUMBER: _builtins.int OUTPUT_FIELD_NUMBER: _builtins.int RECURSIVE_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str recursive: _builtins.bool @_builtins.property def output(self) -> _wrappers_pb2.StringValue: ... + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. sourceAppID is stamped by the sidecar, not the client. + """ + def __init__( self, *, instanceId: _builtins.str = ..., output: _wrappers_pb2.StringValue | None = ..., recursive: _builtins.bool = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["output", b"output"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "output", b"output", "router", b"router"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["instanceId", b"instanceId", "output", b"output", "recursive", b"recursive"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "instanceId", b"instanceId", "output", b"output", "recursive", b"recursive", "router", b"router"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___TerminateRequest: _TypeAlias = TerminateRequest # noqa: Y015 @@ -492,19 +548,30 @@ class SuspendRequest(_message.Message): INSTANCEID_FIELD_NUMBER: _builtins.int REASON_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str @_builtins.property def reason(self) -> _wrappers_pb2.StringValue: ... + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. sourceAppID is stamped by the sidecar, not the client. + """ + def __init__( self, *, instanceId: _builtins.str = ..., reason: _wrappers_pb2.StringValue | None = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["reason", b"reason"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "reason", b"reason", "router", b"router"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["instanceId", b"instanceId", "reason", b"reason"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "instanceId", b"instanceId", "reason", b"reason", "router", b"router"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___SuspendRequest: _TypeAlias = SuspendRequest # noqa: Y015 @@ -526,19 +593,30 @@ class ResumeRequest(_message.Message): INSTANCEID_FIELD_NUMBER: _builtins.int REASON_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str @_builtins.property def reason(self) -> _wrappers_pb2.StringValue: ... + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. sourceAppID is stamped by the sidecar, not the client. + """ + def __init__( self, *, instanceId: _builtins.str = ..., reason: _wrappers_pb2.StringValue | None = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["reason", b"reason"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "reason", b"reason", "router", b"router"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["instanceId", b"instanceId", "reason", b"reason"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_router", b"_router", "instanceId", b"instanceId", "reason", b"reason", "router", b"router"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___ResumeRequest: _TypeAlias = ResumeRequest # noqa: Y015 @@ -562,6 +640,7 @@ class PurgeInstancesRequest(_message.Message): PURGEINSTANCEFILTER_FIELD_NUMBER: _builtins.int RECURSIVE_FIELD_NUMBER: _builtins.int FORCE_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int instanceId: _builtins.str recursive: _builtins.bool force: _builtins.bool @@ -577,6 +656,14 @@ class PurgeInstancesRequest(_message.Message): """ @_builtins.property def purgeInstanceFilter(self) -> Global___PurgeInstanceFilter: ... + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. Cross-app purges are delegated to the target app in + full, so they are always recursive on the remote side. sourceAppID is + stamped by the sidecar, not the client. + """ + def __init__( self, *, @@ -584,18 +671,23 @@ class PurgeInstancesRequest(_message.Message): purgeInstanceFilter: Global___PurgeInstanceFilter | None = ..., recursive: _builtins.bool = ..., force: _builtins.bool | None = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["_force", b"_force", "force", b"force", "instanceId", b"instanceId", "purgeInstanceFilter", b"purgeInstanceFilter", "request", b"request"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_force", b"_force", "_router", b"_router", "force", b"force", "instanceId", b"instanceId", "purgeInstanceFilter", b"purgeInstanceFilter", "request", b"request", "router", b"router"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["_force", b"_force", "force", b"force", "instanceId", b"instanceId", "purgeInstanceFilter", b"purgeInstanceFilter", "recursive", b"recursive", "request", b"request"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_force", b"_force", "_router", b"_router", "force", b"force", "instanceId", b"instanceId", "purgeInstanceFilter", b"purgeInstanceFilter", "recursive", b"recursive", "request", b"request", "router", b"router"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... _WhichOneofReturnType__force: _TypeAlias = _typing.Literal["force"] # noqa: Y015 _WhichOneofArgType__force: _TypeAlias = _typing.Literal["_force", b"_force"] # noqa: Y015 + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 _WhichOneofReturnType_request: _TypeAlias = _typing.Literal["instanceId", "purgeInstanceFilter"] # noqa: Y015 _WhichOneofArgType_request: _TypeAlias = _typing.Literal["request", b"request"] # noqa: Y015 @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__force) -> _WhichOneofReturnType__force | None: ... @_typing.overload + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... + @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType_request) -> _WhichOneofReturnType_request | None: ... Global___PurgeInstancesRequest: _TypeAlias = PurgeInstancesRequest # noqa: Y015 @@ -727,6 +819,7 @@ class RerunWorkflowFromEventRequest(_message.Message): INPUT_FIELD_NUMBER: _builtins.int OVERWRITEINPUT_FIELD_NUMBER: _builtins.int NEWCHILDWORKFLOWINSTANCEID_FIELD_NUMBER: _builtins.int + ROUTER_FIELD_NUMBER: _builtins.int sourceInstanceID: _builtins.str """sourceInstanceID is the workflow instance ID to rerun. Can be a top level instance, or child workflow instance. @@ -754,6 +847,12 @@ class RerunWorkflowFromEventRequest(_message.Message): the next Activity event. """ + @_builtins.property + def router(self) -> _orchestration_pb2.TaskRouter: + """router optionally routes this operation to the workflow instance owned + by another app. sourceAppID is stamped by the sidecar, not the client. + """ + def __init__( self, *, @@ -763,19 +862,24 @@ class RerunWorkflowFromEventRequest(_message.Message): input: _wrappers_pb2.StringValue | None = ..., overwriteInput: _builtins.bool = ..., newChildWorkflowInstanceID: _builtins.str | None = ..., + router: _orchestration_pb2.TaskRouter | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["_newChildWorkflowInstanceID", b"_newChildWorkflowInstanceID", "_newInstanceID", b"_newInstanceID", "input", b"input", "newChildWorkflowInstanceID", b"newChildWorkflowInstanceID", "newInstanceID", b"newInstanceID"] # noqa: Y015 + _HasFieldArgType: _TypeAlias = _typing.Literal["_newChildWorkflowInstanceID", b"_newChildWorkflowInstanceID", "_newInstanceID", b"_newInstanceID", "_router", b"_router", "input", b"input", "newChildWorkflowInstanceID", b"newChildWorkflowInstanceID", "newInstanceID", b"newInstanceID", "router", b"router"] # noqa: Y015 def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["_newChildWorkflowInstanceID", b"_newChildWorkflowInstanceID", "_newInstanceID", b"_newInstanceID", "eventID", b"eventID", "input", b"input", "newChildWorkflowInstanceID", b"newChildWorkflowInstanceID", "newInstanceID", b"newInstanceID", "overwriteInput", b"overwriteInput", "sourceInstanceID", b"sourceInstanceID"] # noqa: Y015 + _ClearFieldArgType: _TypeAlias = _typing.Literal["_newChildWorkflowInstanceID", b"_newChildWorkflowInstanceID", "_newInstanceID", b"_newInstanceID", "_router", b"_router", "eventID", b"eventID", "input", b"input", "newChildWorkflowInstanceID", b"newChildWorkflowInstanceID", "newInstanceID", b"newInstanceID", "overwriteInput", b"overwriteInput", "router", b"router", "sourceInstanceID", b"sourceInstanceID"] # noqa: Y015 def ClearField(self, field_name: _ClearFieldArgType) -> None: ... _WhichOneofReturnType__newChildWorkflowInstanceID: _TypeAlias = _typing.Literal["newChildWorkflowInstanceID"] # noqa: Y015 _WhichOneofArgType__newChildWorkflowInstanceID: _TypeAlias = _typing.Literal["_newChildWorkflowInstanceID", b"_newChildWorkflowInstanceID"] # noqa: Y015 _WhichOneofReturnType__newInstanceID: _TypeAlias = _typing.Literal["newInstanceID"] # noqa: Y015 _WhichOneofArgType__newInstanceID: _TypeAlias = _typing.Literal["_newInstanceID", b"_newInstanceID"] # noqa: Y015 + _WhichOneofReturnType__router: _TypeAlias = _typing.Literal["router"] # noqa: Y015 + _WhichOneofArgType__router: _TypeAlias = _typing.Literal["_router", b"_router"] # noqa: Y015 @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__newChildWorkflowInstanceID) -> _WhichOneofReturnType__newChildWorkflowInstanceID | None: ... @_typing.overload def WhichOneof(self, oneof_group: _WhichOneofArgType__newInstanceID) -> _WhichOneofReturnType__newInstanceID | None: ... + @_typing.overload + def WhichOneof(self, oneof_group: _WhichOneofArgType__router) -> _WhichOneofReturnType__router | None: ... Global___RerunWorkflowFromEventRequest: _TypeAlias = RerunWorkflowFromEventRequest # noqa: Y015 diff --git a/dapr/ext/workflow/aio/dapr_workflow_client.py b/dapr/ext/workflow/aio/dapr_workflow_client.py index 8a6072cf2..552ec35f2 100644 --- a/dapr/ext/workflow/aio/dapr_workflow_client.py +++ b/dapr/ext/workflow/aio/dapr_workflow_client.py @@ -98,6 +98,7 @@ async def schedule_new_workflow( instance_id: Optional[str] = None, start_at: Optional[datetime] = None, reuse_id_policy: Optional[client.WorkflowIdReusePolicy] = None, + app_id: Optional[str] = None, ) -> str: """Schedules a new workflow instance for execution. @@ -113,6 +114,10 @@ async def schedule_new_workflow( reuse_id_policy: Deprecated and has no effect; it will be removed in a future release. A workflow instance ID can always be reused once the existing instance with that ID has reached a terminal state (e.g. COMPLETED, FAILED, or TERMINATED). + app_id: The optional ID of another app to schedule the workflow on. The target + app's WorkflowAccessPolicy governs whether this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: The ID of the scheduled workflow instance. @@ -138,10 +143,15 @@ async def schedule_new_workflow( instance_id=instance_id, start_at=start_at, reuse_id_policy=reuse_id_policy, + app_id=app_id, ) async def get_workflow_state( - self, instance_id: str, *, fetch_payloads: bool = True + self, + instance_id: str, + *, + fetch_payloads: bool = True, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: """Fetches runtime state for the specified workflow instance. @@ -149,6 +159,11 @@ async def get_workflow_state( instance_id: The unique ID of the workflow instance to fetch. fetch_payloads: If true, fetches the input, output payloads and custom status for the workflow instance. Defaults to true. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: The current state of the workflow instance, or None if the workflow instance does not @@ -157,7 +172,9 @@ async def get_workflow_state( """ try: state = await self.__obj.get_orchestration_state( - instance_id, fetch_payloads=fetch_payloads + instance_id, + fetch_payloads=fetch_payloads, + app_id=app_id, ) return WorkflowState(state) if state else None except AioRpcError as error: @@ -170,7 +187,12 @@ async def get_workflow_state( raise async def wait_for_workflow_start( - self, instance_id: str, *, fetch_payloads: bool = False, timeout_in_seconds: int = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = False, + timeout_in_seconds: int = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: """Waits for a workflow to start running and returns a WorkflowState object that contains metadata about the started workflow. @@ -185,18 +207,31 @@ async def wait_for_workflow_start( the workflow instance. Defaults to false. timeout_in_seconds: The maximum time to wait for the workflow instance to start running. Defaults to meaning no timeout. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: WorkflowState record that describes the workflow instance and its execution status. If the specified workflow isn't found, the WorkflowState.Exists value will be false. """ state = await self.__obj.wait_for_orchestration_start( - instance_id, fetch_payloads=fetch_payloads, timeout=timeout_in_seconds + instance_id, + fetch_payloads=fetch_payloads, + timeout=timeout_in_seconds, + app_id=app_id, ) return WorkflowState(state) if state else None async def wait_for_workflow_completion( - self, instance_id: str, *, fetch_payloads: bool = True, timeout_in_seconds: int = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = True, + timeout_in_seconds: int = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: """Waits for a workflow to complete and returns a WorkflowState object that contains metadata about the started instance. @@ -219,17 +254,30 @@ async def wait_for_workflow_completion( for the workflow instance. Defaults to true. timeout_in_seconds: The maximum time in seconds to wait for the workflow instance to complete. Defaults to 0 seconds, meaning no timeout. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: WorkflowState record that describes the workflow instance and its execution status. """ state = await self.__obj.wait_for_orchestration_completion( - instance_id, fetch_payloads=fetch_payloads, timeout=timeout_in_seconds + instance_id, + fetch_payloads=fetch_payloads, + timeout=timeout_in_seconds, + app_id=app_id, ) return WorkflowState(state) if state else None async def raise_workflow_event( - self, instance_id: str, event_name: str, *, data: Optional[Any] = None + self, + instance_id: str, + event_name: str, + *, + data: Optional[Any] = None, + app_id: Optional[str] = None, ) -> None: """Sends an event notification message to a waiting workflow instance. In order to handle the event, the target workflow instance must be waiting for an @@ -251,11 +299,23 @@ async def raise_workflow_event( instance_id: The ID of the workflow instance that will handle the event. event_name: The name of the event. Event names are case-insensitive. data: The serializable data payload to include with the event. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return await self.__obj.raise_orchestration_event(instance_id, event_name, data=data) + return await self.__obj.raise_orchestration_event( + instance_id, event_name, data=data, app_id=app_id + ) async def terminate_workflow( - self, instance_id: str, *, output: Optional[Any] = None, recursive: bool = True + self, + instance_id: str, + *, + output: Optional[Any] = None, + recursive: bool = True, + app_id: Optional[str] = None, ) -> None: """Terminates a running workflow instance and updates its runtime status to WorkflowRuntimeStatus.Terminated This method internally enqueues a "terminate" message in @@ -275,34 +335,73 @@ async def terminate_workflow( instance_id: The ID of the workflow instance to terminate. output: The optional output to set for the terminated workflow instance. recursive: The optional flag to terminate all child workflows. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ return await self.__obj.terminate_orchestration( - instance_id, output=output, recursive=recursive + instance_id, + output=output, + recursive=recursive, + app_id=app_id, ) - async def pause_workflow(self, instance_id: str) -> None: + async def pause_workflow( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ) -> None: """Suspends a workflow instance, halting processing of it until resume_workflow is used to resume the workflow. Args: instance_id: The instance ID of the workflow to suspend. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return await self.__obj.suspend_orchestration(instance_id) + return await self.__obj.suspend_orchestration(instance_id, app_id=app_id) - async def resume_workflow(self, instance_id: str) -> None: + async def resume_workflow( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ) -> None: """Resumes a workflow instance that was suspended via pause_workflow. Args: instance_id: The instance ID of the workflow to resume. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return await self.__obj.resume_orchestration(instance_id) + return await self.__obj.resume_orchestration(instance_id, app_id=app_id) - async def purge_workflow(self, instance_id: str, recursive: bool = True) -> None: + async def purge_workflow( + self, + instance_id: str, + recursive: bool = True, + *, + app_id: Optional[str] = None, + ) -> None: """Purge data from a workflow instance. Args: instance_id: The instance ID of the workflow to purge. recursive: The optional flag to also purge data from all child workflows. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return await self.__obj.purge_orchestration(instance_id, recursive) + return await self.__obj.purge_orchestration(instance_id, recursive, app_id=app_id) diff --git a/dapr/ext/workflow/dapr_workflow_client.py b/dapr/ext/workflow/dapr_workflow_client.py index dca65c200..02be04f88 100644 --- a/dapr/ext/workflow/dapr_workflow_client.py +++ b/dapr/ext/workflow/dapr_workflow_client.py @@ -100,6 +100,7 @@ def schedule_new_workflow( instance_id: Optional[str] = None, start_at: Optional[datetime] = None, reuse_id_policy: Optional[client.WorkflowIdReusePolicy] = None, + app_id: Optional[str] = None, ) -> str: """Schedules a new workflow instance for execution. @@ -115,6 +116,10 @@ def schedule_new_workflow( reuse_id_policy: Deprecated and has no effect; it will be removed in a future release. A workflow instance ID can always be reused once the existing instance with that ID has reached a terminal state (e.g. COMPLETED, FAILED, or TERMINATED). + app_id: The optional ID of another app to schedule the workflow on. The target + app's WorkflowAccessPolicy governs whether this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: The ID of the scheduled workflow instance. @@ -140,10 +145,15 @@ def schedule_new_workflow( instance_id=instance_id, start_at=start_at, reuse_id_policy=reuse_id_policy, + app_id=app_id, ) def get_workflow_state( - self, instance_id: str, *, fetch_payloads: bool = True + self, + instance_id: str, + *, + fetch_payloads: bool = True, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: """Fetches runtime state for the specified workflow instance. @@ -151,6 +161,11 @@ def get_workflow_state( instance_id: The unique ID of the workflow instance to fetch. fetch_payloads: If true, fetches the input, output payloads and custom status for the workflow instance. Defaults to true. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: The current state of the workflow instance, or None if the workflow instance does not @@ -158,7 +173,11 @@ def get_workflow_state( """ try: - state = self.__obj.get_orchestration_state(instance_id, fetch_payloads=fetch_payloads) + state = self.__obj.get_orchestration_state( + instance_id, + fetch_payloads=fetch_payloads, + app_id=app_id, + ) return WorkflowState(state) if state else None except RpcError as error: if 'no such instance exists' in error.details(): @@ -170,7 +189,12 @@ def get_workflow_state( raise def wait_for_workflow_start( - self, instance_id: str, *, fetch_payloads: bool = False, timeout_in_seconds: int = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = False, + timeout_in_seconds: int = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: """Waits for a workflow to start running and returns a WorkflowState object that contains metadata about the started workflow. @@ -185,18 +209,31 @@ def wait_for_workflow_start( the workflow instance. Defaults to false. timeout_in_seconds: The maximum time to wait for the workflow instance to start running. Defaults to meaning no timeout. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: WorkflowState record that describes the workflow instance and its execution status. If the specified workflow isn't found, the WorkflowState.Exists value will be false. """ state = self.__obj.wait_for_orchestration_start( - instance_id, fetch_payloads=fetch_payloads, timeout=timeout_in_seconds + instance_id, + fetch_payloads=fetch_payloads, + timeout=timeout_in_seconds, + app_id=app_id, ) return WorkflowState(state) if state else None def wait_for_workflow_completion( - self, instance_id: str, *, fetch_payloads: bool = True, timeout_in_seconds: int = 0 + self, + instance_id: str, + *, + fetch_payloads: bool = True, + timeout_in_seconds: int = 0, + app_id: Optional[str] = None, ) -> Optional[WorkflowState]: """Waits for a workflow to complete and returns a WorkflowState object that contains metadata about the started instance. @@ -219,17 +256,30 @@ def wait_for_workflow_completion( for the workflow instance. Defaults to true. timeout_in_seconds: The maximum time in seconds to wait for the workflow instance to complete. Defaults to 0 seconds, meaning no timeout. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. Returns: WorkflowState record that describes the workflow instance and its execution status. """ state = self.__obj.wait_for_orchestration_completion( - instance_id, fetch_payloads=fetch_payloads, timeout=timeout_in_seconds + instance_id, + fetch_payloads=fetch_payloads, + timeout=timeout_in_seconds, + app_id=app_id, ) return WorkflowState(state) if state else None def raise_workflow_event( - self, instance_id: str, event_name: str, *, data: Optional[Any] = None + self, + instance_id: str, + event_name: str, + *, + data: Optional[Any] = None, + app_id: Optional[str] = None, ): """Sends an event notification message to a waiting workflow instance. In order to handle the event, the target workflow instance must be waiting for an @@ -251,11 +301,23 @@ def raise_workflow_event( instance_id: The ID of the workflow instance that will handle the event. event_name: The name of the event. Event names are case-insensitive. data: The serializable data payload to include with the event. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return self.__obj.raise_orchestration_event(instance_id, event_name, data=data) + return self.__obj.raise_orchestration_event( + instance_id, event_name, data=data, app_id=app_id + ) def terminate_workflow( - self, instance_id: str, *, output: Optional[Any] = None, recursive: bool = True + self, + instance_id: str, + *, + output: Optional[Any] = None, + recursive: bool = True, + app_id: Optional[str] = None, ): """Terminates a running workflow instance and updates its runtime status to WorkflowRuntimeStatus.Terminated This method internally enqueues a "terminate" message in @@ -275,35 +337,76 @@ def terminate_workflow( instance_id: The ID of the workflow instance to terminate. output: The optional output to set for the terminated workflow instance. recursive: The optional flag to terminate all child workflows. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return self.__obj.terminate_orchestration(instance_id, output=output, recursive=recursive) + return self.__obj.terminate_orchestration( + instance_id, + output=output, + recursive=recursive, + app_id=app_id, + ) - def pause_workflow(self, instance_id: str): + def pause_workflow( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ): """Suspends a workflow instance, halting processing of it until resume_workflow is used to resume the workflow. Args: instance_id: The instance ID of the workflow to suspend. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return self.__obj.suspend_orchestration(instance_id) + return self.__obj.suspend_orchestration(instance_id, app_id=app_id) - def resume_workflow(self, instance_id: str): + def resume_workflow( + self, + instance_id: str, + *, + app_id: Optional[str] = None, + ): """Resumes a workflow instance that was suspended via pause_workflow. Args: instance_id: The instance ID of the workflow to resume. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return self.__obj.resume_orchestration(instance_id) + return self.__obj.resume_orchestration(instance_id, app_id=app_id) - def purge_workflow(self, instance_id: str, recursive: bool = True): + def purge_workflow( + self, + instance_id: str, + recursive: bool = True, + *, + app_id: Optional[str] = None, + ): """Purge data from a workflow instance. Args: instance_id: The instance ID of the workflow to purge. recursive: The optional flag to also purge data from all child workflows. + app_id: The optional ID of the app hosting the workflow instance, when it is + hosted by a different app. The target app's WorkflowAccessPolicy governs whether + this operation is permitted. + Requires a Dapr runtime with cross-app workflow support; older runtimes + ignore app_id and apply the operation to the local app. """ - return self.__obj.purge_orchestration(instance_id, recursive) + return self.__obj.purge_orchestration(instance_id, recursive, app_id=app_id) def close(self): """Closes the gRPC connection used by the client.""" diff --git a/tests/ext/workflow/durabletask/test_client_routing.py b/tests/ext/workflow/durabletask/test_client_routing.py new file mode 100644 index 000000000..414f26da0 --- /dev/null +++ b/tests/ext/workflow/durabletask/test_client_routing.py @@ -0,0 +1,195 @@ +# Copyright 2026 The Dapr Authors +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for cross-app routing (TaskRouter) support in the durabletask clients.""" + +from unittest.mock import AsyncMock, MagicMock, patch + +import dapr.ext.workflow._durabletask.internal.protos as pb +from dapr.ext.workflow._durabletask.aio.client import AsyncTaskHubGrpcClient +from dapr.ext.workflow._durabletask.client import TaskHubGrpcClient, new_task_router + +TARGET_APP_ID = 'appB' +INSTANCE_ID = 'instance001' + + +def _make_sync_client() -> TaskHubGrpcClient: + with patch('grpc.insecure_channel'): + hub_client = TaskHubGrpcClient(host_address='localhost:1') + stub = MagicMock() + stub.StartInstance.return_value = pb.CreateInstanceResponse(instanceId=INSTANCE_ID) + stub.GetInstance.return_value = pb.GetInstanceResponse(exists=False) + stub.WaitForInstanceStart.return_value = pb.GetInstanceResponse(exists=False) + stub.WaitForInstanceCompletion.return_value = pb.GetInstanceResponse(exists=False) + hub_client._stub = stub + return hub_client + + +def _make_async_client() -> AsyncTaskHubGrpcClient: + hub_client = AsyncTaskHubGrpcClient(host_address='localhost:1') + stub = AsyncMock() + stub.StartInstance.return_value = pb.CreateInstanceResponse(instanceId=INSTANCE_ID) + stub.GetInstance.return_value = pb.GetInstanceResponse(exists=False) + stub.WaitForInstanceStart.return_value = pb.GetInstanceResponse(exists=False) + stub.WaitForInstanceCompletion.return_value = pb.GetInstanceResponse(exists=False) + hub_client._stub = stub + return hub_client + + +def _sent_request(stub_method): + return stub_method.call_args[0][0] + + +def _assert_routed(req): + assert req.HasField('router') + assert req.router.targetAppID == TARGET_APP_ID + assert req.router.HasField('targetAppID') + assert req.router.sourceAppID == '' + assert not req.router.HasField('targetAppNamespace') + + +def test_new_task_router_none_when_no_app_id(): + assert new_task_router(None) is None + + +def test_new_task_router_target_app_only(): + router = new_task_router(TARGET_APP_ID) + assert router.targetAppID == TARGET_APP_ID + assert not router.HasField('targetAppNamespace') + assert router.sourceAppID == '' + + +def test_sync_client_sets_router_when_app_id_given(): + hub_client = _make_sync_client() + stub = hub_client._stub + + hub_client.schedule_new_orchestration('wf', app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.StartInstance)) + + hub_client.get_orchestration_state(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.GetInstance)) + + hub_client.wait_for_orchestration_start(INSTANCE_ID, timeout=1, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.WaitForInstanceStart)) + + hub_client.wait_for_orchestration_completion(INSTANCE_ID, timeout=1, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.WaitForInstanceCompletion)) + + hub_client.raise_orchestration_event(INSTANCE_ID, 'event', app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.RaiseEvent)) + + hub_client.terminate_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.TerminateInstance)) + + hub_client.suspend_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.SuspendInstance)) + + hub_client.resume_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.ResumeInstance)) + + hub_client.purge_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.PurgeInstances)) + + +def test_sync_client_no_router_when_app_id_none(): + hub_client = _make_sync_client() + stub = hub_client._stub + + hub_client.schedule_new_orchestration('wf') + assert not _sent_request(stub.StartInstance).HasField('router') + + hub_client.get_orchestration_state(INSTANCE_ID) + assert not _sent_request(stub.GetInstance).HasField('router') + + hub_client.wait_for_orchestration_start(INSTANCE_ID, timeout=1) + assert not _sent_request(stub.WaitForInstanceStart).HasField('router') + + hub_client.wait_for_orchestration_completion(INSTANCE_ID, timeout=1) + assert not _sent_request(stub.WaitForInstanceCompletion).HasField('router') + + hub_client.raise_orchestration_event(INSTANCE_ID, 'event') + assert not _sent_request(stub.RaiseEvent).HasField('router') + + hub_client.terminate_orchestration(INSTANCE_ID) + assert not _sent_request(stub.TerminateInstance).HasField('router') + + hub_client.suspend_orchestration(INSTANCE_ID) + assert not _sent_request(stub.SuspendInstance).HasField('router') + + hub_client.resume_orchestration(INSTANCE_ID) + assert not _sent_request(stub.ResumeInstance).HasField('router') + + hub_client.purge_orchestration(INSTANCE_ID) + assert not _sent_request(stub.PurgeInstances).HasField('router') + + +async def test_async_client_sets_router_when_app_id_given(): + hub_client = _make_async_client() + stub = hub_client._stub + + await hub_client.schedule_new_orchestration('wf', app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.StartInstance)) + + await hub_client.get_orchestration_state(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.GetInstance)) + + await hub_client.wait_for_orchestration_start(INSTANCE_ID, timeout=1, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.WaitForInstanceStart)) + + await hub_client.wait_for_orchestration_completion(INSTANCE_ID, timeout=1, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.WaitForInstanceCompletion)) + + await hub_client.raise_orchestration_event(INSTANCE_ID, 'event', app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.RaiseEvent)) + + await hub_client.terminate_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.TerminateInstance)) + + await hub_client.suspend_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.SuspendInstance)) + + await hub_client.resume_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.ResumeInstance)) + + await hub_client.purge_orchestration(INSTANCE_ID, app_id=TARGET_APP_ID) + _assert_routed(_sent_request(stub.PurgeInstances)) + + +async def test_async_client_no_router_when_app_id_none(): + hub_client = _make_async_client() + stub = hub_client._stub + + await hub_client.schedule_new_orchestration('wf') + assert not _sent_request(stub.StartInstance).HasField('router') + + await hub_client.get_orchestration_state(INSTANCE_ID) + assert not _sent_request(stub.GetInstance).HasField('router') + + await hub_client.wait_for_orchestration_start(INSTANCE_ID, timeout=1) + assert not _sent_request(stub.WaitForInstanceStart).HasField('router') + + await hub_client.wait_for_orchestration_completion(INSTANCE_ID, timeout=1) + assert not _sent_request(stub.WaitForInstanceCompletion).HasField('router') + + await hub_client.raise_orchestration_event(INSTANCE_ID, 'event') + assert not _sent_request(stub.RaiseEvent).HasField('router') + + await hub_client.terminate_orchestration(INSTANCE_ID) + assert not _sent_request(stub.TerminateInstance).HasField('router') + + await hub_client.suspend_orchestration(INSTANCE_ID) + assert not _sent_request(stub.SuspendInstance).HasField('router') + + await hub_client.resume_orchestration(INSTANCE_ID) + assert not _sent_request(stub.ResumeInstance).HasField('router') + + await hub_client.purge_orchestration(INSTANCE_ID) + assert not _sent_request(stub.PurgeInstances).HasField('router') diff --git a/tests/ext/workflow/durabletask/test_orchestration_executor.py b/tests/ext/workflow/durabletask/test_orchestration_executor.py index cdbbbdee0..d6f164fd4 100644 --- a/tests/ext/workflow/durabletask/test_orchestration_executor.py +++ b/tests/ext/workflow/durabletask/test_orchestration_executor.py @@ -246,7 +246,7 @@ def orchestrator(ctx: task.OrchestrationContext, orchestrator_input): def test_schedule_activity_actions_router_without_app_id(): - """Tests that scheduleTask action contains correct router fields when app_id is specified""" + """Tests that the workflow action carries no target app ID when app_id is not specified""" def dummy_activity(ctx, _): pass @@ -274,12 +274,10 @@ def orchestrator(ctx: task.OrchestrationContext, _): action = actions[0] assert action.router.sourceAppID == 'source-app' assert action.router.targetAppID == '' - assert action.scheduleTask.router.sourceAppID == 'source-app' - assert action.scheduleTask.router.targetAppID == '' def test_schedule_activity_actions_router_with_app_id(): - """Tests that scheduleTask action contains correct router fields when app_id is specified""" + """Tests that the workflow action carries correct router fields when app_id is specified""" def dummy_activity(ctx, _): pass @@ -307,8 +305,6 @@ def orchestrator(ctx: task.OrchestrationContext, _): action = actions[0] assert action.router.sourceAppID == 'source-app' assert action.router.targetAppID == 'target-app' - assert action.scheduleTask.router.sourceAppID == 'source-app' - assert action.scheduleTask.router.targetAppID == 'target-app' def test_activity_task_completion(): @@ -771,7 +767,7 @@ def orchestrator(ctx: task.OrchestrationContext, _): def test_create_sub_orchestration_actions_router_without_app_id(): - """Tests that createChildWorkflow action contains correct router fields when app_id is specified""" + """Tests that the workflow action carries no target app ID when app_id is not specified""" def suborchestrator(ctx: task.OrchestrationContext, _): pass @@ -801,12 +797,10 @@ def orchestrator(ctx: task.OrchestrationContext, _): action = actions[0] assert action.router.sourceAppID == 'source-app' assert action.router.targetAppID == '' - assert action.createChildWorkflow.router.sourceAppID == 'source-app' - assert action.createChildWorkflow.router.targetAppID == '' def test_create_sub_orchestration_actions_router_with_app_id(): - """Tests that createChildWorkflow action contains correct router fields when app_id is specified""" + """Tests that the workflow action carries correct router fields when app_id is specified""" def suborchestrator(ctx: task.OrchestrationContext, _): pass @@ -836,8 +830,6 @@ def orchestrator(ctx: task.OrchestrationContext, _): action = actions[0] assert action.router.sourceAppID == 'source-app' assert action.router.targetAppID == 'target-app' - assert action.createChildWorkflow.router.sourceAppID == 'source-app' - assert action.createChildWorkflow.router.targetAppID == 'target-app' def test_sub_orchestration_task_failed(): diff --git a/tests/ext/workflow/test_workflow_client.py b/tests/ext/workflow/test_workflow_client.py index 257e72b35..c19eb6a74 100644 --- a/tests/ext/workflow/test_workflow_client.py +++ b/tests/ext/workflow/test_workflow_client.py @@ -51,6 +51,10 @@ def details(self): class FakeTaskHubGrpcClient: def __init__(self): self.last_scheduled_workflow_name = None + self.last_app_id = None + + def _record_router(self, app_id): + self.last_app_id = app_id def schedule_new_orchestration( self, @@ -59,11 +63,14 @@ def schedule_new_orchestration( instance_id, start_at, reuse_id_policy: Union[client.WorkflowIdReusePolicy, None] = None, + app_id=None, ): self.last_scheduled_workflow_name = workflow + self._record_router(app_id) return mock_schedule_result - def get_orchestration_state(self, instance_id, fetch_payloads): + def get_orchestration_state(self, instance_id, fetch_payloads, app_id=None): + self._record_router(app_id) if wf_status == 'not-found': raise SimulatedRpcError(code='UNKNOWN', details='no such instance exists') elif wf_status == 'found': @@ -73,31 +80,48 @@ def get_orchestration_state(self, instance_id, fetch_payloads): else: raise SimulatedRpcError(code='UNKNOWN', details='unknown error') - def wait_for_orchestration_start(self, instance_id, fetch_payloads, timeout): + def wait_for_orchestration_start(self, instance_id, fetch_payloads, timeout, app_id=None): + self._record_router(app_id) return self._inner_get_orchestration_state(instance_id, client.OrchestrationStatus.RUNNING) - def wait_for_orchestration_completion(self, instance_id, fetch_payloads, timeout): + def wait_for_orchestration_completion(self, instance_id, fetch_payloads, timeout, app_id=None): + self._record_router(app_id) return self._inner_get_orchestration_state( instance_id, client.OrchestrationStatus.COMPLETED ) def raise_orchestration_event( - self, instance_id: str, event_name: str, *, data: Union[Any, None] = None + self, + instance_id: str, + event_name: str, + *, + data: Union[Any, None] = None, + app_id=None, ): + self._record_router(app_id) return mock_raise_event_result def terminate_orchestration( - self, instance_id: str, *, output: Union[Any, None] = None, recursive: bool = True + self, + instance_id: str, + *, + output: Union[Any, None] = None, + recursive: bool = True, + app_id=None, ): + self._record_router(app_id) return mock_terminate_result - def suspend_orchestration(self, instance_id: str): + def suspend_orchestration(self, instance_id: str, *, app_id=None): + self._record_router(app_id) return mock_suspend_result - def resume_orchestration(self, instance_id: str): + def resume_orchestration(self, instance_id: str, *, app_id=None): + self._record_router(app_id) return mock_resume_result - def purge_orchestration(self, instance_id: str, recursive: bool = True): + def purge_orchestration(self, instance_id: str, recursive: bool = True, *, app_id=None): + self._record_router(app_id) return mock_purge_result def _inner_get_orchestration_state(self, instance_id, state: client.OrchestrationStatus): @@ -289,3 +313,60 @@ def test_client_functions(self): assert actual_purge_result == mock_purge_result actual_purge_result = wfClient.purge_workflow(instance_id=mock_instance_id) assert actual_purge_result == mock_purge_result + + +class WorkflowClientCrossAppTest(unittest.TestCase): + """Verifies app_id is forwarded to the underlying task hub client.""" + + target_app_id = 'appB' + + def _assert_forwarded(self, fake_client): + assert fake_client.last_app_id == self.target_app_id + + def test_cross_app_kwargs_are_forwarded(self): + fake_client = FakeTaskHubGrpcClient() + with mock.patch( + 'dapr.ext.workflow._durabletask.client.TaskHubGrpcClient', return_value=fake_client + ): + wfClient = DaprWorkflowClient() + routing = {'app_id': self.target_app_id} + + wfClient.schedule_new_workflow(workflow='my_registered_workflow', **routing) + self._assert_forwarded(fake_client) + + global wf_status + wf_status = 'found' + wfClient.get_workflow_state(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + wfClient.wait_for_workflow_start(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + wfClient.wait_for_workflow_completion(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + wfClient.raise_workflow_event( + instance_id=mock_instance_id, event_name='test_event', **routing + ) + self._assert_forwarded(fake_client) + + wfClient.terminate_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + wfClient.pause_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + wfClient.resume_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + wfClient.purge_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + def test_cross_app_kwargs_default_to_none(self): + fake_client = FakeTaskHubGrpcClient() + with mock.patch( + 'dapr.ext.workflow._durabletask.client.TaskHubGrpcClient', return_value=fake_client + ): + wfClient = DaprWorkflowClient() + wfClient.terminate_workflow(instance_id=mock_instance_id) + assert fake_client.last_app_id is None diff --git a/tests/ext/workflow/test_workflow_client_aio.py b/tests/ext/workflow/test_workflow_client_aio.py index 6bdf2d5be..b0e50ba45 100644 --- a/tests/ext/workflow/test_workflow_client_aio.py +++ b/tests/ext/workflow/test_workflow_client_aio.py @@ -51,6 +51,10 @@ def details(self): class FakeAsyncTaskHubGrpcClient: def __init__(self): self.last_scheduled_workflow_name = None + self.last_app_id = None + + def _record_router(self, app_id): + self.last_app_id = app_id async def schedule_new_orchestration( self, @@ -60,11 +64,14 @@ async def schedule_new_orchestration( instance_id, start_at, reuse_id_policy: Union[client.WorkflowIdReusePolicy, None] = None, + app_id=None, ): self.last_scheduled_workflow_name = workflow + self._record_router(app_id) return mock_schedule_result - async def get_orchestration_state(self, instance_id, *, fetch_payloads): + async def get_orchestration_state(self, instance_id, *, fetch_payloads, app_id=None): + self._record_router(app_id) if wf_status == 'not-found': raise SimulatedAioRpcError(code='UNKNOWN', details='no such instance exists') elif wf_status == 'found': @@ -74,31 +81,52 @@ async def get_orchestration_state(self, instance_id, *, fetch_payloads): else: raise SimulatedAioRpcError(code='UNKNOWN', details='unknown error') - async def wait_for_orchestration_start(self, instance_id, *, fetch_payloads, timeout): + async def wait_for_orchestration_start( + self, instance_id, *, fetch_payloads, timeout, app_id=None + ): + self._record_router(app_id) return self._inner_get_orchestration_state(instance_id, client.OrchestrationStatus.RUNNING) - async def wait_for_orchestration_completion(self, instance_id, *, fetch_payloads, timeout): + async def wait_for_orchestration_completion( + self, instance_id, *, fetch_payloads, timeout, app_id=None + ): + self._record_router(app_id) return self._inner_get_orchestration_state( instance_id, client.OrchestrationStatus.COMPLETED ) async def raise_orchestration_event( - self, instance_id: str, event_name: str, *, data: Union[Any, None] = None + self, + instance_id: str, + event_name: str, + *, + data: Union[Any, None] = None, + app_id=None, ): + self._record_router(app_id) return mock_raise_event_result async def terminate_orchestration( - self, instance_id: str, *, output: Union[Any, None] = None, recursive: bool = True + self, + instance_id: str, + *, + output: Union[Any, None] = None, + recursive: bool = True, + app_id=None, ): + self._record_router(app_id) return mock_terminate_result - async def suspend_orchestration(self, instance_id: str): + async def suspend_orchestration(self, instance_id: str, *, app_id=None): + self._record_router(app_id) return mock_suspend_result - async def resume_orchestration(self, instance_id: str): + async def resume_orchestration(self, instance_id: str, *, app_id=None): + self._record_router(app_id) return mock_resume_result - async def purge_orchestration(self, instance_id: str, recursive: bool = True): + async def purge_orchestration(self, instance_id: str, recursive: bool = True, *, app_id=None): + self._record_router(app_id) return mock_purge_result def _inner_get_orchestration_state(self, instance_id, state: client.OrchestrationStatus): @@ -295,3 +323,62 @@ async def test_client_functions(self): assert actual_purge_result == mock_purge_result actual_purge_result = await wfClient.purge_workflow(instance_id=mock_instance_id) assert actual_purge_result == mock_purge_result + + +class WorkflowClientAioCrossAppTest(unittest.IsolatedAsyncioTestCase): + """Verifies app_id is forwarded to the underlying async task hub client.""" + + target_app_id = 'appB' + + def _assert_forwarded(self, fake_client): + assert fake_client.last_app_id == self.target_app_id + + async def test_cross_app_kwargs_are_forwarded(self): + fake_client = FakeAsyncTaskHubGrpcClient() + with mock.patch( + 'dapr.ext.workflow._durabletask.aio.client.AsyncTaskHubGrpcClient', + return_value=fake_client, + ): + wfClient = DaprWorkflowClient() + routing = {'app_id': self.target_app_id} + + await wfClient.schedule_new_workflow(workflow='my_registered_workflow', **routing) + self._assert_forwarded(fake_client) + + global wf_status + wf_status = 'found' + await wfClient.get_workflow_state(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + await wfClient.wait_for_workflow_start(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + await wfClient.wait_for_workflow_completion(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + await wfClient.raise_workflow_event( + instance_id=mock_instance_id, event_name='test_event', **routing + ) + self._assert_forwarded(fake_client) + + await wfClient.terminate_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + await wfClient.pause_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + await wfClient.resume_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + await wfClient.purge_workflow(instance_id=mock_instance_id, **routing) + self._assert_forwarded(fake_client) + + async def test_cross_app_kwargs_default_to_none(self): + fake_client = FakeAsyncTaskHubGrpcClient() + with mock.patch( + 'dapr.ext.workflow._durabletask.aio.client.AsyncTaskHubGrpcClient', + return_value=fake_client, + ): + wfClient = DaprWorkflowClient() + await wfClient.terminate_workflow(instance_id=mock_instance_id) + assert fake_client.last_app_id is None diff --git a/tests/integration/apps/workflow_host.py b/tests/integration/apps/workflow_host.py new file mode 100644 index 000000000..57fa495db --- /dev/null +++ b/tests/integration/apps/workflow_host.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +""" +Copyright 2026 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Workflow host for cross-app integration tests. + +Registers a workflow that blocks on an external event so that every +client-level operation (get, pause, resume, raise event, terminate, purge) is +observable against a running instance. The runtime dials out to its sidecar +over gRPC, so unlike the actor and pubsub hosts this app serves no app channel +and daprd is started without an --app-port. +""" + +import signal +import threading +from typing import Any + +from dapr.ext.workflow import DaprWorkflowContext, WorkflowRuntime + +WORKFLOW_NAME = 'CrossAppWaitForEvent' +EVENT_NAME = 'Finish' + + +def wait_for_event_workflow(ctx: DaprWorkflowContext, wf_input: Any) -> Any: + """Blocks until EVENT_NAME arrives, then returns its payload.""" + payload = yield ctx.wait_for_external_event(EVENT_NAME) + return payload + + +def main() -> None: + runtime = WorkflowRuntime() + runtime.register_workflow(wait_for_event_workflow, name=WORKFLOW_NAME) + runtime.start() + + # The test drives everything through the sidecar, so this process just has + # to stay alive until it is torn down with the sidecar's process group. + stop = threading.Event() + signal.signal(signal.SIGTERM, lambda *_: stop.set()) + signal.signal(signal.SIGINT, lambda *_: stop.set()) + try: + stop.wait() + finally: + runtime.shutdown() + + +if __name__ == '__main__': + main() diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 3ea3c7eb1..28e790be2 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -109,9 +109,12 @@ def start_sidecar( self.clients.append(client) # /healthz/outbound (polled by DaprClient) only checks sidecar-side - # readiness. When we launched an app alongside the sidecar, also wait - # for /v1.0/healthz so invoke_method et al. don't race the app's server. - if app_cmd is not None: + # readiness. When the app serves an app channel, also wait for + # /v1.0/healthz so invoke_method et al. don't race the app's server. + # Keyed on app_port rather than app_cmd because some apps (workflow + # workers) dial out to the sidecar instead of listening, so they have + # no app channel for /v1.0/healthz to probe. + if app_port is not None: _wait_for_app_health(http_port) return client diff --git a/tests/integration/test_workflow_cross_app.py b/tests/integration/test_workflow_cross_app.py new file mode 100644 index 000000000..47a5710e6 --- /dev/null +++ b/tests/integration/test_workflow_cross_app.py @@ -0,0 +1,170 @@ +# -*- coding: utf-8 -*- + +""" +Copyright 2026 The Dapr Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +End-to-end tests for cross-app workflow client operations. + +Two sidecars are started: a host app that registers the workflow, and a caller +app that registers nothing. Every operation is issued from the caller's +DaprWorkflowClient with app_id pointing at the host, proving the target app ID +travels on the wire and the runtime routes to the owning app. + +Requires a daprd that supports cross-app workflow operations; against an older +runtime the app_id is ignored and the caller would act on its own app. +""" + +import time + +import pytest + +from dapr.ext.workflow import DaprWorkflowClient +from tests.integration.apps.workflow_host import EVENT_NAME, WORKFLOW_NAME + +pytestmark = pytest.mark.dapr_head + +HOST_APP_ID = 'wf-cross-app-host' +HOST_GRPC_PORT = 13541 +HOST_HTTP_PORT = 3541 +HOST_INTERNAL_GRPC_PORT = 13542 +HOST_METRICS_PORT = 9141 + +CALLER_APP_ID = 'wf-cross-app-caller' +CALLER_GRPC_PORT = 13551 +CALLER_HTTP_PORT = 3551 +CALLER_INTERNAL_GRPC_PORT = 13552 +CALLER_METRICS_PORT = 9151 + +WORKFLOW_READY_TIMEOUT = 30 +STATUS_TIMEOUT = 30 + + +@pytest.fixture(scope='module', autouse=True) +def sidecars(dapr_env, apps_dir): + """Starts the workflow host app and a caller app with its own sidecar.""" + dapr_env.start_sidecar( + app_id=HOST_APP_ID, + grpc_port=HOST_GRPC_PORT, + http_port=HOST_HTTP_PORT, + internal_grpc_port=HOST_INTERNAL_GRPC_PORT, + metrics_port=HOST_METRICS_PORT, + app_cmd=f'python3 {apps_dir / "workflow_host.py"}', + ) + dapr_env.start_sidecar( + app_id=CALLER_APP_ID, + grpc_port=CALLER_GRPC_PORT, + http_port=CALLER_HTTP_PORT, + internal_grpc_port=CALLER_INTERNAL_GRPC_PORT, + metrics_port=CALLER_METRICS_PORT, + ) + + +@pytest.fixture(scope='module') +def caller_client(): + """A workflow client bound to the caller sidecar, which hosts no workflows.""" + client = DaprWorkflowClient(port=str(CALLER_GRPC_PORT)) + try: + yield client + finally: + client.close() + + +@pytest.fixture(scope='module') +def host_client(): + """A workflow client bound to the host sidecar, used only to corroborate state.""" + client = DaprWorkflowClient(port=str(HOST_GRPC_PORT)) + try: + yield client + finally: + client.close() + + +def _schedule_on_host(caller_client: DaprWorkflowClient) -> str: + """Schedules the host's workflow from the caller and waits for it to run. + + The host worker registers its workflow asynchronously after its sidecar + reports ready, so scheduling is retried until the host has it. + """ + deadline = time.monotonic() + WORKFLOW_READY_TIMEOUT + last_error: Exception | None = None + while time.monotonic() < deadline: + try: + instance_id = caller_client.schedule_new_workflow( + workflow=WORKFLOW_NAME, app_id=HOST_APP_ID + ) + state = caller_client.wait_for_workflow_start( + instance_id, app_id=HOST_APP_ID, timeout_in_seconds=10 + ) + if state is not None: + return instance_id + except Exception as exc: # noqa: BLE001 - retried until the host is up + last_error = exc + time.sleep(0.5) + raise AssertionError(f'host app never accepted a cross-app schedule: {last_error}') + + +def _wait_for_status(client: DaprWorkflowClient, instance_id: str, expected: str) -> None: + deadline = time.monotonic() + STATUS_TIMEOUT + seen = None + while time.monotonic() < deadline: + state = client.get_workflow_state(instance_id, app_id=HOST_APP_ID) + seen = None if state is None else state.runtime_status.name + if seen == expected: + return + time.sleep(0.2) + raise AssertionError(f'expected status {expected}, last saw {seen}') + + +def test_cross_app_schedule_targets_the_host_app(caller_client, host_client): + """A workflow scheduled with app_id runs on the host, not on the caller.""" + instance_id = _schedule_on_host(caller_client) + + hosted = host_client.get_workflow_state(instance_id) + assert hosted is not None + assert hosted.name == WORKFLOW_NAME + + local_to_caller = caller_client.get_workflow_state(instance_id) + assert local_to_caller is None + + +def test_cross_app_pause_and_resume(caller_client): + """Pause and resume drive the remote instance through SUSPENDED and back.""" + instance_id = _schedule_on_host(caller_client) + + caller_client.pause_workflow(instance_id, app_id=HOST_APP_ID) + _wait_for_status(caller_client, instance_id, 'SUSPENDED') + + caller_client.resume_workflow(instance_id, app_id=HOST_APP_ID) + _wait_for_status(caller_client, instance_id, 'RUNNING') + + +def test_cross_app_raise_event_completes_and_purge_removes(caller_client, host_client): + """Raising the awaited event completes the remote workflow, then purge deletes it.""" + instance_id = _schedule_on_host(caller_client) + + caller_client.raise_workflow_event(instance_id, EVENT_NAME, data='finished', app_id=HOST_APP_ID) + state = caller_client.wait_for_workflow_completion( + instance_id, app_id=HOST_APP_ID, timeout_in_seconds=STATUS_TIMEOUT + ) + assert state is not None + assert state.runtime_status.name == 'COMPLETED' + + caller_client.purge_workflow(instance_id, app_id=HOST_APP_ID) + assert host_client.get_workflow_state(instance_id) is None + + +def test_cross_app_terminate(caller_client): + """Terminate stops the remote instance.""" + instance_id = _schedule_on_host(caller_client) + + caller_client.terminate_workflow(instance_id, app_id=HOST_APP_ID) + _wait_for_status(caller_client, instance_id, 'TERMINATED') diff --git a/tools/regen_durabletask_protos.sh b/tools/regen_durabletask_protos.sh index 4b9120f11..20b048eb1 100755 --- a/tools/regen_durabletask_protos.sh +++ b/tools/regen_durabletask_protos.sh @@ -15,7 +15,8 @@ # Regenerate Python protobuf/gRPC stubs for the vendored durabletask package. # -# Proto source files are fetched from the durabletask-protobuf repository. +# Proto source files are fetched from the durabletask-protobuf repository, or +# taken from a local checkout when DURABLETASK_PROTOBUF_DIR is set. # Generated output goes to dapr/ext/workflow/_durabletask/internal/ # # Prerequisites: uv sync --all-extras --group dev @@ -23,43 +24,78 @@ # Usage: # ./tools/regen_durabletask_protos.sh # DURABLETASK_PROTOBUF_BRANCH=v1.2.3 ./tools/regen_durabletask_protos.sh +# DURABLETASK_PROTOBUF_DIR=/path/to/durabletask-protobuf ./tools/regen_durabletask_protos.sh set -euo pipefail DURABLETASK_PROTOBUF_BRANCH=${DURABLETASK_PROTOBUF_BRANCH:-main} +DURABLETASK_PROTOBUF_DIR=${DURABLETASK_PROTOBUF_DIR:-} +proto_source_commit="" REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" OUTPUT_DIR="${REPO_ROOT}/dapr/ext/workflow/_durabletask/internal" PYTHON_PACKAGE="dapr.ext.workflow._durabletask.internal" -if type "curl" > /dev/null 2>&1; then - HTTP_REQUEST_CLI=curl -elif type "wget" > /dev/null 2>&1; then - HTTP_REQUEST_CLI=wget +if [ -n "$DURABLETASK_PROTOBUF_DIR" ]; then + if [ ! -d "${DURABLETASK_PROTOBUF_DIR}/protos" ]; then + echo "Error: ${DURABLETASK_PROTOBUF_DIR}/protos does not exist" + exit 1 + fi + echo "Using local durabletask-protobuf checkout at ${DURABLETASK_PROTOBUF_DIR}" + proto_dir="${DURABLETASK_PROTOBUF_DIR}/protos" + + # The recorded commit is only meaningful if the protos it names are the ones + # actually fed to protoc. Uncommitted or untracked proto changes would be + # baked into the stubs while PROTO_SOURCE_COMMIT_HASH pointed at HEAD, so the + # provenance would be a lie. Refuse instead: commit the proto change (or push + # it upstream) and rerun. + if [ -n "$(git -C "${DURABLETASK_PROTOBUF_DIR}" status --porcelain -- protos 2>/dev/null)" ]; then + echo "Error: ${DURABLETASK_PROTOBUF_DIR}/protos has uncommitted or untracked changes." + echo "The generated stubs would not match the commit recorded in PROTO_SOURCE_COMMIT_HASH." + git -C "${DURABLETASK_PROTOBUF_DIR}" status --short -- protos + exit 1 + fi + + proto_source_commit="$(git -C "${DURABLETASK_PROTOBUF_DIR}" rev-parse HEAD 2>/dev/null || true)" else - echo "Either curl or wget is required" - exit 1 -fi + if type "curl" > /dev/null 2>&1; then + HTTP_REQUEST_CLI=curl + elif type "wget" > /dev/null 2>&1; then + HTTP_REQUEST_CLI=wget + else + echo "Either curl or wget is required" + exit 1 + fi -tmp="$(mktemp -d)" -trap 'rm -rf "$tmp"' EXIT + tmp="$(mktemp -d)" + trap 'rm -rf "$tmp"' EXIT -url="https://github.com/dapr/durabletask-protobuf/archive/refs/heads/${DURABLETASK_PROTOBUF_BRANCH}.tar.gz" + url="https://github.com/dapr/durabletask-protobuf/archive/refs/heads/${DURABLETASK_PROTOBUF_BRANCH}.tar.gz" -echo "Downloading durabletask-protobuf from ${url}..." -pushd "$tmp" > /dev/null -if [ "$HTTP_REQUEST_CLI" == "curl" ]; then - curl -SsL "$url" -o - | tar --strip-components=1 -xzf - -else - wget -q -O - "$url" | tar --strip-components=1 -xzf - + echo "Downloading durabletask-protobuf from ${url}..." + pushd "$tmp" > /dev/null + if [ "$HTTP_REQUEST_CLI" == "curl" ]; then + curl -SsL "$url" -o - | tar --strip-components=1 -xzf - + else + wget -q -O - "$url" | tar --strip-components=1 -xzf - + fi + popd > /dev/null + + proto_dir="${tmp}/protos" + + # The tarball carries no git metadata, so resolve the branch head via the API. + api_url="https://api.github.com/repos/dapr/durabletask-protobuf/commits/${DURABLETASK_PROTOBUF_BRANCH}" + if [ "$HTTP_REQUEST_CLI" == "curl" ]; then + proto_source_commit="$(curl -SsL -H 'Accept: application/vnd.github.sha' "$api_url" 2>/dev/null || true)" + else + proto_source_commit="$(wget -q -O - --header='Accept: application/vnd.github.sha' "$api_url" 2>/dev/null || true)" + fi fi -popd > /dev/null # The .proto files live under protos/ in durabletask-protobuf and use bare # imports like: import "orchestration.proto" # # We use the protos directory as the single --proto_path so that bare imports # resolve correctly. Generated files land directly in the output directory. -proto_dir="${tmp}/protos" proto_files=() while IFS= read -r -d '' file; do @@ -129,5 +165,15 @@ for f in "${OUTPUT_DIR}"/*_pb2.py; do fi done +# Record which durabletask-protobuf commit produced these stubs. Without this +# the file is edited by hand and silently drifts from the generated code. +if [ -n "$proto_source_commit" ]; then + echo "$proto_source_commit" > "${OUTPUT_DIR}/PROTO_SOURCE_COMMIT_HASH" + echo "Recorded source commit ${proto_source_commit}" +else + echo "Warning: could not resolve the durabletask-protobuf commit;" \ + "update ${OUTPUT_DIR}/PROTO_SOURCE_COMMIT_HASH by hand" +fi + echo -e "\nDurableTask protobuf/gRPC stubs regenerated successfully!" echo "Output: ${OUTPUT_DIR}"