diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b671f00a3..1f5fae3d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -238,7 +238,7 @@ jobs: - run: uv add --dev --python 3.10 "googleapis-common-protos==1.70.0" - run: uv add --python 3.10 "protobuf<4" - run: uv sync --all-extras - - run: cargo install --locked nexgen --version 0.2.2 --features advanced --force + - run: cargo install --locked nexgen --version 0.2.3 --features advanced --force - run: poe build-develop - run: poe gen-protos - name: Check generation unchanged diff --git a/CHANGELOG.md b/CHANGELOG.md index be3444177..a3ca40991 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ to include examples, links to docs, or any other relevant information. ### Changed +- System Nexus Signal-with-Start Workflow operations now use the typed + `WorkflowOutboundInterceptor.start_signal_with_start_workflow` interception point instead of + the generic `WorkflowOutboundInterceptor.start_nexus_operation` method. + ### Deprecated ### :boom: Breaking Changes diff --git a/pyproject.toml b/pyproject.toml index d05d2f8c6..ec621ea69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -187,8 +187,13 @@ exclude = [ # Ignore generated code 'temporalio/api', 'temporalio/bridge/proto', + 'temporalio/nexus/system/workflow_service', ] +[[tool.mypy.overrides]] +module = "temporalio.nexus.system.workflow_service.*" +ignore_errors = true + [tool.pydocstyle] convention = "google" # https://github.com/PyCQA/pydocstyle/issues/363#issuecomment-625563088 diff --git a/scripts/gen_nexus_system_api.py b/scripts/gen_nexus_system_api.py index 82f40a8f0..b45616434 100644 --- a/scripts/gen_nexus_system_api.py +++ b/scripts/gen_nexus_system_api.py @@ -35,7 +35,7 @@ / "v1" / "request_response.proto" ) -NEX_GEN_VERSION = "0.2.2" +NEX_GEN_VERSION = "0.2.3" def nex_gen_command() -> list[str]: @@ -131,6 +131,7 @@ def generate_nexus_system_api() -> None: str(wit_path), str(wit_deps_dir), "--native-api", + "--system-nexus", "--support-file", str(python_support_path), "--descriptors", diff --git a/temporalio/bridge/Cargo.lock b/temporalio/bridge/Cargo.lock index 745d3b358..72f89d746 100644 --- a/temporalio/bridge/Cargo.lock +++ b/temporalio/bridge/Cargo.lock @@ -156,6 +156,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "bindgen" version = "0.72.1" @@ -539,7 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -923,7 +929,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -1512,7 +1518,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8edd1efdd8ab23ba9cb9ace3d9987a72663d5d7c9f74fa00b51d6213645cf6c" dependencies = [ - "base64", + "base64 0.22.1", "serde", ] @@ -1934,7 +1940,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2068,7 +2074,7 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -2154,7 +2160,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2213,7 +2219,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2554,7 +2560,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2587,7 +2593,7 @@ dependencies = [ "anyhow", "async-trait", "backon", - "base64", + "base64 0.23.1", "bon", "bytes", "derive_more", @@ -2692,7 +2698,7 @@ name = "temporalio-protos" version = "0.7.0" dependencies = [ "anyhow", - "base64", + "base64 0.23.1", "derive_more", "http", "pbjson", @@ -2926,7 +2932,7 @@ checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "axum", - "base64", + "base64 0.22.1", "bytes", "flate2", "h2", @@ -3381,7 +3387,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.py b/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.py index 64fa8a255..0cdc02c6b 100644 --- a/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.py +++ b/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.py @@ -45,7 +45,7 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n;temporal/sdk/core/workflow_commands/workflow_commands.proto\x12\x19\x63oresdk.workflow_commands\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a$temporal/api/common/v1/message.proto\x1a$temporal/api/enums/v1/workflow.proto\x1a%temporal/api/failure/v1/message.proto\x1a\'temporal/api/sdk/v1/user_metadata.proto\x1a,temporal/api/sdk/v1/event_group_marker.proto\x1a\x35temporal/sdk/core/child_workflow/child_workflow.proto\x1a#temporal/sdk/core/nexus/nexus.proto\x1a%temporal/sdk/core/common/common.proto"\xa9\x10\n\x0fWorkflowCommand\x12\x38\n\ruser_metadata\x18\x64 \x01(\x0b\x32!.temporal.api.sdk.v1.UserMetadata\x12\x42\n\x13\x65vent_group_markers\x18\x65 \x03(\x0b\x32%.temporal.api.sdk.v1.EventGroupMarker\x12<\n\x0bstart_timer\x18\x01 \x01(\x0b\x32%.coresdk.workflow_commands.StartTimerH\x00\x12H\n\x11schedule_activity\x18\x02 \x01(\x0b\x32+.coresdk.workflow_commands.ScheduleActivityH\x00\x12\x42\n\x10respond_to_query\x18\x03 \x01(\x0b\x32&.coresdk.workflow_commands.QueryResultH\x00\x12S\n\x17request_cancel_activity\x18\x04 \x01(\x0b\x32\x30.coresdk.workflow_commands.RequestCancelActivityH\x00\x12>\n\x0c\x63\x61ncel_timer\x18\x05 \x01(\x0b\x32&.coresdk.workflow_commands.CancelTimerH\x00\x12[\n\x1b\x63omplete_workflow_execution\x18\x06 \x01(\x0b\x32\x34.coresdk.workflow_commands.CompleteWorkflowExecutionH\x00\x12S\n\x17\x66\x61il_workflow_execution\x18\x07 \x01(\x0b\x32\x30.coresdk.workflow_commands.FailWorkflowExecutionH\x00\x12g\n"continue_as_new_workflow_execution\x18\x08 \x01(\x0b\x32\x39.coresdk.workflow_commands.ContinueAsNewWorkflowExecutionH\x00\x12W\n\x19\x63\x61ncel_workflow_execution\x18\t \x01(\x0b\x32\x32.coresdk.workflow_commands.CancelWorkflowExecutionH\x00\x12\x45\n\x10set_patch_marker\x18\n \x01(\x0b\x32).coresdk.workflow_commands.SetPatchMarkerH\x00\x12`\n\x1estart_child_workflow_execution\x18\x0b \x01(\x0b\x32\x36.coresdk.workflow_commands.StartChildWorkflowExecutionH\x00\x12\x62\n\x1f\x63\x61ncel_child_workflow_execution\x18\x0c \x01(\x0b\x32\x37.coresdk.workflow_commands.CancelChildWorkflowExecutionH\x00\x12w\n*request_cancel_external_workflow_execution\x18\r \x01(\x0b\x32\x41.coresdk.workflow_commands.RequestCancelExternalWorkflowExecutionH\x00\x12h\n"signal_external_workflow_execution\x18\x0e \x01(\x0b\x32:.coresdk.workflow_commands.SignalExternalWorkflowExecutionH\x00\x12Q\n\x16\x63\x61ncel_signal_workflow\x18\x0f \x01(\x0b\x32/.coresdk.workflow_commands.CancelSignalWorkflowH\x00\x12S\n\x17schedule_local_activity\x18\x10 \x01(\x0b\x32\x30.coresdk.workflow_commands.ScheduleLocalActivityH\x00\x12^\n\x1drequest_cancel_local_activity\x18\x11 \x01(\x0b\x32\x35.coresdk.workflow_commands.RequestCancelLocalActivityH\x00\x12\x66\n!upsert_workflow_search_attributes\x18\x12 \x01(\x0b\x32\x39.coresdk.workflow_commands.UpsertWorkflowSearchAttributesH\x00\x12Y\n\x1amodify_workflow_properties\x18\x13 \x01(\x0b\x32\x33.coresdk.workflow_commands.ModifyWorkflowPropertiesH\x00\x12\x44\n\x0fupdate_response\x18\x14 \x01(\x0b\x32).coresdk.workflow_commands.UpdateResponseH\x00\x12U\n\x18schedule_nexus_operation\x18\x15 \x01(\x0b\x32\x31.coresdk.workflow_commands.ScheduleNexusOperationH\x00\x12`\n\x1erequest_cancel_nexus_operation\x18\x16 \x01(\x0b\x32\x36.coresdk.workflow_commands.RequestCancelNexusOperationH\x00\x42\t\n\x07variant"S\n\nStartTimer\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x38\n\x15start_to_fire_timeout\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration"\x1a\n\x0b\x43\x61ncelTimer\x12\x0b\n\x03seq\x18\x01 \x01(\r"\xb8\x06\n\x10ScheduleActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x13\n\x0b\x61\x63tivity_id\x18\x02 \x01(\t\x12\x15\n\ractivity_type\x18\x03 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12I\n\x07headers\x18\x06 \x03(\x0b\x32\x38.coresdk.workflow_commands.ScheduleActivity.HeadersEntry\x12\x32\n\targuments\x18\x07 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12<\n\x19schedule_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\n \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\x0b \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\x0c \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12N\n\x11\x63\x61ncellation_type\x18\r \x01(\x0e\x32\x33.coresdk.workflow_commands.ActivityCancellationType\x12\x1e\n\x16\x64o_not_eagerly_execute\x18\x0e \x01(\x08\x12;\n\x11versioning_intent\x18\x0f \x01(\x0e\x32 .coresdk.common.VersioningIntent\x12\x32\n\x08priority\x18\x10 \x01(\x0b\x32 .temporal.api.common.v1.Priority\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"\xee\x05\n\x15ScheduleLocalActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x13\n\x0b\x61\x63tivity_id\x18\x02 \x01(\t\x12\x15\n\ractivity_type\x18\x03 \x01(\t\x12\x0f\n\x07\x61ttempt\x18\x04 \x01(\r\x12:\n\x16original_schedule_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12N\n\x07headers\x18\x06 \x03(\x0b\x32=.coresdk.workflow_commands.ScheduleLocalActivity.HeadersEntry\x12\x32\n\targuments\x18\x07 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12<\n\x19schedule_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\n \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\x0b \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x38\n\x15local_retry_threshold\x18\x0c \x01(\x0b\x32\x19.google.protobuf.Duration\x12N\n\x11\x63\x61ncellation_type\x18\r \x01(\x0e\x32\x33.coresdk.workflow_commands.ActivityCancellationType\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"$\n\x15RequestCancelActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r")\n\x1aRequestCancelLocalActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r"\x9c\x01\n\x0bQueryResult\x12\x10\n\x08query_id\x18\x01 \x01(\t\x12<\n\tsucceeded\x18\x02 \x01(\x0b\x32\'.coresdk.workflow_commands.QuerySuccessH\x00\x12\x32\n\x06\x66\x61iled\x18\x03 \x01(\x0b\x32 .temporal.api.failure.v1.FailureH\x00\x42\t\n\x07variant"A\n\x0cQuerySuccess\x12\x31\n\x08response\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload"L\n\x19\x43ompleteWorkflowExecution\x12/\n\x06result\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload"J\n\x15\x46\x61ilWorkflowExecution\x12\x31\n\x07\x66\x61ilure\x18\x01 \x01(\x0b\x32 .temporal.api.failure.v1.Failure"\x92\x07\n\x1e\x43ontinueAsNewWorkflowExecution\x12\x15\n\rworkflow_type\x18\x01 \x01(\t\x12\x12\n\ntask_queue\x18\x02 \x01(\t\x12\x32\n\targuments\x18\x03 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x37\n\x14workflow_run_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12Q\n\x04memo\x18\x06 \x03(\x0b\x32\x43.coresdk.workflow_commands.ContinueAsNewWorkflowExecution.MemoEntry\x12W\n\x07headers\x18\x07 \x03(\x0b\x32\x46.coresdk.workflow_commands.ContinueAsNewWorkflowExecution.HeadersEntry\x12\x43\n\x11search_attributes\x18\x08 \x01(\x0b\x32(.temporal.api.common.v1.SearchAttributes\x12\x39\n\x0cretry_policy\x18\t \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12;\n\x11versioning_intent\x18\n \x01(\x0e\x32 .coresdk.common.VersioningIntent\x12[\n\x1binitial_versioning_behavior\x18\x0b \x01(\x0e\x32\x36.temporal.api.enums.v1.ContinueAsNewVersioningBehavior\x12\x39\n\x16\x62\x61\x63koff_start_interval\x18\x0c \x01(\x0b\x32\x19.google.protobuf.Duration\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"L\n\x17\x43\x61ncelWorkflowExecution\x12\x31\n\x07\x64\x65tails\x18\x01 \x01(\x0b\x32 .temporal.api.common.v1.Payloads"6\n\x0eSetPatchMarker\x12\x10\n\x08patch_id\x18\x01 \x01(\t\x12\x12\n\ndeprecated\x18\x02 \x01(\x08"\x96\t\n\x1bStartChildWorkflowExecution\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x03 \x01(\t\x12\x15\n\rworkflow_type\x18\x04 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12.\n\x05input\x18\x06 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12=\n\x1aworkflow_execution_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x37\n\x14workflow_run_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x46\n\x13parent_close_policy\x18\n \x01(\x0e\x32).coresdk.child_workflow.ParentClosePolicy\x12N\n\x18workflow_id_reuse_policy\x18\x0c \x01(\x0e\x32,.temporal.api.enums.v1.WorkflowIdReusePolicy\x12\x39\n\x0cretry_policy\x18\r \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x15\n\rcron_schedule\x18\x0e \x01(\t\x12T\n\x07headers\x18\x0f \x03(\x0b\x32\x43.coresdk.workflow_commands.StartChildWorkflowExecution.HeadersEntry\x12N\n\x04memo\x18\x10 \x03(\x0b\x32@.coresdk.workflow_commands.StartChildWorkflowExecution.MemoEntry\x12\x43\n\x11search_attributes\x18\x11 \x01(\x0b\x32(.temporal.api.common.v1.SearchAttributes\x12P\n\x11\x63\x61ncellation_type\x18\x12 \x01(\x0e\x32\x35.coresdk.child_workflow.ChildWorkflowCancellationType\x12;\n\x11versioning_intent\x18\x13 \x01(\x0e\x32 .coresdk.common.VersioningIntent\x12\x32\n\x08priority\x18\x14 \x01(\x0b\x32 .temporal.api.common.v1.Priority\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"J\n\x1c\x43\x61ncelChildWorkflowExecution\x12\x1a\n\x12\x63hild_workflow_seq\x18\x01 \x01(\r\x12\x0e\n\x06reason\x18\x02 \x01(\t"\x8e\x01\n&RequestCancelExternalWorkflowExecution\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12G\n\x12workflow_execution\x18\x02 \x01(\x0b\x32+.coresdk.common.NamespacedWorkflowExecution\x12\x0e\n\x06reason\x18\x03 \x01(\t"\x8f\x03\n\x1fSignalExternalWorkflowExecution\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12I\n\x12workflow_execution\x18\x02 \x01(\x0b\x32+.coresdk.common.NamespacedWorkflowExecutionH\x00\x12\x1b\n\x11\x63hild_workflow_id\x18\x03 \x01(\tH\x00\x12\x13\n\x0bsignal_name\x18\x04 \x01(\t\x12-\n\x04\x61rgs\x18\x05 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12X\n\x07headers\x18\x06 \x03(\x0b\x32G.coresdk.workflow_commands.SignalExternalWorkflowExecution.HeadersEntry\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x42\x08\n\x06target"#\n\x14\x43\x61ncelSignalWorkflow\x12\x0b\n\x03seq\x18\x01 \x01(\r"e\n\x1eUpsertWorkflowSearchAttributes\x12\x43\n\x11search_attributes\x18\x01 \x01(\x0b\x32(.temporal.api.common.v1.SearchAttributes"O\n\x18ModifyWorkflowProperties\x12\x33\n\rupserted_memo\x18\x01 \x01(\x0b\x32\x1c.temporal.api.common.v1.Memo"\xd2\x01\n\x0eUpdateResponse\x12\x1c\n\x14protocol_instance_id\x18\x01 \x01(\t\x12*\n\x08\x61\x63\x63\x65pted\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x34\n\x08rejected\x18\x03 \x01(\x0b\x32 .temporal.api.failure.v1.FailureH\x00\x12\x34\n\tcompleted\x18\x04 \x01(\x0b\x32\x1f.temporal.api.common.v1.PayloadH\x00\x42\n\n\x08response"\x9a\x04\n\x16ScheduleNexusOperation\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x10\n\x08\x65ndpoint\x18\x02 \x01(\t\x12\x0f\n\x07service\x18\x03 \x01(\t\x12\x11\n\toperation\x18\x04 \x01(\t\x12.\n\x05input\x18\x05 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12<\n\x19schedule_to_close_timeout\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12X\n\x0cnexus_header\x18\x07 \x03(\x0b\x32\x42.coresdk.workflow_commands.ScheduleNexusOperation.NexusHeaderEntry\x12H\n\x11\x63\x61ncellation_type\x18\x08 \x01(\x0e\x32-.coresdk.nexus.NexusOperationCancellationType\x12<\n\x19schedule_to_start_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\n \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\x32\n\x10NexusHeaderEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"*\n\x1bRequestCancelNexusOperation\x12\x0b\n\x03seq\x18\x01 \x01(\r*X\n\x18\x41\x63tivityCancellationType\x12\x0e\n\nTRY_CANCEL\x10\x00\x12\x1f\n\x1bWAIT_CANCELLATION_COMPLETED\x10\x01\x12\x0b\n\x07\x41\x42\x41NDON\x10\x02\x42\x36\xea\x02\x33Temporalio::Internal::Bridge::Api::WorkflowCommandsb\x06proto3' + b'\n;temporal/sdk/core/workflow_commands/workflow_commands.proto\x12\x19\x63oresdk.workflow_commands\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a$temporal/api/common/v1/message.proto\x1a$temporal/api/enums/v1/workflow.proto\x1a%temporal/api/failure/v1/message.proto\x1a\'temporal/api/sdk/v1/user_metadata.proto\x1a,temporal/api/sdk/v1/event_group_marker.proto\x1a\x35temporal/sdk/core/child_workflow/child_workflow.proto\x1a#temporal/sdk/core/nexus/nexus.proto\x1a%temporal/sdk/core/common/common.proto"\xa9\x10\n\x0fWorkflowCommand\x12\x38\n\ruser_metadata\x18\x64 \x01(\x0b\x32!.temporal.api.sdk.v1.UserMetadata\x12\x42\n\x13\x65vent_group_markers\x18\x65 \x03(\x0b\x32%.temporal.api.sdk.v1.EventGroupMarker\x12<\n\x0bstart_timer\x18\x01 \x01(\x0b\x32%.coresdk.workflow_commands.StartTimerH\x00\x12H\n\x11schedule_activity\x18\x02 \x01(\x0b\x32+.coresdk.workflow_commands.ScheduleActivityH\x00\x12\x42\n\x10respond_to_query\x18\x03 \x01(\x0b\x32&.coresdk.workflow_commands.QueryResultH\x00\x12S\n\x17request_cancel_activity\x18\x04 \x01(\x0b\x32\x30.coresdk.workflow_commands.RequestCancelActivityH\x00\x12>\n\x0c\x63\x61ncel_timer\x18\x05 \x01(\x0b\x32&.coresdk.workflow_commands.CancelTimerH\x00\x12[\n\x1b\x63omplete_workflow_execution\x18\x06 \x01(\x0b\x32\x34.coresdk.workflow_commands.CompleteWorkflowExecutionH\x00\x12S\n\x17\x66\x61il_workflow_execution\x18\x07 \x01(\x0b\x32\x30.coresdk.workflow_commands.FailWorkflowExecutionH\x00\x12g\n"continue_as_new_workflow_execution\x18\x08 \x01(\x0b\x32\x39.coresdk.workflow_commands.ContinueAsNewWorkflowExecutionH\x00\x12W\n\x19\x63\x61ncel_workflow_execution\x18\t \x01(\x0b\x32\x32.coresdk.workflow_commands.CancelWorkflowExecutionH\x00\x12\x45\n\x10set_patch_marker\x18\n \x01(\x0b\x32).coresdk.workflow_commands.SetPatchMarkerH\x00\x12`\n\x1estart_child_workflow_execution\x18\x0b \x01(\x0b\x32\x36.coresdk.workflow_commands.StartChildWorkflowExecutionH\x00\x12\x62\n\x1f\x63\x61ncel_child_workflow_execution\x18\x0c \x01(\x0b\x32\x37.coresdk.workflow_commands.CancelChildWorkflowExecutionH\x00\x12w\n*request_cancel_external_workflow_execution\x18\r \x01(\x0b\x32\x41.coresdk.workflow_commands.RequestCancelExternalWorkflowExecutionH\x00\x12h\n"signal_external_workflow_execution\x18\x0e \x01(\x0b\x32:.coresdk.workflow_commands.SignalExternalWorkflowExecutionH\x00\x12Q\n\x16\x63\x61ncel_signal_workflow\x18\x0f \x01(\x0b\x32/.coresdk.workflow_commands.CancelSignalWorkflowH\x00\x12S\n\x17schedule_local_activity\x18\x10 \x01(\x0b\x32\x30.coresdk.workflow_commands.ScheduleLocalActivityH\x00\x12^\n\x1drequest_cancel_local_activity\x18\x11 \x01(\x0b\x32\x35.coresdk.workflow_commands.RequestCancelLocalActivityH\x00\x12\x66\n!upsert_workflow_search_attributes\x18\x12 \x01(\x0b\x32\x39.coresdk.workflow_commands.UpsertWorkflowSearchAttributesH\x00\x12Y\n\x1amodify_workflow_properties\x18\x13 \x01(\x0b\x32\x33.coresdk.workflow_commands.ModifyWorkflowPropertiesH\x00\x12\x44\n\x0fupdate_response\x18\x14 \x01(\x0b\x32).coresdk.workflow_commands.UpdateResponseH\x00\x12U\n\x18schedule_nexus_operation\x18\x15 \x01(\x0b\x32\x31.coresdk.workflow_commands.ScheduleNexusOperationH\x00\x12`\n\x1erequest_cancel_nexus_operation\x18\x16 \x01(\x0b\x32\x36.coresdk.workflow_commands.RequestCancelNexusOperationH\x00\x42\t\n\x07variant"S\n\nStartTimer\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x38\n\x15start_to_fire_timeout\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration"\x1a\n\x0b\x43\x61ncelTimer\x12\x0b\n\x03seq\x18\x01 \x01(\r"\xb8\x06\n\x10ScheduleActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x13\n\x0b\x61\x63tivity_id\x18\x02 \x01(\t\x12\x15\n\ractivity_type\x18\x03 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12I\n\x07headers\x18\x06 \x03(\x0b\x32\x38.coresdk.workflow_commands.ScheduleActivity.HeadersEntry\x12\x32\n\targuments\x18\x07 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12<\n\x19schedule_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\n \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\x0b \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\x0c \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12N\n\x11\x63\x61ncellation_type\x18\r \x01(\x0e\x32\x33.coresdk.workflow_commands.ActivityCancellationType\x12\x1e\n\x16\x64o_not_eagerly_execute\x18\x0e \x01(\x08\x12;\n\x11versioning_intent\x18\x0f \x01(\x0e\x32 .coresdk.common.VersioningIntent\x12\x32\n\x08priority\x18\x10 \x01(\x0b\x32 .temporal.api.common.v1.Priority\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"\x95\x06\n\x15ScheduleLocalActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x13\n\x0b\x61\x63tivity_id\x18\x02 \x01(\t\x12\x15\n\ractivity_type\x18\x03 \x01(\t\x12\x0f\n\x07\x61ttempt\x18\x04 \x01(\r\x12:\n\x16original_schedule_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12N\n\x07headers\x18\x06 \x03(\x0b\x32=.coresdk.workflow_commands.ScheduleLocalActivity.HeadersEntry\x12\x32\n\targuments\x18\x07 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12<\n\x19schedule_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\n \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\x0b \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x38\n\x15local_retry_threshold\x18\x0c \x01(\x0b\x32\x19.google.protobuf.Duration\x12N\n\x11\x63\x61ncellation_type\x18\r \x01(\x0e\x32\x33.coresdk.workflow_commands.ActivityCancellationType\x12%\n\x1dinclude_arguments_into_marker\x18\x0e \x01(\x08\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"$\n\x15RequestCancelActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r")\n\x1aRequestCancelLocalActivity\x12\x0b\n\x03seq\x18\x01 \x01(\r"\x9c\x01\n\x0bQueryResult\x12\x10\n\x08query_id\x18\x01 \x01(\t\x12<\n\tsucceeded\x18\x02 \x01(\x0b\x32\'.coresdk.workflow_commands.QuerySuccessH\x00\x12\x32\n\x06\x66\x61iled\x18\x03 \x01(\x0b\x32 .temporal.api.failure.v1.FailureH\x00\x42\t\n\x07variant"A\n\x0cQuerySuccess\x12\x31\n\x08response\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload"L\n\x19\x43ompleteWorkflowExecution\x12/\n\x06result\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload"J\n\x15\x46\x61ilWorkflowExecution\x12\x31\n\x07\x66\x61ilure\x18\x01 \x01(\x0b\x32 .temporal.api.failure.v1.Failure"\x92\x07\n\x1e\x43ontinueAsNewWorkflowExecution\x12\x15\n\rworkflow_type\x18\x01 \x01(\t\x12\x12\n\ntask_queue\x18\x02 \x01(\t\x12\x32\n\targuments\x18\x03 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x37\n\x14workflow_run_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12Q\n\x04memo\x18\x06 \x03(\x0b\x32\x43.coresdk.workflow_commands.ContinueAsNewWorkflowExecution.MemoEntry\x12W\n\x07headers\x18\x07 \x03(\x0b\x32\x46.coresdk.workflow_commands.ContinueAsNewWorkflowExecution.HeadersEntry\x12\x43\n\x11search_attributes\x18\x08 \x01(\x0b\x32(.temporal.api.common.v1.SearchAttributes\x12\x39\n\x0cretry_policy\x18\t \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12;\n\x11versioning_intent\x18\n \x01(\x0e\x32 .coresdk.common.VersioningIntent\x12[\n\x1binitial_versioning_behavior\x18\x0b \x01(\x0e\x32\x36.temporal.api.enums.v1.ContinueAsNewVersioningBehavior\x12\x39\n\x16\x62\x61\x63koff_start_interval\x18\x0c \x01(\x0b\x32\x19.google.protobuf.Duration\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"L\n\x17\x43\x61ncelWorkflowExecution\x12\x31\n\x07\x64\x65tails\x18\x01 \x01(\x0b\x32 .temporal.api.common.v1.Payloads"6\n\x0eSetPatchMarker\x12\x10\n\x08patch_id\x18\x01 \x01(\t\x12\x12\n\ndeprecated\x18\x02 \x01(\x08"\x96\t\n\x1bStartChildWorkflowExecution\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x03 \x01(\t\x12\x15\n\rworkflow_type\x18\x04 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12.\n\x05input\x18\x06 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12=\n\x1aworkflow_execution_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x37\n\x14workflow_run_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x46\n\x13parent_close_policy\x18\n \x01(\x0e\x32).coresdk.child_workflow.ParentClosePolicy\x12N\n\x18workflow_id_reuse_policy\x18\x0c \x01(\x0e\x32,.temporal.api.enums.v1.WorkflowIdReusePolicy\x12\x39\n\x0cretry_policy\x18\r \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x15\n\rcron_schedule\x18\x0e \x01(\t\x12T\n\x07headers\x18\x0f \x03(\x0b\x32\x43.coresdk.workflow_commands.StartChildWorkflowExecution.HeadersEntry\x12N\n\x04memo\x18\x10 \x03(\x0b\x32@.coresdk.workflow_commands.StartChildWorkflowExecution.MemoEntry\x12\x43\n\x11search_attributes\x18\x11 \x01(\x0b\x32(.temporal.api.common.v1.SearchAttributes\x12P\n\x11\x63\x61ncellation_type\x18\x12 \x01(\x0e\x32\x35.coresdk.child_workflow.ChildWorkflowCancellationType\x12;\n\x11versioning_intent\x18\x13 \x01(\x0e\x32 .coresdk.common.VersioningIntent\x12\x32\n\x08priority\x18\x14 \x01(\x0b\x32 .temporal.api.common.v1.Priority\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01"J\n\x1c\x43\x61ncelChildWorkflowExecution\x12\x1a\n\x12\x63hild_workflow_seq\x18\x01 \x01(\r\x12\x0e\n\x06reason\x18\x02 \x01(\t"\x8e\x01\n&RequestCancelExternalWorkflowExecution\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12G\n\x12workflow_execution\x18\x02 \x01(\x0b\x32+.coresdk.common.NamespacedWorkflowExecution\x12\x0e\n\x06reason\x18\x03 \x01(\t"\x8f\x03\n\x1fSignalExternalWorkflowExecution\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12I\n\x12workflow_execution\x18\x02 \x01(\x0b\x32+.coresdk.common.NamespacedWorkflowExecutionH\x00\x12\x1b\n\x11\x63hild_workflow_id\x18\x03 \x01(\tH\x00\x12\x13\n\x0bsignal_name\x18\x04 \x01(\t\x12-\n\x04\x61rgs\x18\x05 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12X\n\x07headers\x18\x06 \x03(\x0b\x32G.coresdk.workflow_commands.SignalExternalWorkflowExecution.HeadersEntry\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x42\x08\n\x06target"#\n\x14\x43\x61ncelSignalWorkflow\x12\x0b\n\x03seq\x18\x01 \x01(\r"e\n\x1eUpsertWorkflowSearchAttributes\x12\x43\n\x11search_attributes\x18\x01 \x01(\x0b\x32(.temporal.api.common.v1.SearchAttributes"O\n\x18ModifyWorkflowProperties\x12\x33\n\rupserted_memo\x18\x01 \x01(\x0b\x32\x1c.temporal.api.common.v1.Memo"\xd2\x01\n\x0eUpdateResponse\x12\x1c\n\x14protocol_instance_id\x18\x01 \x01(\t\x12*\n\x08\x61\x63\x63\x65pted\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x34\n\x08rejected\x18\x03 \x01(\x0b\x32 .temporal.api.failure.v1.FailureH\x00\x12\x34\n\tcompleted\x18\x04 \x01(\x0b\x32\x1f.temporal.api.common.v1.PayloadH\x00\x42\n\n\x08response"\x9a\x04\n\x16ScheduleNexusOperation\x12\x0b\n\x03seq\x18\x01 \x01(\r\x12\x10\n\x08\x65ndpoint\x18\x02 \x01(\t\x12\x0f\n\x07service\x18\x03 \x01(\t\x12\x11\n\toperation\x18\x04 \x01(\t\x12.\n\x05input\x18\x05 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12<\n\x19schedule_to_close_timeout\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12X\n\x0cnexus_header\x18\x07 \x03(\x0b\x32\x42.coresdk.workflow_commands.ScheduleNexusOperation.NexusHeaderEntry\x12H\n\x11\x63\x61ncellation_type\x18\x08 \x01(\x0e\x32-.coresdk.nexus.NexusOperationCancellationType\x12<\n\x19schedule_to_start_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\n \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\x32\n\x10NexusHeaderEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"*\n\x1bRequestCancelNexusOperation\x12\x0b\n\x03seq\x18\x01 \x01(\r*X\n\x18\x41\x63tivityCancellationType\x12\x0e\n\nTRY_CANCEL\x10\x00\x12\x1f\n\x1bWAIT_CANCELLATION_COMPLETED\x10\x01\x12\x0b\n\x07\x41\x42\x41NDON\x10\x02\x42\x36\xea\x02\x33Temporalio::Internal::Bridge::Api::WorkflowCommandsb\x06proto3' ) _ACTIVITYCANCELLATIONTYPE = DESCRIPTOR.enum_types_by_name["ActivityCancellationType"] @@ -484,8 +484,8 @@ _SIGNALEXTERNALWORKFLOWEXECUTION_HEADERSENTRY._serialized_options = b"8\001" _SCHEDULENEXUSOPERATION_NEXUSHEADERENTRY._options = None _SCHEDULENEXUSOPERATION_NEXUSHEADERENTRY._serialized_options = b"8\001" - _ACTIVITYCANCELLATIONTYPE._serialized_start = 8633 - _ACTIVITYCANCELLATIONTYPE._serialized_end = 8721 + _ACTIVITYCANCELLATIONTYPE._serialized_start = 8672 + _ACTIVITYCANCELLATIONTYPE._serialized_end = 8760 _WORKFLOWCOMMAND._serialized_start = 518 _WORKFLOWCOMMAND._serialized_end = 2607 _STARTTIMER._serialized_start = 2609 @@ -497,57 +497,57 @@ _SCHEDULEACTIVITY_HEADERSENTRY._serialized_start = 3468 _SCHEDULEACTIVITY_HEADERSENTRY._serialized_end = 3547 _SCHEDULELOCALACTIVITY._serialized_start = 3550 - _SCHEDULELOCALACTIVITY._serialized_end = 4300 + _SCHEDULELOCALACTIVITY._serialized_end = 4339 _SCHEDULELOCALACTIVITY_HEADERSENTRY._serialized_start = 3468 _SCHEDULELOCALACTIVITY_HEADERSENTRY._serialized_end = 3547 - _REQUESTCANCELACTIVITY._serialized_start = 4302 - _REQUESTCANCELACTIVITY._serialized_end = 4338 - _REQUESTCANCELLOCALACTIVITY._serialized_start = 4340 - _REQUESTCANCELLOCALACTIVITY._serialized_end = 4381 - _QUERYRESULT._serialized_start = 4384 - _QUERYRESULT._serialized_end = 4540 - _QUERYSUCCESS._serialized_start = 4542 - _QUERYSUCCESS._serialized_end = 4607 - _COMPLETEWORKFLOWEXECUTION._serialized_start = 4609 - _COMPLETEWORKFLOWEXECUTION._serialized_end = 4685 - _FAILWORKFLOWEXECUTION._serialized_start = 4687 - _FAILWORKFLOWEXECUTION._serialized_end = 4761 - _CONTINUEASNEWWORKFLOWEXECUTION._serialized_start = 4764 - _CONTINUEASNEWWORKFLOWEXECUTION._serialized_end = 5678 - _CONTINUEASNEWWORKFLOWEXECUTION_MEMOENTRY._serialized_start = 5521 - _CONTINUEASNEWWORKFLOWEXECUTION_MEMOENTRY._serialized_end = 5597 + _REQUESTCANCELACTIVITY._serialized_start = 4341 + _REQUESTCANCELACTIVITY._serialized_end = 4377 + _REQUESTCANCELLOCALACTIVITY._serialized_start = 4379 + _REQUESTCANCELLOCALACTIVITY._serialized_end = 4420 + _QUERYRESULT._serialized_start = 4423 + _QUERYRESULT._serialized_end = 4579 + _QUERYSUCCESS._serialized_start = 4581 + _QUERYSUCCESS._serialized_end = 4646 + _COMPLETEWORKFLOWEXECUTION._serialized_start = 4648 + _COMPLETEWORKFLOWEXECUTION._serialized_end = 4724 + _FAILWORKFLOWEXECUTION._serialized_start = 4726 + _FAILWORKFLOWEXECUTION._serialized_end = 4800 + _CONTINUEASNEWWORKFLOWEXECUTION._serialized_start = 4803 + _CONTINUEASNEWWORKFLOWEXECUTION._serialized_end = 5717 + _CONTINUEASNEWWORKFLOWEXECUTION_MEMOENTRY._serialized_start = 5560 + _CONTINUEASNEWWORKFLOWEXECUTION_MEMOENTRY._serialized_end = 5636 _CONTINUEASNEWWORKFLOWEXECUTION_HEADERSENTRY._serialized_start = 3468 _CONTINUEASNEWWORKFLOWEXECUTION_HEADERSENTRY._serialized_end = 3547 - _CANCELWORKFLOWEXECUTION._serialized_start = 5680 - _CANCELWORKFLOWEXECUTION._serialized_end = 5756 - _SETPATCHMARKER._serialized_start = 5758 - _SETPATCHMARKER._serialized_end = 5812 - _STARTCHILDWORKFLOWEXECUTION._serialized_start = 5815 - _STARTCHILDWORKFLOWEXECUTION._serialized_end = 6989 + _CANCELWORKFLOWEXECUTION._serialized_start = 5719 + _CANCELWORKFLOWEXECUTION._serialized_end = 5795 + _SETPATCHMARKER._serialized_start = 5797 + _SETPATCHMARKER._serialized_end = 5851 + _STARTCHILDWORKFLOWEXECUTION._serialized_start = 5854 + _STARTCHILDWORKFLOWEXECUTION._serialized_end = 7028 _STARTCHILDWORKFLOWEXECUTION_HEADERSENTRY._serialized_start = 3468 _STARTCHILDWORKFLOWEXECUTION_HEADERSENTRY._serialized_end = 3547 - _STARTCHILDWORKFLOWEXECUTION_MEMOENTRY._serialized_start = 5521 - _STARTCHILDWORKFLOWEXECUTION_MEMOENTRY._serialized_end = 5597 - _CANCELCHILDWORKFLOWEXECUTION._serialized_start = 6991 - _CANCELCHILDWORKFLOWEXECUTION._serialized_end = 7065 - _REQUESTCANCELEXTERNALWORKFLOWEXECUTION._serialized_start = 7068 - _REQUESTCANCELEXTERNALWORKFLOWEXECUTION._serialized_end = 7210 - _SIGNALEXTERNALWORKFLOWEXECUTION._serialized_start = 7213 - _SIGNALEXTERNALWORKFLOWEXECUTION._serialized_end = 7612 + _STARTCHILDWORKFLOWEXECUTION_MEMOENTRY._serialized_start = 5560 + _STARTCHILDWORKFLOWEXECUTION_MEMOENTRY._serialized_end = 5636 + _CANCELCHILDWORKFLOWEXECUTION._serialized_start = 7030 + _CANCELCHILDWORKFLOWEXECUTION._serialized_end = 7104 + _REQUESTCANCELEXTERNALWORKFLOWEXECUTION._serialized_start = 7107 + _REQUESTCANCELEXTERNALWORKFLOWEXECUTION._serialized_end = 7249 + _SIGNALEXTERNALWORKFLOWEXECUTION._serialized_start = 7252 + _SIGNALEXTERNALWORKFLOWEXECUTION._serialized_end = 7651 _SIGNALEXTERNALWORKFLOWEXECUTION_HEADERSENTRY._serialized_start = 3468 _SIGNALEXTERNALWORKFLOWEXECUTION_HEADERSENTRY._serialized_end = 3547 - _CANCELSIGNALWORKFLOW._serialized_start = 7614 - _CANCELSIGNALWORKFLOW._serialized_end = 7649 - _UPSERTWORKFLOWSEARCHATTRIBUTES._serialized_start = 7651 - _UPSERTWORKFLOWSEARCHATTRIBUTES._serialized_end = 7752 - _MODIFYWORKFLOWPROPERTIES._serialized_start = 7754 - _MODIFYWORKFLOWPROPERTIES._serialized_end = 7833 - _UPDATERESPONSE._serialized_start = 7836 - _UPDATERESPONSE._serialized_end = 8046 - _SCHEDULENEXUSOPERATION._serialized_start = 8049 - _SCHEDULENEXUSOPERATION._serialized_end = 8587 - _SCHEDULENEXUSOPERATION_NEXUSHEADERENTRY._serialized_start = 8537 - _SCHEDULENEXUSOPERATION_NEXUSHEADERENTRY._serialized_end = 8587 - _REQUESTCANCELNEXUSOPERATION._serialized_start = 8589 - _REQUESTCANCELNEXUSOPERATION._serialized_end = 8631 + _CANCELSIGNALWORKFLOW._serialized_start = 7653 + _CANCELSIGNALWORKFLOW._serialized_end = 7688 + _UPSERTWORKFLOWSEARCHATTRIBUTES._serialized_start = 7690 + _UPSERTWORKFLOWSEARCHATTRIBUTES._serialized_end = 7791 + _MODIFYWORKFLOWPROPERTIES._serialized_start = 7793 + _MODIFYWORKFLOWPROPERTIES._serialized_end = 7872 + _UPDATERESPONSE._serialized_start = 7875 + _UPDATERESPONSE._serialized_end = 8085 + _SCHEDULENEXUSOPERATION._serialized_start = 8088 + _SCHEDULENEXUSOPERATION._serialized_end = 8626 + _SCHEDULENEXUSOPERATION_NEXUSHEADERENTRY._serialized_start = 8576 + _SCHEDULENEXUSOPERATION_NEXUSHEADERENTRY._serialized_end = 8626 + _REQUESTCANCELNEXUSOPERATION._serialized_start = 8628 + _REQUESTCANCELNEXUSOPERATION._serialized_end = 8670 # @@protoc_insertion_point(module_scope) diff --git a/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.pyi b/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.pyi index 510643132..ad4a5f487 100644 --- a/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.pyi +++ b/temporalio/bridge/proto/workflow_commands/workflow_commands_pb2.pyi @@ -620,6 +620,7 @@ class ScheduleLocalActivity(google.protobuf.message.Message): RETRY_POLICY_FIELD_NUMBER: builtins.int LOCAL_RETRY_THRESHOLD_FIELD_NUMBER: builtins.int CANCELLATION_TYPE_FIELD_NUMBER: builtins.int + INCLUDE_ARGUMENTS_INTO_MARKER_FIELD_NUMBER: builtins.int seq: builtins.int """Lang's incremental sequence number, used as the operation identifier""" activity_id: builtins.str @@ -684,6 +685,11 @@ class ScheduleLocalActivity(google.protobuf.message.Message): confirmed. Lang should default this to `WAIT_CANCELLATION_COMPLETED`, even though proto will default to `TRY_CANCEL` automatically. """ + include_arguments_into_marker: builtins.bool + """If set, the local activity arguments will be included in the resulting marker under the + `input` key. This is disabled by default to avoid increasing history size unless the lang + SDK explicitly chooses to expose it. + """ def __init__( self, *, @@ -706,6 +712,7 @@ class ScheduleLocalActivity(google.protobuf.message.Message): retry_policy: temporalio.api.common.v1.message_pb2.RetryPolicy | None = ..., local_retry_threshold: google.protobuf.duration_pb2.Duration | None = ..., cancellation_type: global___ActivityCancellationType.ValueType = ..., + include_arguments_into_marker: builtins.bool = ..., ) -> None: ... def HasField( self, @@ -739,6 +746,8 @@ class ScheduleLocalActivity(google.protobuf.message.Message): b"cancellation_type", "headers", b"headers", + "include_arguments_into_marker", + b"include_arguments_into_marker", "local_retry_threshold", b"local_retry_threshold", "original_schedule_time", diff --git a/temporalio/bridge/sdk-core b/temporalio/bridge/sdk-core index b860e3f14..85b71d7ec 160000 --- a/temporalio/bridge/sdk-core +++ b/temporalio/bridge/sdk-core @@ -1 +1 @@ -Subproject commit b860e3f14f68af64bd4d0e372b3c78b2ce9ecff1 +Subproject commit 85b71d7ecd4f2bf677fa1cee17f3fbc1ab10f1b9 diff --git a/temporalio/bridge/src/envconfig.rs b/temporalio/bridge/src/envconfig.rs index 7ce2f4664..0b21d1987 100644 --- a/temporalio/bridge/src/envconfig.rs +++ b/temporalio/bridge/src/envconfig.rs @@ -19,6 +19,11 @@ fn data_source_to_dict(py: Python, ds: &DataSource) -> PyResult> { match ds { DataSource::Path(p) => dict.set_item("path", p)?, DataSource::Data(d) => dict.set_item("data", PyBytes::new(py, d))?, + _ => { + return Err(PyRuntimeError::new_err( + "unsupported configuration data source", + )) + } }; Ok(dict.into()) } diff --git a/temporalio/bridge/src/worker.rs b/temporalio/bridge/src/worker.rs index 321dc6560..e74698e94 100644 --- a/temporalio/bridge/src/worker.rs +++ b/temporalio/bridge/src/worker.rs @@ -900,10 +900,10 @@ fn convert_versioning_strategy( WorkerVersioningStrategy::DeploymentBased(options) => { temporalio_sdk_core::WorkerVersioningStrategy::WorkerDeploymentBased( temporalio_common::worker::WorkerDeploymentOptions::new( - temporalio_common::worker::WorkerDeploymentVersion { - deployment_name: options.version.deployment_name, - build_id: options.version.build_id, - }, + temporalio_common::worker::WorkerDeploymentVersion::builder() + .deployment_name(options.version.deployment_name) + .build_id(options.version.build_id) + .build(), ) .use_worker_versioning(options.use_worker_versioning) .maybe_default_versioning_behavior(if options.use_worker_versioning { diff --git a/temporalio/contrib/opentelemetry/_interceptor.py b/temporalio/contrib/opentelemetry/_interceptor.py index eb22f8be6..6dca4596e 100644 --- a/temporalio/contrib/opentelemetry/_interceptor.py +++ b/temporalio/contrib/opentelemetry/_interceptor.py @@ -33,6 +33,7 @@ import temporalio.client import temporalio.converter import temporalio.exceptions +import temporalio.nexus.system.workflow_service.models import temporalio.worker import temporalio.workflow from temporalio.exceptions import ApplicationError, ApplicationErrorCategory @@ -433,6 +434,10 @@ class _InputWithStringHeaders(Protocol): headers: Mapping[str, str] | None +class _InputWithModelHeaders(Protocol): + headers: Mapping[str, Any] | None + + class _InputWithOperationContext(Generic[_ContextT], Protocol): ctx: _ContextT @@ -684,6 +689,18 @@ def _context_carrier_to_headers( } return headers + def _context_carrier_to_model_headers( + self, + carrier: _CarrierDict, + headers: Mapping[str, Any] | None, + ) -> Mapping[str, Any]: + if carrier: + return { + **(headers or {}), + self.header_key: carrier, + } + return headers or {} + def _completed_span( self, span_name: str, @@ -691,6 +708,7 @@ def _completed_span( link_context_carrier: _CarrierDict | None = None, add_to_outbound: _InputWithHeaders | None = None, add_to_outbound_str: _InputWithStringHeaders | None = None, + add_to_outbound_model: _InputWithModelHeaders | None = None, new_span_even_on_replay: bool = False, additional_attributes: opentelemetry.util.types.Attributes = None, exception: Exception | None = None, @@ -742,6 +760,11 @@ def _completed_span( updated_context_carrier, add_to_outbound_str.headers ) + if add_to_outbound_model: + add_to_outbound_model.headers = self._context_carrier_to_model_headers( + updated_context_carrier, add_to_outbound_model.headers + ) + def _set_on_context( self, context: opentelemetry.context.Context ) -> opentelemetry.context.Context: @@ -830,6 +853,19 @@ async def start_nexus_operation( return await super().start_nexus_operation(input) + async def start_signal_with_start_workflow( + self, + request: temporalio.nexus.system.workflow_service.models.SignalWithStartWorkflowRequest, + ) -> temporalio.workflow.NexusOperationHandle[ + temporalio.nexus.system.workflow_service.models.SignalWithStartWorkflowResponse + ]: + self.root._completed_span( + "SignalWithStartWorkflow", + kind=opentelemetry.trace.SpanKind.CLIENT, + add_to_outbound_model=request, + ) + return await super().start_signal_with_start_workflow(request) + def _carrier_to_nexus_headers( carrier: _CarrierDict, initial: Mapping[str, str] | None = None diff --git a/temporalio/contrib/opentelemetry/_otel_interceptor.py b/temporalio/contrib/opentelemetry/_otel_interceptor.py index c120fcd03..ff07f0f1d 100644 --- a/temporalio/contrib/opentelemetry/_otel_interceptor.py +++ b/temporalio/contrib/opentelemetry/_otel_interceptor.py @@ -32,6 +32,7 @@ import temporalio.api.common.v1 import temporalio.client import temporalio.converter +import temporalio.nexus.system.workflow_service.models import temporalio.worker import temporalio.workflow from temporalio.contrib.opentelemetry._tracer_provider import ( @@ -600,3 +601,15 @@ async def start_nexus_operation( ): input.headers = _context_to_nexus_headers(input.headers or {}) return await super().start_nexus_operation(input) + + async def start_signal_with_start_workflow( + self, + request: temporalio.nexus.system.workflow_service.models.SignalWithStartWorkflowRequest, + ) -> temporalio.workflow.NexusOperationHandle[ + temporalio.nexus.system.workflow_service.models.SignalWithStartWorkflowResponse + ]: + with self._workflow_maybe_span( + "SignalWithStartWorkflow", kind=opentelemetry.trace.SpanKind.CLIENT + ): + request.headers = _context_to_headers(request.headers or {}) + return await super().start_signal_with_start_workflow(request) diff --git a/temporalio/nexus/system/workflow_service/__init__.py b/temporalio/nexus/system/workflow_service/__init__.py index 49f7e4c12..3d7dac503 100644 --- a/temporalio/nexus/system/workflow_service/__init__.py +++ b/temporalio/nexus/system/workflow_service/__init__.py @@ -1,4 +1,4 @@ -# Generated by nexgen v0.2.2. DO NOT EDIT! +# Generated by nexgen v0.2.3. DO NOT EDIT! from __future__ import annotations diff --git a/temporalio/nexus/system/workflow_service/_support/__init__.py b/temporalio/nexus/system/workflow_service/_support/__init__.py index a07fc7273..f56c1cca7 100644 --- a/temporalio/nexus/system/workflow_service/_support/__init__.py +++ b/temporalio/nexus/system/workflow_service/_support/__init__.py @@ -1,4 +1,4 @@ -# Generated by nexgen v0.2.2. DO NOT EDIT! +# Generated by nexgen v0.2.3. DO NOT EDIT! from __future__ import annotations diff --git a/temporalio/nexus/system/workflow_service/_system_nexus_interceptor.py b/temporalio/nexus/system/workflow_service/_system_nexus_interceptor.py new file mode 100644 index 000000000..2f5e54ee2 --- /dev/null +++ b/temporalio/nexus/system/workflow_service/_system_nexus_interceptor.py @@ -0,0 +1,96 @@ +# Generated by nexgen v0.2.3. DO NOT EDIT! + +from __future__ import annotations + +import abc +import typing + +from temporalio.nexus.system import TEMPORAL_SYSTEM_ENDPOINT + +from . import models + +if typing.TYPE_CHECKING: + import temporalio.workflow + from temporalio.worker._interceptor import StartNexusOperationInput + + +__all__ = [ + "_start_system_nexus_operation", + "_SystemNexusWorkflowOutboundInterceptorBase", + "_SystemNexusWorkflowOutboundInterceptorTerminal", +] + + +_InputT = typing.TypeVar("_InputT") +_OutputT = typing.TypeVar("_OutputT") + + +async def _start_system_nexus_operation( + interceptor: _SystemNexusWorkflowOutboundInterceptorBase, + input: StartNexusOperationInput[_InputT, _OutputT], +) -> temporalio.workflow.NexusOperationHandle[_OutputT]: + if ( + input.service == "temporal.api.workflowservice.v1.WorkflowService" + and input.operation_name == "SignalWithStartWorkflowExecution" + ): + typed_input = typing.cast( + "StartNexusOperationInput[models.SignalWithStartWorkflowRequest, models.SignalWithStartWorkflowResponse]", + input, + ) + # The dispatch check above establishes that this operation's response type is _OutputT. + return typing.cast( + "temporalio.workflow.NexusOperationHandle[_OutputT]", + await interceptor.start_signal_with_start_workflow(typed_input.input), + ) + raise ValueError( + f"unsupported System Nexus operation: {input.service}/{input.operation_name}" + ) + + +class _SystemNexusWorkflowOutboundInterceptorBase(abc.ABC): + @abc.abstractmethod + def _next_system_nexus_interceptor( + self, + ) -> _SystemNexusWorkflowOutboundInterceptorBase: ... + + async def start_signal_with_start_workflow( + self, request: models.SignalWithStartWorkflowRequest + ) -> temporalio.workflow.NexusOperationHandle[ + models.SignalWithStartWorkflowResponse + ]: + """Intercept the SignalWithStartWorkflow operation.""" + return await self._next_system_nexus_interceptor().start_signal_with_start_workflow( + request + ) + + +class _SystemNexusWorkflowOutboundInterceptorTerminal(abc.ABC): + @abc.abstractmethod + async def _outbound_start_nexus_operation( + self, + input: StartNexusOperationInput[_InputT, _OutputT], + ) -> temporalio.workflow.NexusOperationHandle[_OutputT]: ... + + async def start_signal_with_start_workflow( + self, request: models.SignalWithStartWorkflowRequest + ) -> temporalio.workflow.NexusOperationHandle[ + models.SignalWithStartWorkflowResponse + ]: + from temporalio.worker._interceptor import StartNexusOperationInput + from temporalio.workflow import NexusOperationCancellationType + + return await self._outbound_start_nexus_operation( + StartNexusOperationInput( + endpoint=TEMPORAL_SYSTEM_ENDPOINT, + service="temporal.api.workflowservice.v1.WorkflowService", + operation="SignalWithStartWorkflowExecution", + input=request, + output_type=models.SignalWithStartWorkflowResponse, + schedule_to_close_timeout=None, + schedule_to_start_timeout=None, + start_to_close_timeout=None, + cancellation_type=NexusOperationCancellationType.WAIT_COMPLETED, + headers=None, + summary=None, + ) + ) diff --git a/temporalio/nexus/system/workflow_service/models.py b/temporalio/nexus/system/workflow_service/models.py index 5361e77b6..7e0c9f2eb 100644 --- a/temporalio/nexus/system/workflow_service/models.py +++ b/temporalio/nexus/system/workflow_service/models.py @@ -1,4 +1,4 @@ -# Generated by nexgen v0.2.2. DO NOT EDIT! +# Generated by nexgen v0.2.3. DO NOT EDIT! from __future__ import annotations @@ -46,9 +46,41 @@ ) +@dataclasses.dataclass(slots=True, kw_only=True) +class SignalWithStartWorkflowRequest: + """ + .. warning:: + This API is experimental and subject to change. + """ + + workflow: str | collections.abc.Callable[..., collections.abc.Awaitable[object]] + args: list[typing.Any] | None = None + id: str + task_queue: str + signal: str | collections.abc.Callable[..., None | collections.abc.Awaitable[None]] + signal_args: list[typing.Any] | None = None + execution_timeout: datetime.timedelta | None = None + run_timeout: datetime.timedelta | None = None + task_timeout: datetime.timedelta | None = None + id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = ( + temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE + ) + id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy | None = None + retry_policy: temporalio.common.RetryPolicy | None = None + cron_schedule: str | None = None + memo: collections.abc.Mapping[str, typing.Any] | None = None + search_attributes: temporalio.common.TypedSearchAttributes | None = None + priority: temporalio.common.Priority | None = None + versioning_override: temporalio.common.VersioningOverride | None = None + start_delay: datetime.timedelta | None = None + user_metadata: UserMetadata | None = None + namespace: str = dataclasses.field(default_factory=workflow_namespace) + headers: collections.abc.Mapping[str, typing.Any] | None = None + + class _SignalWithStartWorkflowRequestTransferTypeConverter( temporalio.converter.TransferTypeConverter[ - "SignalWithStartWorkflowRequest", + SignalWithStartWorkflowRequest, temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionRequest, ] ): @@ -63,8 +95,8 @@ class _SignalWithStartWorkflowRequestTransferTypeConverter( def from_transfer_type( self, value: temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionRequest, - type_hint: type["SignalWithStartWorkflowRequest"], - ) -> "SignalWithStartWorkflowRequest": + type_hint: type[SignalWithStartWorkflowRequest], + ) -> SignalWithStartWorkflowRequest: if not value.HasField("workflow_type"): raise ValueError( "missing required field SignalWithStartWorkflowRequest.workflow" @@ -142,7 +174,7 @@ def from_transfer_type( @typing_extensions.override def to_transfer_type( self, - value: "SignalWithStartWorkflowRequest", + value: SignalWithStartWorkflowRequest, ) -> temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionRequest: message = temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionRequest() message.workflow_type.CopyFrom(workflow_type_to_proto(value.workflow)) @@ -200,44 +232,20 @@ def to_transfer_type( return message -@temporalio.converter.transfer_type_convertible( +_ = temporalio.converter.transfer_type_convertible( _SignalWithStartWorkflowRequestTransferTypeConverter -) -@dataclasses.dataclass(slots=True, kw_only=True) -class SignalWithStartWorkflowRequest: - """ - .. warning:: - This API is experimental and subject to change. - """ +)(SignalWithStartWorkflowRequest) - workflow: str | collections.abc.Callable[..., collections.abc.Awaitable[object]] - args: list[typing.Any] | None = None - id: str - task_queue: str - signal: str | collections.abc.Callable[..., None | collections.abc.Awaitable[None]] - signal_args: list[typing.Any] | None = None - execution_timeout: datetime.timedelta | None = None - run_timeout: datetime.timedelta | None = None - task_timeout: datetime.timedelta | None = None - id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = ( - temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE - ) - id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy | None = None - retry_policy: temporalio.common.RetryPolicy | None = None - cron_schedule: str | None = None - memo: collections.abc.Mapping[str, typing.Any] | None = None - search_attributes: temporalio.common.TypedSearchAttributes | None = None - priority: temporalio.common.Priority | None = None - versioning_override: temporalio.common.VersioningOverride | None = None - start_delay: datetime.timedelta | None = None - user_metadata: UserMetadata | None = None - namespace: str = dataclasses.field(default_factory=workflow_namespace) - headers: collections.abc.Mapping[str, typing.Any] | None = None + +@dataclasses.dataclass(slots=True) +class UserMetadata: + static_summary: typing.Any | None = None + static_details: typing.Any | None = None class _UserMetadataTransferTypeConverter( temporalio.converter.TransferTypeConverter[ - "UserMetadata", temporalio.api.sdk.v1.user_metadata_pb2.UserMetadata + UserMetadata, temporalio.api.sdk.v1.user_metadata_pb2.UserMetadata ] ): transfer_type: type[temporalio.api.sdk.v1.user_metadata_pb2.UserMetadata] | None = ( @@ -248,8 +256,8 @@ class _UserMetadataTransferTypeConverter( def from_transfer_type( self, value: temporalio.api.sdk.v1.user_metadata_pb2.UserMetadata, - type_hint: type["UserMetadata"], - ) -> "UserMetadata": + type_hint: type[UserMetadata], + ) -> UserMetadata: return UserMetadata( static_summary=payload_from_proto(value.summary) if value.HasField("summary") @@ -262,7 +270,7 @@ def from_transfer_type( @typing_extensions.override def to_transfer_type( self, - value: "UserMetadata", + value: UserMetadata, ) -> temporalio.api.sdk.v1.user_metadata_pb2.UserMetadata: message = temporalio.api.sdk.v1.user_metadata_pb2.UserMetadata() if value.static_summary is not None: @@ -272,16 +280,25 @@ def to_transfer_type( return message -@temporalio.converter.transfer_type_convertible(_UserMetadataTransferTypeConverter) +_ = temporalio.converter.transfer_type_convertible(_UserMetadataTransferTypeConverter)( + UserMetadata +) + + @dataclasses.dataclass(slots=True) -class UserMetadata: - static_summary: typing.Any | None = None - static_details: typing.Any | None = None +class SignalWithStartWorkflowResponse: + """ + .. warning:: + This API is experimental and subject to change. + """ + + run_id: str | None = None + started: bool | None = None class _SignalWithStartWorkflowResponseTransferTypeConverter( temporalio.converter.TransferTypeConverter[ - "SignalWithStartWorkflowResponse", + SignalWithStartWorkflowResponse, temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionResponse, ] ): @@ -296,8 +313,8 @@ class _SignalWithStartWorkflowResponseTransferTypeConverter( def from_transfer_type( self, value: temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionResponse, - type_hint: type["SignalWithStartWorkflowResponse"], - ) -> "SignalWithStartWorkflowResponse": + type_hint: type[SignalWithStartWorkflowResponse], + ) -> SignalWithStartWorkflowResponse: return SignalWithStartWorkflowResponse( run_id=value.run_id if bool(value.run_id) else None, started=value.started if bool(value.started) else None, @@ -306,7 +323,7 @@ def from_transfer_type( @typing_extensions.override def to_transfer_type( self, - value: "SignalWithStartWorkflowResponse", + value: SignalWithStartWorkflowResponse, ) -> temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionResponse: message = temporalio.api.workflowservice.v1.request_response_pb2.SignalWithStartWorkflowExecutionResponse() if value.run_id is not None: @@ -316,15 +333,6 @@ def to_transfer_type( return message -@temporalio.converter.transfer_type_convertible( +_ = temporalio.converter.transfer_type_convertible( _SignalWithStartWorkflowResponseTransferTypeConverter -) -@dataclasses.dataclass(slots=True) -class SignalWithStartWorkflowResponse: - """ - .. warning:: - This API is experimental and subject to change. - """ - - run_id: str | None = None - started: bool | None = None +)(SignalWithStartWorkflowResponse) diff --git a/temporalio/nexus/system/workflow_service/operations/__init__.py b/temporalio/nexus/system/workflow_service/operations/__init__.py index 3c550f69c..e5abdafea 100644 --- a/temporalio/nexus/system/workflow_service/operations/__init__.py +++ b/temporalio/nexus/system/workflow_service/operations/__init__.py @@ -1,3 +1,3 @@ -# Generated by nexgen v0.2.2. DO NOT EDIT! +# Generated by nexgen v0.2.3. DO NOT EDIT! from __future__ import annotations diff --git a/temporalio/nexus/system/workflow_service/operations/signal_with_start_workflow.py b/temporalio/nexus/system/workflow_service/operations/signal_with_start_workflow.py index 97eb8159a..c04b115b3 100644 --- a/temporalio/nexus/system/workflow_service/operations/signal_with_start_workflow.py +++ b/temporalio/nexus/system/workflow_service/operations/signal_with_start_workflow.py @@ -1,4 +1,4 @@ -# Generated by nexgen v0.2.2. DO NOT EDIT! +# Generated by nexgen v0.2.3. DO NOT EDIT! from __future__ import annotations diff --git a/temporalio/nexus/system/workflow_service/services.py b/temporalio/nexus/system/workflow_service/services.py index 237565fff..9d46fe40a 100644 --- a/temporalio/nexus/system/workflow_service/services.py +++ b/temporalio/nexus/system/workflow_service/services.py @@ -1,4 +1,4 @@ -# Generated by nexgen v0.2.2. DO NOT EDIT! +# Generated by nexgen v0.2.3. DO NOT EDIT! from __future__ import annotations diff --git a/temporalio/worker/_interceptor.py b/temporalio/worker/_interceptor.py index 4acf3c5d1..1bac84673 100644 --- a/temporalio/worker/_interceptor.py +++ b/temporalio/worker/_interceptor.py @@ -21,6 +21,9 @@ import temporalio.nexus import temporalio.nexus._util import temporalio.workflow +from temporalio.nexus.system.workflow_service._system_nexus_interceptor import ( + _SystemNexusWorkflowOutboundInterceptorBase, +) from temporalio.workflow import ContinueAsNewVersioningBehavior, VersioningIntent @@ -414,12 +417,14 @@ async def handle_update_handler(self, input: HandleUpdateInput) -> Any: return await self.next.handle_update_handler(input) -class WorkflowOutboundInterceptor: +class WorkflowOutboundInterceptor(_SystemNexusWorkflowOutboundInterceptorBase): """Outbound interceptor to wrap calls made from within workflows. This should be extended by any workflow outbound interceptors. """ + next: WorkflowOutboundInterceptor + def __init__(self, next: WorkflowOutboundInterceptor) -> None: """Create the outbound interceptor. @@ -429,6 +434,11 @@ def __init__(self, next: WorkflowOutboundInterceptor) -> None: """ self.next = next + def _next_system_nexus_interceptor( + self, + ) -> _SystemNexusWorkflowOutboundInterceptorBase: + return self.next + def continue_as_new(self, input: ContinueAsNewInput) -> NoReturn: """Called for every :py:func:`temporalio.workflow.continue_as_new` call.""" self.next.continue_as_new(input) diff --git a/temporalio/worker/_workflow_instance.py b/temporalio/worker/_workflow_instance.py index 69b416f26..fca73c266 100644 --- a/temporalio/worker/_workflow_instance.py +++ b/temporalio/worker/_workflow_instance.py @@ -60,6 +60,10 @@ import temporalio.nexus.system import temporalio.workflow from temporalio.converter import StorageDriverStoreContext, StorageDriverWorkflowInfo +from temporalio.nexus.system.workflow_service._system_nexus_interceptor import ( + _start_system_nexus_operation, + _SystemNexusWorkflowOutboundInterceptorTerminal, +) from temporalio.service import __version__ from ..api.failure.v1.message_pb2 import Failure @@ -1732,7 +1736,23 @@ async def workflow_start_nexus_operation( headers: Mapping[str, str] | None, summary: str | None, ) -> temporalio.workflow.NexusOperationHandle[OutputT]: - # start_nexus_operation + if temporalio.nexus.system.is_system_endpoint(endpoint): + return await _start_system_nexus_operation( + self._outbound, + StartNexusOperationInput( + endpoint=temporalio.nexus.system.TEMPORAL_SYSTEM_ENDPOINT, + service=service, + operation=operation, + input=input, + output_type=output_type, + schedule_to_close_timeout=schedule_to_close_timeout, + schedule_to_start_timeout=schedule_to_start_timeout, + start_to_close_timeout=start_to_close_timeout, + cancellation_type=cancellation_type, + headers=None, + summary=summary, + ), + ) return await self._outbound.start_nexus_operation( StartNexusOperationInput( endpoint=endpoint, @@ -3131,11 +3151,18 @@ async def handle_update_handler(self, input: HandleUpdateInput) -> Any: return handler(*input.args) -class _WorkflowOutboundImpl(WorkflowOutboundInterceptor): +class _WorkflowOutboundImpl( + _SystemNexusWorkflowOutboundInterceptorTerminal, WorkflowOutboundInterceptor +): def __init__(self, instance: _WorkflowInstanceImpl) -> None: # type: ignore # We are intentionally not calling the base class's __init__ here self._instance = instance + async def _outbound_start_nexus_operation( + self, input: StartNexusOperationInput[InputT, OutputT] + ) -> temporalio.workflow.NexusOperationHandle[OutputT]: + return await self._instance._outbound_start_nexus_operation(input) + def continue_as_new(self, input: ContinueAsNewInput) -> NoReturn: self._instance._outbound_continue_as_new(input) diff --git a/tests/contrib/opentelemetry/test_opentelemetry.py b/tests/contrib/opentelemetry/test_opentelemetry.py index 1bab931ac..0ea9530e6 100644 --- a/tests/contrib/opentelemetry/test_opentelemetry.py +++ b/tests/contrib/opentelemetry/test_opentelemetry.py @@ -88,6 +88,34 @@ class TracingWorkflowActionActivity: fail_on_non_replay_before_complete: bool = False +@workflow.defn +class SignalWithStartHeaderWorkflow: + def __init__(self) -> None: + self._signaled = False + + @workflow.run + async def run(self) -> bool: + await workflow.wait_condition(lambda: self._signaled) + return "_tracer-data" in workflow.info().headers + + @workflow.signal + def notify(self) -> None: + self._signaled = True + + +@workflow.defn +class SignalWithStartCallerWorkflow: + @workflow.run + async def run(self, target_id: str, task_queue: str) -> str: + handle = await workflow.signal_with_start_workflow( + SignalWithStartHeaderWorkflow.run, + id=target_id, + task_queue=task_queue, + signal=SignalWithStartHeaderWorkflow.notify, + ) + return handle.id + + @dataclass class TracingWorkflowActionContinueAsNew: param: TracingWorkflowParam @@ -229,6 +257,41 @@ def update_validator(self) -> None: pass +@pytest.mark.requires_local_server +async def test_workflow_signal_with_start_propagates_trace_headers( + client: Client, env: WorkflowEnvironment +): + if env.supports_time_skipping: + pytest.skip("Nexus tests don't work with the Java test server") + provider = TracerProvider() + exporter = InMemorySpanExporter() + provider.add_span_processor(SimpleSpanProcessor(exporter)) + tracer = get_tracer(__name__, tracer_provider=provider) + config = client.config() + config["interceptors"] = [TracingInterceptor(tracer)] + client = Client(**config) + + async with Worker( + client, + task_queue=f"signal-with-start-{uuid.uuid4()}", + workflows=[SignalWithStartCallerWorkflow, SignalWithStartHeaderWorkflow], + workflow_runner=UnsandboxedWorkflowRunner(), + ) as worker: + target_id = f"signal-with-start-target-{uuid.uuid4()}" + with tracer.start_as_current_span("signal-with-start"): + caller = await client.start_workflow( + SignalWithStartCallerWorkflow.run, + args=[target_id, worker.task_queue], + id=f"signal-with-start-caller-{uuid.uuid4()}", + task_queue=worker.task_queue, + ) + assert await caller.result() == target_id + assert await client.get_workflow_handle(target_id).result() is True + assert any( + span.name == "SignalWithStartWorkflow" for span in exporter.get_finished_spans() + ) + + async def test_opentelemetry_tracing(client: Client, env: WorkflowEnvironment): # TODO(cretz): Fix if env.supports_time_skipping: diff --git a/tests/contrib/opentelemetry/test_opentelemetry_plugin.py b/tests/contrib/opentelemetry/test_opentelemetry_plugin.py index 12d0c5972..022645fee 100644 --- a/tests/contrib/opentelemetry/test_opentelemetry_plugin.py +++ b/tests/contrib/opentelemetry/test_opentelemetry_plugin.py @@ -122,6 +122,34 @@ async def run(self): return +@workflow.defn +class SignalWithStartHeaderWorkflow: + def __init__(self) -> None: + self._signaled = False + + @workflow.run + async def run(self) -> bool: + await workflow.wait_condition(lambda: self._signaled) + return "_tracer-data" in workflow.info().headers + + @workflow.signal + def notify(self) -> None: + self._signaled = True + + +@workflow.defn +class SignalWithStartCallerWorkflow: + @workflow.run + async def run(self, target_id: str, task_queue: str) -> str: + handle = await workflow.signal_with_start_workflow( + SignalWithStartHeaderWorkflow.run, + id=target_id, + task_queue=task_queue, + signal=SignalWithStartHeaderWorkflow.notify, + ) + return handle.id + + async def test_otel_tracing_basic(client: Client, reset_otel_tracer_provider: Any): # type: ignore[reportUnusedParameter] exporter = InMemorySpanExporter() provider = create_tracer_provider() @@ -169,6 +197,41 @@ async def test_otel_tracing_basic(client: Client, reset_otel_tracer_provider: An ) +@pytest.mark.requires_local_server +async def test_workflow_signal_with_start_propagates_trace_headers( + client: Client, + env: WorkflowEnvironment, + reset_otel_tracer_provider: Any, # type: ignore[reportUnusedParameter] +): + if env.supports_time_skipping: + pytest.skip("Nexus tests don't work with the Java test server") + exporter = InMemorySpanExporter() + provider = create_tracer_provider() + provider.add_span_processor(SimpleSpanProcessor(exporter)) + opentelemetry.trace.set_tracer_provider(provider) + config = client.config() + config["plugins"] = [OpenTelemetryPlugin(add_temporal_spans=True)] + client = Client(**config) + + async with new_worker( + client, SignalWithStartCallerWorkflow, SignalWithStartHeaderWorkflow + ) as worker: + target_id = f"signal-with-start-target-{uuid.uuid4()}" + with get_tracer(__name__).start_as_current_span("signal-with-start"): + caller = await client.start_workflow( + SignalWithStartCallerWorkflow.run, + args=[target_id, worker.task_queue], + id=f"signal-with-start-caller-{uuid.uuid4()}", + task_queue=worker.task_queue, + execution_timeout=timedelta(seconds=3), + ) + assert await caller.result() == target_id + assert await client.get_workflow_handle(target_id).result() is True + assert any( + span.name == "SignalWithStartWorkflow" for span in exporter.get_finished_spans() + ) + + @workflow.defn class ComprehensiveWorkflow: def __init__(self) -> None: diff --git a/tests/nexus/test_temporal_system_nexus.py b/tests/nexus/test_temporal_system_nexus.py index dc49f0302..d2abefa23 100644 --- a/tests/nexus/test_temporal_system_nexus.py +++ b/tests/nexus/test_temporal_system_nexus.py @@ -36,7 +36,6 @@ from temporalio.testing import WorkflowEnvironment from temporalio.worker import ( Interceptor, - StartNexusOperationInput, Worker, WorkflowInboundInterceptor, WorkflowInterceptorClassInput, @@ -251,11 +250,16 @@ def init(self, outbound: WorkflowOutboundInterceptor) -> None: class _TracingWorkflowOutboundInterceptor(WorkflowOutboundInterceptor): - async def start_nexus_operation( - self, input: StartNexusOperationInput[Any, Any] - ) -> workflow.NexusOperationHandle[Any]: - interceptor_traces.append(("workflow.start_nexus_operation", input)) - return await super().start_nexus_operation(input) + async def start_signal_with_start_workflow( + self, request: workflow_service_models.SignalWithStartWorkflowRequest + ) -> workflow.NexusOperationHandle[ + workflow_service_models.SignalWithStartWorkflowResponse + ]: + request.headers = {**(request.headers or {}), "interceptor-header": "value"} + interceptor_traces.append( + ("workflow.start_signal_with_start_workflow", request) + ) + return await super().start_signal_with_start_workflow(request) def _assert_stored_payloads_include( @@ -270,15 +274,15 @@ def _assert_stored_payloads_include( assert expected_payload_data.issubset(stored_payload_data) -def _assert_start_nexus_operation_interceptor_trace() -> None: +def _assert_signal_with_start_workflow_interceptor_trace() -> None: assert len(interceptor_traces) == 1 trace_name, trace_value = interceptor_traces.pop() - assert trace_name == "workflow.start_nexus_operation" - trace_input = cast(StartNexusOperationInput[Any, Any], trace_value) - request = trace_input.input + assert trace_name == "workflow.start_signal_with_start_workflow" + request = cast(workflow_service_models.SignalWithStartWorkflowRequest, trace_value) assert request.id == "system-nexus-workflow-id" assert request.signal == "test-signal" assert request.workflow == "test-workflow" + assert request.headers == {"interceptor-header": "value"} class _MarkingPayloadVisitor(VisitorFunctions): @@ -708,7 +712,7 @@ async def test_external_workflow_handle_signal_with_start_workflow_uses_system_n b'"details-value"', }, ) - _assert_start_nexus_operation_interceptor_trace() + _assert_signal_with_start_workflow_interceptor_trace() # Cloud namespaces created by CI do not have the System Nexus dynamic config.