Skip to content

Commit

Permalink
Versioning 3 Pre-Release APIs (#496)
Browse files Browse the repository at this point in the history
<!-- Describe what has changed in this PR -->
**What changed?**
Includes:

- Added `versioning_info` to `WorkflowExecutionInfo`, containing
`VersioningBehavior`, current `Deployment`, `VersioningOverride`, and
ongoing `DeploymentTransition` for an execution.
- Added Deployment APIs, for managing worker deployments:
  - `DescribeDeployment`
  - `ListDeployments`
  - `GetCurrentDeployment`
  - `SetCurrentDeployment` (tentative)
  - `GetDeploymentReachability`
- Added `UpdateWorkflowExecutionOptions` API (and its batch mode) so
users can set versioning override for executions.
- Updated data-path APIs so SDK can send `Deployment` and
`VersioningBehavior` info in task completion responses and in polls.
- Deprecated some fields and massages belonging to Versioning 1-2
pre-release.

<!-- Tell your future self why have you made these changes -->
**Why?**
Versioning 3 brings improved experience compared to last iterations of
this project. It adds two new concepts: VersioningBehavior and
Deployment. More info can be found in the proto documentation.

<!-- Are there any breaking changes on binary or code level? -->
**Breaking changes**
None. Versioning 1-2 pre-release APIs are still supported, until further
notice.

<!-- If this breaks the Server, please provide the Server PR to merge
right after this PR was merged. -->
**Server PR**
temporalio/temporal#6890

---------

Co-authored-by: Carly de Frondeville <[email protected]>
  • Loading branch information
ShahabT and carlydf authored Nov 26, 2024
1 parent 8ab82a6 commit 33cbaa8
Show file tree
Hide file tree
Showing 12 changed files with 2,423 additions and 89 deletions.
965 changes: 941 additions & 24 deletions openapi/openapiv2.json

Large diffs are not rendered by default.

1,027 changes: 981 additions & 46 deletions openapi/openapiv3.yaml

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion temporal/api/batch/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ option java_outer_classname = "MessageProto";
option ruby_package = "Temporalio::Api::Batch::V1";
option csharp_namespace = "Temporalio.Api.Batch.V1";

import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

import "temporal/api/common/v1/message.proto";
import "temporal/api/enums/v1/batch_operation.proto";
import "temporal/api/enums/v1/reset.proto";
import "temporal/api/workflow/v1/message.proto";

message BatchOperationInfo {
// Batch job ID
Expand Down Expand Up @@ -102,3 +103,17 @@ message BatchOperationReset {
temporal.api.enums.v1.ResetReapplyType reset_reapply_type = 2;

}

// BatchOperationUpdateWorkflowExecutionOptions sends UpdateWorkflowExecutionOptions requests to batch workflows.
// Keep the parameters in sync with temporal.api.workflowservice.v1.UpdateWorkflowExecutionOptionsRequest.
message BatchOperationUpdateWorkflowExecutionOptions {
// The identity of the worker/client.
string identity = 1;

// Workflow Execution options. Partial updates are accepted and controlled by update_mask.
temporal.api.workflow.v1.WorkflowExecutionOptions workflow_execution_options = 2;

// Controls which fields from `workflow_execution_options` will be applied.
// To unset a field, set it to null and use the update mask to indicate that it should be mutated.
google.protobuf.FieldMask update_mask = 3;
}
6 changes: 5 additions & 1 deletion temporal/api/common/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ message MeteringMetadata {
uint32 nonfirst_local_activity_execution_attempts = 13;
}

// Deprecated. This message is replaced with `Deployment` and `VersioningBehavior`.
// Identifies the version(s) of a worker that processed a task
message WorkerVersionStamp {
// An opaque whole-worker identifier. Replaces the deprecated `binary_checksum` field when this
Expand All @@ -136,7 +137,7 @@ message WorkerVersionStamp {
// Later, may include bundle id that could be used for WASM and/or JS dynamically loadable bundles.
}

// Identifies the version(s) that a worker is compatible with when polling or identifying itself,
// Identifies the version that a worker is compatible with when polling or identifying itself,
// and whether or not this worker is opting into the build-id based versioning feature. This is
// used by matching to determine which workers ought to receive what tasks.
message WorkerVersionCapabilities {
Expand All @@ -147,6 +148,9 @@ message WorkerVersionCapabilities {
// tasks.
bool use_versioning = 2;

// Must be sent if user has set a deployment series name (versioning-3).
string deployment_series_name = 4;

// Later, may include info like "I can process WASM and/or JS bundles"
}

Expand Down
89 changes: 89 additions & 0 deletions temporal/api/deployment/v1/message.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// The MIT License
//
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

syntax = "proto3";

package temporal.api.deployment.v1;

option go_package = "go.temporal.io/api/deployment/v1;deployment";
option java_package = "io.temporal.api.deployment.v1";
option java_multiple_files = true;
option java_outer_classname = "MessageProto";
option ruby_package = "Temporalio::Api::Deployment::V1";
option csharp_namespace = "Temporalio.Api.Deployment.V1";

import "google/protobuf/timestamp.proto";

import "temporal/api/enums/v1/task_queue.proto";
import "temporal/api/common/v1/message.proto";

// `Deployment` identifies a deployment of Temporal workers. The combination of deployment series
// name + build ID serves as the identifier. User can use `WorkerDeploymentOptions` in their worker
// programs to specify these values.
message Deployment {
// Different versions of the same worker service/application are related together by having a
// shared series name.
// Out of all deployments of a series, one can be designated as the current deployment, which
// receives new workflow executions and new tasks of workflows with
// `VERSIONING_BEHAVIOR_AUTO_UPGRADE` versioning behavior.
string series_name = 1;
// Build ID changes with each version of the worker when the worker program code and/or config
// changes.
string build_id = 2;
}

// `DeploymentInfo` holds information about a deployment. Deployment information is tracked
// automatically by server as soon as the first poll from that deployment reaches the server. There
// can be multiple task queue workers in a single deployment which are listed in this message.
message DeploymentInfo {
Deployment deployment = 1;
google.protobuf.Timestamp create_time = 2;
repeated TaskQueueInfo task_queue_infos = 3;
// A user-defined set of key-values. Can be updated as part of write operations to the
// deployment, such as `SetCurrentDeployment`.
map<string, temporal.api.common.v1.Payload> metadata = 4;
// If this deployment is the current deployment of its deployment series.
bool is_current = 5;

message TaskQueueInfo {
string name = 1;
temporal.api.enums.v1.TaskQueueType type = 2;
// When server saw the first poller for this task queue in this deployment.
google.protobuf.Timestamp first_poller_time = 3;
}
}

// Used as part of Deployment write APIs to update metadata attached to a deployment.
message UpdateDeploymentMetadata {
map<string, temporal.api.common.v1.Payload> upsert_entries = 1;
// List of keys to remove from the metadata.
repeated string remove_entries = 2;
}

// DeploymentListInfo is an abbreviated set of fields from DeploymentInfo that's returned in
// ListDeployments.
message DeploymentListInfo {
deployment.v1.Deployment deployment = 1;
google.protobuf.Timestamp create_time = 2;
// If this deployment is the current deployment of its deployment series.
bool is_current = 3;
}
49 changes: 49 additions & 0 deletions temporal/api/enums/v1/deployment.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// The MIT License
//
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

syntax = "proto3";

package temporal.api.enums.v1;

option go_package = "go.temporal.io/api/enums/v1;enums";
option java_package = "io.temporal.api.enums.v1";
option java_multiple_files = true;
option java_outer_classname = "DeploymentProto";
option ruby_package = "Temporalio::Api::Enums::V1";
option csharp_namespace = "Temporalio.Api.Enums.V1";

// Specify the reachability level for a deployment so users can decide if it is time to
// decommission the deployment.
enum DeploymentReachability {
// Reachability level is not specified.
DEPLOYMENT_REACHABILITY_UNSPECIFIED = 0;
// The deployment is reachable by new and/or open workflows. The deployment cannot be
// decommissioned safely.
DEPLOYMENT_REACHABILITY_REACHABLE = 1;
// The deployment is not reachable by new or open workflows, but might be still needed by
// Queries sent to closed workflows. The deployment can be decommissioned safely if user does
// not query closed workflows.
DEPLOYMENT_REACHABILITY_CLOSED_WORKFLOWS_ONLY = 2;
// The deployment is not reachable by any workflow because all the workflows who needed this
// deployment went out of retention period. The deployment can be decommissioned safely.
DEPLOYMENT_REACHABILITY_UNREACHABLE = 3;
}
2 changes: 2 additions & 0 deletions temporal/api/enums/v1/event_type.proto
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,6 @@ enum EventType {
EVENT_TYPE_NEXUS_OPERATION_TIMED_OUT = 53;
// A Nexus operation was requested to be canceled using a RequestCancelNexusOperation command.
EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED = 54;
// Workflow execution options updated by user.
EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED = 55;
}
24 changes: 23 additions & 1 deletion temporal/api/enums/v1/workflow.proto
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,26 @@ enum TimeoutType {
TIMEOUT_TYPE_SCHEDULE_TO_START = 2;
TIMEOUT_TYPE_SCHEDULE_TO_CLOSE = 3;
TIMEOUT_TYPE_HEARTBEAT = 4;
}
}

enum VersioningBehavior {
// Workflow execution is unversioned. This is the legacy behavior. An unversioned workflow's
// task may go to any unversioned worker who is polling for the task queue.
VERSIONING_BEHAVIOR_UNSPECIFIED = 0;
// Workflow will be pinned to the current deployment until completion. Can be overridden
// explicitly via `UpdateWorkflowExecutionOptions` API.
// Activities of `PINNED` workflows are sent to the same deployment. Exception to this would be
// when the activity task queue workers are not present in the workflows deployment, in which
// case the activity will be sent to the current deployment of its own task queue.
VERSIONING_BEHAVIOR_PINNED = 1;
// Workflow will automatically move to the current deployment of its task queue when the next
// workflow task is dispatched.
// Activities of `AUTO_UPGRADE` workflows are sent to the current deployment of the workflow
// execution based on the last completed workflow task. Exception to this would be when the
// activity task queue workers are not present in the workflow's deployment, in which case the
// activity will be sent to the current deployment of its own task queue.
// Workflows stuck on a backlogged activity will still auto-upgrade if the default deployment
// of their task queue changes, without having to wait for the backlogged activity to complete
// on the old deployment.
VERSIONING_BEHAVIOR_AUTO_UPGRADE = 2;
}
41 changes: 31 additions & 10 deletions temporal/api/history/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import "temporal/api/enums/v1/failed_cause.proto";
import "temporal/api/enums/v1/update.proto";
import "temporal/api/enums/v1/workflow.proto";
import "temporal/api/common/v1/message.proto";
import "temporal/api/deployment/v1/message.proto";
import "temporal/api/failure/v1/message.proto";
import "temporal/api/taskqueue/v1/message.proto";
import "temporal/api/update/v1/message.proto";
Expand Down Expand Up @@ -104,7 +105,7 @@ message WorkflowExecutionStartedEventAttributes {
string workflow_id = 28;
// If this workflow intends to use anything other than the current overall default version for
// the queue, then we include it here.
// Deprecated. use `inherited_build_id` instead
// Deprecated. [cleanup-experimental-wv]
temporal.api.common.v1.WorkerVersionStamp source_version_stamp = 29;
// Completion callbacks attached when this workflow was started.
repeated temporal.api.common.v1.Callback completion_callbacks = 30;
Expand All @@ -128,7 +129,10 @@ message WorkflowExecutionStartedEventAttributes {
// - The root workflow of W1 is W1 and the root workflow of W2 is W2.
temporal.api.common.v1.WorkflowExecution root_workflow_execution = 31;
// When present, this execution is assigned to the build ID of its parent or previous execution.
// Deprecated. This field should be cleaned up when versioning-2 API is removed. [cleanup-experimental-wv]
string inherited_build_id = 32;
// Versioning override applied to this workflow when it was started.
temporal.api.workflow.v1.VersioningOverride versioning_override = 33;
}

message WorkflowExecutionCompletedEventAttributes {
Expand Down Expand Up @@ -215,9 +219,11 @@ message WorkflowTaskStartedEventAttributes {
// just the event id of this event, so we don't include it explicitly here.
int64 history_size_bytes = 5;
// Version info of the worker to whom this task was dispatched.
// Deprecated. This field should be cleaned up when versioning-2 API is removed. [cleanup-experimental-wv]
temporal.api.common.v1.WorkerVersionStamp worker_version = 6;
// Used by server internally to properly reapply build ID redirects to an execution
// when rebuilding it from events.
// Deprecated. This field should be cleaned up when versioning-2 API is removed. [cleanup-experimental-wv]
int64 build_id_redirect_counter = 7;
}

Expand All @@ -233,14 +239,23 @@ message WorkflowTaskCompletedEventAttributes {
// Version info of the worker who processed this workflow task. If present, the `build_id` field
// within is also used as `binary_checksum`, which may be omitted in that case (it may also be
// populated to preserve compatibility).
// Deprecated. Use the info inside the corresponding WorkflowTaskStartedEvent
// Deprecated. Use `deployment` and `versioning_behavior` instead.
temporal.api.common.v1.WorkerVersionStamp worker_version = 5;
// Data the SDK wishes to record for itself, but server need not interpret, and does not
// directly impact workflow state.
temporal.api.sdk.v1.WorkflowTaskCompletedMetadata sdk_metadata = 6;

// Local usage data sent during workflow task completion and recorded here for posterity
temporal.api.common.v1.MeteringMetadata metering_metadata = 13;

// The deployment that completed this task. May or may not be set for unversioned workers,
// depending on whether a value is sent by the SDK. This value updates workflow execution's
// `versioning_info.deployment`.
temporal.api.deployment.v1.Deployment deployment = 7;
// Versioning behavior sent by the worker that completed this task for this particular workflow
// execution. UNSPECIFIED means the task was completed by an unversioned worker. This value
// updates workflow execution's `versioning_info.behavior`.
temporal.api.enums.v1.VersioningBehavior versioning_behavior = 8;
}

message WorkflowTaskTimedOutEventAttributes {
Expand Down Expand Up @@ -333,9 +348,11 @@ message ActivityTaskStartedEventAttributes {
// been retried.
temporal.api.failure.v1.Failure last_failure = 5;
// Version info of the worker to whom this task was dispatched.
// Deprecated. This field should be cleaned up when versioning-2 API is removed. [cleanup-experimental-wv]
temporal.api.common.v1.WorkerVersionStamp worker_version = 6;
// Used by server internally to properly reapply build ID redirects to an execution
// when rebuilding it from events.
// Deprecated. This field should be cleaned up when versioning-2 API is removed. [cleanup-experimental-wv]
int64 build_id_redirect_counter = 7;
}

Expand Down Expand Up @@ -723,19 +740,22 @@ message ChildWorkflowExecutionTerminatedEventAttributes {
int64 started_event_id = 5;
}

message WorkflowExecutionOptionsUpdatedEventAttributes {
// Versioning override in the mutable state after event has been applied.
temporal.api.workflow.v1.VersioningOverride versioning_override = 1;
}

// Not used anywhere. Use case is replaced by WorkflowExecutionOptionsUpdatedEventAttributes
message WorkflowPropertiesModifiedExternallyEventAttributes {
// If set to a nonempty string, future workflow tasks for this workflow shall be dispatched on
// the provided queue.
// Not used.
string new_task_queue = 1;
// If set, update the workflow task timeout to this value.
// Not used.
google.protobuf.Duration new_workflow_task_timeout = 2;
// If set, update the workflow run timeout to this value. May be set to 0 for no timeout.
// Not used.
google.protobuf.Duration new_workflow_run_timeout = 3;
// If set, update the workflow execution timeout to this value. May be set to 0 for no timeout.
// Not used.
google.protobuf.Duration new_workflow_execution_timeout = 4;
// If set, update the workflow memo with the provided values. The values will be merged with
// the existing memo. If the user wants to delete values, a default/empty Payload should be
// used as the value for the key being deleted.
// Not used.
temporal.api.common.v1.Memo upserted_memo = 5;
}

Expand Down Expand Up @@ -980,6 +1000,7 @@ message HistoryEvent {
NexusOperationCanceledEventAttributes nexus_operation_canceled_event_attributes = 57;
NexusOperationTimedOutEventAttributes nexus_operation_timed_out_event_attributes = 58;
NexusOperationCancelRequestedEventAttributes nexus_operation_cancel_requested_event_attributes = 59;
WorkflowExecutionOptionsUpdatedEventAttributes workflow_execution_options_updated_event_attributes = 60;
}
}

Expand Down
Loading

0 comments on commit 33cbaa8

Please sign in to comment.