From 663d5bbf2d50a7654c7f9a03bf0501140c0ea2f8 Mon Sep 17 00:00:00 2001 From: johanngan Date: Thu, 5 Nov 2026 14:20:57 -0600 Subject: [PATCH] Update sdk-core to main (ff30d403) Ran update-core, and regenerated the bridge protos Core's API update changed. Co-Authored-By: Claude Opus 5.5 --- changelog/added/headier-mackenzie.md | 2 + changelog/fixed/headier-mackenzie.md | 3 + temporalio/bridge/Cargo.lock | 4 +- .../bridge/proto/activity_task/__init__.py | 2 + .../proto/activity_task/activity_task_pb2.py | 34 ++++--- .../proto/activity_task/activity_task_pb2.pyi | 88 +++++++++++++++++++ temporalio/bridge/sdk-core | 2 +- 7 files changed, 122 insertions(+), 13 deletions(-) create mode 100644 changelog/added/headier-mackenzie.md create mode 100644 changelog/fixed/headier-mackenzie.md diff --git a/changelog/added/headier-mackenzie.md b/changelog/added/headier-mackenzie.md new file mode 100644 index 0000000000..66ea4d3254 --- /dev/null +++ b/changelog/added/headier-mackenzie.md @@ -0,0 +1,2 @@ +Core: A local activity's `ActivityTask.Start` has `workflow_task` (field 21), with the started event id, attempt and start time of the workflow task in which Core dispatched it. `workflow_task` also has `previous_started_event_id`, `previous_attempt` and `previous_started_time`, which name the run's last completed workflow task, and `failed_tasks`, the started event ids of the run's last 100 failed or timed out workflow tasks. Retries that Core runs locally keep the value. Core leaves it unset for other activities. +Core: Client environment config profiles include the raw TOML tables under `profile..ext`, keyed by extension name, for SDK envconfig extensions. Strict mode accepts any content under `ext`. The C bridge's profile JSON includes them as an `ext` object, with TOML datetimes as strings. diff --git a/changelog/fixed/headier-mackenzie.md b/changelog/fixed/headier-mackenzie.md new file mode 100644 index 0000000000..2c099ac2d5 --- /dev/null +++ b/changelog/fixed/headier-mackenzie.md @@ -0,0 +1,3 @@ +Core: A workflow task failure reported with the cause `WORKFLOW_TASK_FAILED_CAUSE_EXTERNAL_STORAGE_FAILURE` is now counted on `workflow_task_execution_failed` with `failure_reason="ExternalStorageError"`, matching activity failures with the storage cause. It was previously counted as `WorkflowError`. +Core: Ephemeral dev and test servers now complete the automatic port reservation handshake on Linux and macOS before starting, preventing intermittent address-in-use errors during TCP teardown. +Core: Resource-based worker tuners now read CPU usage and quotas from standard cgroup v1 mounts. Workers on cgroup v1 systems no longer fall back to host CPU usage and admit work based on understated container load. diff --git a/temporalio/bridge/Cargo.lock b/temporalio/bridge/Cargo.lock index deae7c52f1..531d3a6515 100644 --- a/temporalio/bridge/Cargo.lock +++ b/temporalio/bridge/Cargo.lock @@ -1222,9 +1222,9 @@ checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "lru" -version = "0.18.5" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5" +checksum = "4a9f71e3591c7ec44d3e563e87bf14ddc2bada8519dca046e5b0e560cd004e2d" dependencies = [ "hashbrown 0.17.1", ] diff --git a/temporalio/bridge/proto/activity_task/__init__.py b/temporalio/bridge/proto/activity_task/__init__.py index 779ebf3535..9e69a0f894 100644 --- a/temporalio/bridge/proto/activity_task/__init__.py +++ b/temporalio/bridge/proto/activity_task/__init__.py @@ -4,6 +4,7 @@ ActivityTask, Cancel, Start, + WorkflowTaskAttempt, ) __all__ = [ @@ -12,4 +13,5 @@ "ActivityTask", "Cancel", "Start", + "WorkflowTaskAttempt", ] diff --git a/temporalio/bridge/proto/activity_task/activity_task_pb2.py b/temporalio/bridge/proto/activity_task/activity_task_pb2.py index 38bd426a7c..cc7365b5db 100644 --- a/temporalio/bridge/proto/activity_task/activity_task_pb2.py +++ b/temporalio/bridge/proto/activity_task/activity_task_pb2.py @@ -29,7 +29,7 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n3temporal/sdk/core/activity_task/activity_task.proto\x12\x15\x63oresdk.activity_task\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a$temporal/api/common/v1/message.proto\x1a#temporal/api/nexus/v1/message.proto\x1a%temporal/sdk/core/common/common.proto"\x8d\x01\n\x0c\x41\x63tivityTask\x12\x12\n\ntask_token\x18\x01 \x01(\x0c\x12-\n\x05start\x18\x03 \x01(\x0b\x32\x1c.coresdk.activity_task.StartH\x00\x12/\n\x06\x63\x61ncel\x18\x04 \x01(\x0b\x32\x1d.coresdk.activity_task.CancelH\x00\x42\t\n\x07variant"\x98\x08\n\x05Start\x12\x1a\n\x12workflow_namespace\x18\x01 \x01(\t\x12\x15\n\rworkflow_type\x18\x02 \x01(\t\x12\x45\n\x12workflow_execution\x18\x03 \x01(\x0b\x32).temporal.api.common.v1.WorkflowExecution\x12\x13\n\x0b\x61\x63tivity_id\x18\x04 \x01(\t\x12\x15\n\ractivity_type\x18\x05 \x01(\t\x12\x45\n\rheader_fields\x18\x06 \x03(\x0b\x32..coresdk.activity_task.Start.HeaderFieldsEntry\x12.\n\x05input\x18\x07 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12:\n\x11heartbeat_details\x18\x08 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x32\n\x0escheduled_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x42\n\x1e\x63urrent_attempt_scheduled_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0cstarted_time\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07\x61ttempt\x18\x0c \x01(\r\x12<\n\x19schedule_to_close_timeout\x18\r \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\x0e \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\x0f \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\x10 \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x32\n\x08priority\x18\x12 \x01(\x0b\x32 .temporal.api.common.v1.Priority\x12\x10\n\x08is_local\x18\x11 \x01(\x08\x12\x0e\n\x06run_id\x18\x13 \x01(\t\x12\x65\n&propagated_nexus_serialization_context\x18\x14 \x01(\x0b\x32\x35.temporal.api.nexus.v1.PropagatedSerializationContext\x1aT\n\x11HeaderFieldsEntry\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"\x8a\x01\n\x06\x43\x61ncel\x12;\n\x06reason\x18\x01 \x01(\x0e\x32+.coresdk.activity_task.ActivityCancelReason\x12\x43\n\x07\x64\x65tails\x18\x02 \x01(\x0b\x32\x32.coresdk.activity_task.ActivityCancellationDetails"\xa0\x01\n\x1b\x41\x63tivityCancellationDetails\x12\x14\n\x0cis_not_found\x18\x01 \x01(\x08\x12\x14\n\x0cis_cancelled\x18\x02 \x01(\x08\x12\x11\n\tis_paused\x18\x03 \x01(\x08\x12\x14\n\x0cis_timed_out\x18\x04 \x01(\x08\x12\x1a\n\x12is_worker_shutdown\x18\x05 \x01(\x08\x12\x10\n\x08is_reset\x18\x06 \x01(\x08*o\n\x14\x41\x63tivityCancelReason\x12\r\n\tNOT_FOUND\x10\x00\x12\r\n\tCANCELLED\x10\x01\x12\r\n\tTIMED_OUT\x10\x02\x12\x13\n\x0fWORKER_SHUTDOWN\x10\x03\x12\n\n\x06PAUSED\x10\x04\x12\t\n\x05RESET\x10\x05\x42\x32\xea\x02/Temporalio::Internal::Bridge::Api::ActivityTaskb\x06proto3' + b'\n3temporal/sdk/core/activity_task/activity_task.proto\x12\x15\x63oresdk.activity_task\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a$temporal/api/common/v1/message.proto\x1a#temporal/api/nexus/v1/message.proto\x1a%temporal/sdk/core/common/common.proto"\x8d\x01\n\x0c\x41\x63tivityTask\x12\x12\n\ntask_token\x18\x01 \x01(\x0c\x12-\n\x05start\x18\x03 \x01(\x0b\x32\x1c.coresdk.activity_task.StartH\x00\x12/\n\x06\x63\x61ncel\x18\x04 \x01(\x0b\x32\x1d.coresdk.activity_task.CancelH\x00\x42\t\n\x07variant"\xdb\x08\n\x05Start\x12\x1a\n\x12workflow_namespace\x18\x01 \x01(\t\x12\x15\n\rworkflow_type\x18\x02 \x01(\t\x12\x45\n\x12workflow_execution\x18\x03 \x01(\x0b\x32).temporal.api.common.v1.WorkflowExecution\x12\x13\n\x0b\x61\x63tivity_id\x18\x04 \x01(\t\x12\x15\n\ractivity_type\x18\x05 \x01(\t\x12\x45\n\rheader_fields\x18\x06 \x03(\x0b\x32..coresdk.activity_task.Start.HeaderFieldsEntry\x12.\n\x05input\x18\x07 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12:\n\x11heartbeat_details\x18\x08 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x32\n\x0escheduled_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x42\n\x1e\x63urrent_attempt_scheduled_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0cstarted_time\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07\x61ttempt\x18\x0c \x01(\r\x12<\n\x19schedule_to_close_timeout\x18\r \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\x0e \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\x0f \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\x10 \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x32\n\x08priority\x18\x12 \x01(\x0b\x32 .temporal.api.common.v1.Priority\x12\x10\n\x08is_local\x18\x11 \x01(\x08\x12\x0e\n\x06run_id\x18\x13 \x01(\t\x12\x65\n&propagated_nexus_serialization_context\x18\x14 \x01(\x0b\x32\x35.temporal.api.nexus.v1.PropagatedSerializationContext\x12\x41\n\rworkflow_task\x18\x15 \x01(\x0b\x32*.coresdk.activity_task.WorkflowTaskAttempt\x1aT\n\x11HeaderFieldsEntry\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"\x80\x02\n\x13WorkflowTaskAttempt\x12\x18\n\x10started_event_id\x18\x01 \x01(\x03\x12\x0f\n\x07\x61ttempt\x18\x02 \x01(\r\x12\x30\n\x0cstarted_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12!\n\x19previous_started_event_id\x18\x04 \x01(\x03\x12\x14\n\x0c\x66\x61iled_tasks\x18\x05 \x03(\x03\x12\x18\n\x10previous_attempt\x18\x06 \x01(\r\x12\x39\n\x15previous_started_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\x8a\x01\n\x06\x43\x61ncel\x12;\n\x06reason\x18\x01 \x01(\x0e\x32+.coresdk.activity_task.ActivityCancelReason\x12\x43\n\x07\x64\x65tails\x18\x02 \x01(\x0b\x32\x32.coresdk.activity_task.ActivityCancellationDetails"\xa0\x01\n\x1b\x41\x63tivityCancellationDetails\x12\x14\n\x0cis_not_found\x18\x01 \x01(\x08\x12\x14\n\x0cis_cancelled\x18\x02 \x01(\x08\x12\x11\n\tis_paused\x18\x03 \x01(\x08\x12\x14\n\x0cis_timed_out\x18\x04 \x01(\x08\x12\x1a\n\x12is_worker_shutdown\x18\x05 \x01(\x08\x12\x10\n\x08is_reset\x18\x06 \x01(\x08*o\n\x14\x41\x63tivityCancelReason\x12\r\n\tNOT_FOUND\x10\x00\x12\r\n\tCANCELLED\x10\x01\x12\r\n\tTIMED_OUT\x10\x02\x12\x13\n\x0fWORKER_SHUTDOWN\x10\x03\x12\n\n\x06PAUSED\x10\x04\x12\t\n\x05RESET\x10\x05\x42\x32\xea\x02/Temporalio::Internal::Bridge::Api::ActivityTaskb\x06proto3' ) _ACTIVITYCANCELREASON = DESCRIPTOR.enum_types_by_name["ActivityCancelReason"] @@ -45,6 +45,7 @@ _ACTIVITYTASK = DESCRIPTOR.message_types_by_name["ActivityTask"] _START = DESCRIPTOR.message_types_by_name["Start"] _START_HEADERFIELDSENTRY = _START.nested_types_by_name["HeaderFieldsEntry"] +_WORKFLOWTASKATTEMPT = DESCRIPTOR.message_types_by_name["WorkflowTaskAttempt"] _CANCEL = DESCRIPTOR.message_types_by_name["Cancel"] _ACTIVITYCANCELLATIONDETAILS = DESCRIPTOR.message_types_by_name[ "ActivityCancellationDetails" @@ -81,6 +82,17 @@ _sym_db.RegisterMessage(Start) _sym_db.RegisterMessage(Start.HeaderFieldsEntry) +WorkflowTaskAttempt = _reflection.GeneratedProtocolMessageType( + "WorkflowTaskAttempt", + (_message.Message,), + { + "DESCRIPTOR": _WORKFLOWTASKATTEMPT, + "__module__": "temporal.sdk.core.activity_task.activity_task_pb2", + # @@protoc_insertion_point(class_scope:coresdk.activity_task.WorkflowTaskAttempt) + }, +) +_sym_db.RegisterMessage(WorkflowTaskAttempt) + Cancel = _reflection.GeneratedProtocolMessageType( "Cancel", (_message.Message,), @@ -110,16 +122,18 @@ ) _START_HEADERFIELDSENTRY._options = None _START_HEADERFIELDSENTRY._serialized_options = b"8\001" - _ACTIVITYCANCELREASON._serialized_start = 1756 - _ACTIVITYCANCELREASON._serialized_end = 1867 + _ACTIVITYCANCELREASON._serialized_start = 2082 + _ACTIVITYCANCELREASON._serialized_end = 2193 _ACTIVITYTASK._serialized_start = 258 _ACTIVITYTASK._serialized_end = 399 _START._serialized_start = 402 - _START._serialized_end = 1450 - _START_HEADERFIELDSENTRY._serialized_start = 1366 - _START_HEADERFIELDSENTRY._serialized_end = 1450 - _CANCEL._serialized_start = 1453 - _CANCEL._serialized_end = 1591 - _ACTIVITYCANCELLATIONDETAILS._serialized_start = 1594 - _ACTIVITYCANCELLATIONDETAILS._serialized_end = 1754 + _START._serialized_end = 1517 + _START_HEADERFIELDSENTRY._serialized_start = 1433 + _START_HEADERFIELDSENTRY._serialized_end = 1517 + _WORKFLOWTASKATTEMPT._serialized_start = 1520 + _WORKFLOWTASKATTEMPT._serialized_end = 1776 + _CANCEL._serialized_start = 1779 + _CANCEL._serialized_end = 1917 + _ACTIVITYCANCELLATIONDETAILS._serialized_start = 1920 + _ACTIVITYCANCELLATIONDETAILS._serialized_end = 2080 # @@protoc_insertion_point(module_scope) diff --git a/temporalio/bridge/proto/activity_task/activity_task_pb2.pyi b/temporalio/bridge/proto/activity_task/activity_task_pb2.pyi index fd17611e29..960c984f23 100644 --- a/temporalio/bridge/proto/activity_task/activity_task_pb2.pyi +++ b/temporalio/bridge/proto/activity_task/activity_task_pb2.pyi @@ -162,6 +162,7 @@ class Start(google.protobuf.message.Message): IS_LOCAL_FIELD_NUMBER: builtins.int RUN_ID_FIELD_NUMBER: builtins.int PROPAGATED_NEXUS_SERIALIZATION_CONTEXT_FIELD_NUMBER: builtins.int + WORKFLOW_TASK_FIELD_NUMBER: builtins.int workflow_namespace: builtins.str """The namespace the workflow lives in""" workflow_type: builtins.str @@ -237,6 +238,11 @@ class Start(google.protobuf.message.Message): Only set for standalone activities. Lang should use it to serialize the activity's result and failure, which are returned to the Nexus caller. """ + @property + def workflow_task(self) -> global___WorkflowTaskAttempt: + """For a local activity, the workflow task in which Core dispatched this execution. Retries that + Core runs locally keep the value. Unset for other activities. + """ def __init__( self, *, @@ -270,6 +276,7 @@ class Start(google.protobuf.message.Message): run_id: builtins.str = ..., propagated_nexus_serialization_context: temporalio.api.nexus.v1.message_pb2.PropagatedSerializationContext | None = ..., + workflow_task: global___WorkflowTaskAttempt | None = ..., ) -> None: ... def HasField( self, @@ -294,6 +301,8 @@ class Start(google.protobuf.message.Message): b"started_time", "workflow_execution", b"workflow_execution", + "workflow_task", + b"workflow_task", ], ) -> builtins.bool: ... def ClearField( @@ -337,6 +346,8 @@ class Start(google.protobuf.message.Message): b"workflow_execution", "workflow_namespace", b"workflow_namespace", + "workflow_task", + b"workflow_task", "workflow_type", b"workflow_type", ], @@ -344,6 +355,83 @@ class Start(google.protobuf.message.Message): global___Start = Start +class WorkflowTaskAttempt(google.protobuf.message.Message): + """One attempt of a workflow task, from the poll response and the history of that attempt.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STARTED_EVENT_ID_FIELD_NUMBER: builtins.int + ATTEMPT_FIELD_NUMBER: builtins.int + STARTED_TIME_FIELD_NUMBER: builtins.int + PREVIOUS_STARTED_EVENT_ID_FIELD_NUMBER: builtins.int + FAILED_TASKS_FIELD_NUMBER: builtins.int + PREVIOUS_ATTEMPT_FIELD_NUMBER: builtins.int + PREVIOUS_STARTED_TIME_FIELD_NUMBER: builtins.int + started_event_id: builtins.int + """The event id of the task's WorkflowTaskStarted event.""" + attempt: builtins.int + @property + def started_time(self) -> google.protobuf.timestamp_pb2.Timestamp: + """When the server started the task.""" + previous_started_event_id: builtins.int + """The started event id of the run's last completed workflow task, from the poll response. + 0 when no task of the run has completed. + """ + @property + def failed_tasks( + self, + ) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """The started event ids of the run's last 100 failed and timed out workflow tasks in history, + in event order. The cap keeps each start small. A transient attempt has no such event. + """ + previous_attempt: builtins.int + """The attempt and the started time of the task at previous_started_event_id, from its + WorkflowTaskScheduled and WorkflowTaskStarted events. Unset when no task has completed. + """ + @property + def previous_started_time(self) -> google.protobuf.timestamp_pb2.Timestamp: ... + def __init__( + self, + *, + started_event_id: builtins.int = ..., + attempt: builtins.int = ..., + started_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + previous_started_event_id: builtins.int = ..., + failed_tasks: collections.abc.Iterable[builtins.int] | None = ..., + previous_attempt: builtins.int = ..., + previous_started_time: google.protobuf.timestamp_pb2.Timestamp | None = ..., + ) -> None: ... + def HasField( + self, + field_name: typing_extensions.Literal[ + "previous_started_time", + b"previous_started_time", + "started_time", + b"started_time", + ], + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "attempt", + b"attempt", + "failed_tasks", + b"failed_tasks", + "previous_attempt", + b"previous_attempt", + "previous_started_event_id", + b"previous_started_event_id", + "previous_started_time", + b"previous_started_time", + "started_event_id", + b"started_event_id", + "started_time", + b"started_time", + ], + ) -> None: ... + +global___WorkflowTaskAttempt = WorkflowTaskAttempt + class Cancel(google.protobuf.message.Message): """Attempt to cancel a running activity""" diff --git a/temporalio/bridge/sdk-core b/temporalio/bridge/sdk-core index f49305f18e..ff30d403dc 160000 --- a/temporalio/bridge/sdk-core +++ b/temporalio/bridge/sdk-core @@ -1 +1 @@ -Subproject commit f49305f18ebd724668d5f86bf715b5ffe59287f2 +Subproject commit ff30d403dc4fcf35b888677f25b96bdbda88d323