syntax = "proto3";
package temporal.api.taskqueue.v1;
option go_package = "go.temporal.io/api/taskqueue/v1;taskqueue";
option java_package = "io.temporal.api.taskqueue.v1";
option java_multiple_files = true;
option java_outer_classname = "MessageProto";
option ruby_package = "Temporalio::Api::TaskQueue::V1";
option csharp_namespace = "Temporalio.Api.TaskQueue.V1";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "temporal/api/enums/v1/task_queue.proto";
import "temporal/api/common/v1/message.proto";
import "temporal/api/deployment/v1/message.proto";
// See https://docs.temporal.io/docs/concepts/task-queues/
message TaskQueue {
string name = 1;
// Default: TASK_QUEUE_KIND_NORMAL.
temporal.api.enums.v1.TaskQueueKind kind = 2;
// Iff kind == TASK_QUEUE_KIND_STICKY, then this field contains the name of
// the normal task queue that the sticky worker is running on.
string normal_name = 3;
}
// Only applies to activity task queues
message TaskQueueMetadata {
// Allows throttling dispatch of tasks from this queue
google.protobuf.DoubleValue max_tasks_per_second = 1;
}
message TaskQueueVersioningInfo {
// Specifies which Deployment Version should receive new workflow executions and tasks of
// existing unversioned or AutoUpgrade workflows.
// Nil value represents all the unversioned workers (those with `UNVERSIONED` (or unspecified) `WorkerVersioningMode`.)
// Note: Current Version is overridden by the Ramping Version for a portion of traffic when ramp percentage
// is non-zero (see `ramping_deployment_version` and `ramping_version_percentage`).
temporal.api.deployment.v1.WorkerDeploymentVersion current_deployment_version = 7;
// Deprecated. Use `current_deployment_version`.
string current_version = 1 [deprecated = true];
// When ramp percentage is non-zero, that portion of traffic is shifted from the Current Version to the Ramping Version.
// Must always be different from `current_deployment_version` unless both are nil.
// Nil value represents all the unversioned workers (those with `UNVERSIONED` (or unspecified) `WorkerVersioningMode`.)
// Note that it is possible to ramp from one Version to another Version, or from unversioned
// workers to a particular Version, or from a particular Version to unversioned workers.
temporal.api.deployment.v1.WorkerDeploymentVersion ramping_deployment_version = 9;
// Deprecated. Use `ramping_deployment_version`.
string ramping_version = 2 [deprecated = true];
// Percentage of tasks that are routed to the Ramping Version instead of the Current Version.
// Valid range: [0, 100]. A 100% value means the Ramping Version is receiving full traffic but
// not yet "promoted" to be the Current Version, likely due to pending validations.
// A 0% value means the Ramping Version is receiving no traffic.
float ramping_version_percentage = 3;
// Last time versioning information of this Task Queue changed.
google.protobuf.Timestamp update_time = 4;
}
// Used for specifying versions the caller is interested in.
message TaskQueueVersionSelection {
// Include specific Build IDs.
repeated string build_ids = 1;
// Include the unversioned queue.
bool unversioned = 2;
// Include all active versions. A version is considered active if, in the last few minutes,
// it has had new tasks or polls, or it has been the subject of certain task queue API calls.
bool all_active = 3;
}
message TaskQueueVersionInfo {
// Task Queue info per Task Type. Key is the numerical value of the temporal.api.enums.v1.TaskQueueType enum.
map<int32, TaskQueueTypeInfo> types_info = 1;
// Task Reachability is eventually consistent; there may be a delay until it converges to the most
// accurate value but it is designed in a way to take the more conservative side until it converges.
// For example REACHABLE is more conservative than CLOSED_WORKFLOWS_ONLY.
//
// Note: future activities who inherit their workflow's Build ID but not its Task Queue will not be
// accounted for reachability as server cannot know if they'll happen as they do not use
// assignment rules of their Task Queue. Same goes for Child Workflows or Continue-As-New Workflows
// who inherit the parent/previous workflow's Build ID but not its Task Queue. In those cases, make
// sure to query reachability for the parent/previous workflow's Task Queue as well.
temporal.api.enums.v1.BuildIdTaskReachability task_reachability = 2;
}
message TaskQueueTypeInfo {
// Unversioned workers (with `useVersioning=false`) are reported in unversioned result even if they set a Build ID.
repeated PollerInfo pollers = 1;
TaskQueueStats stats = 2;
}
// TaskQueueStats contains statistics about task queue backlog and activity.
//
// For workflow task queue type, this result is partial because tasks sent to sticky queues are not included. Read
// comments above each metric to understand the impact of sticky queue exclusion on that metric accuracy.
message TaskQueueStats {
// The approximate number of tasks backlogged in this task queue. May count expired tasks but eventually
// converges to the right value. Can be relied upon for scaling decisions.
//
// Special note for workflow task queue type: this metric does not count sticky queue tasks. However, because
// those tasks only remain valid for a few seconds, the inaccuracy becomes less significant as the backlog size
// grows.
int64 approximate_backlog_count = 1;
// Approximate age of the oldest task in the backlog based on the creation time of the task at the head of
// the queue. Can be relied upon for scaling decisions.
//
// Special note for workflow task queue type: this metric does not count sticky queue tasks. However, because
// those tasks only remain valid for a few seconds, they should not affect the result when backlog is older than
// few seconds.
google.protobuf.Duration approximate_backlog_age = 2;
// The approximate tasks per second added to the task queue, averaging the last 30 seconds. These includes tasks
// whether or not they were added to/dispatched from the backlog or they were dispatched immediately without going
// to the backlog (sync-matched).
//
// The difference between `tasks_add_rate` and `tasks_dispatch_rate` is a reliable metric for the rate at which
// backlog grows/shrinks.
//
// Note: the actual tasks delivered to the workers may significantly be higher than the numbers reported by
// tasks_add_rate, because:
// - Tasks can be sent to workers without going to the task queue. This is called Eager dispatch. Eager dispatch is
// enable for activities by default in the latest SDKs.
// - Tasks going to Sticky queue are not accounted for. Note that, typically, only the first workflow task of each
// workflow goes to a normal queue, and the rest workflow tasks go to the Sticky queue associated with a specific
// worker instance.
float tasks_add_rate = 3;
// The approximate tasks per second dispatched from the task queue, averaging the last 30 seconds. These includes
// tasks whether or not they were added to/dispatched from the backlog or they were dispatched immediately without
// going to the backlog (sync-matched).
//
// The difference between `tasks_add_rate` and `tasks_dispatch_rate` is a reliable metric for the rate at which
// backlog grows/shrinks.
//
// Note: the actual tasks delivered to the workers may significantly be higher than the numbers reported by
// tasks_dispatch_rate, because:
// - Tasks can be sent to workers without going to the task queue. This is called Eager dispatch. Eager dispatch is
// enable for activities by default in the latest SDKs.
// - Tasks going to Sticky queue are not accounted for. Note that, typically, only the first workflow task of each
// workflow goes to a normal queue, and the rest workflow tasks go to the Sticky queue associated with a specific
// worker instance.
float tasks_dispatch_rate = 4;
}
// Deprecated. Use `InternalTaskQueueStatus`. This is kept until `DescribeTaskQueue` supports legacy behavior.
message TaskQueueStatus {
int64 backlog_count_hint = 1;
int64 read_level = 2;
int64 ack_level = 3;
double rate_per_second = 4;
TaskIdBlock task_id_block = 5;
}
message TaskIdBlock {
int64 start_id = 1;
int64 end_id = 2;
}
message TaskQueuePartitionMetadata {
string key = 1;
string owner_host_name = 2;
}
message PollerInfo {
google.protobuf.Timestamp last_access_time = 1;
string identity = 2;
double rate_per_second = 3;
// If a worker has opted into the worker versioning feature while polling, its capabilities will
// appear here.
// Deprecated. Replaced by deployment_options.
temporal.api.common.v1.WorkerVersionCapabilities worker_version_capabilities = 4 [deprecated = true];
// Worker deployment options that SDK sent to server.
temporal.api.deployment.v1.WorkerDeploymentOptions deployment_options = 5;
}
message StickyExecutionAttributes {
TaskQueue worker_task_queue = 1;
// (-- api-linter: core::0140::prepositions=disabled
// aip.dev/not-precedent: "to" is used to indicate interval. --)
google.protobuf.Duration schedule_to_start_timeout = 2;
}
// Used by the worker versioning APIs, represents an unordered set of one or more versions which are
// considered to be compatible with each other. Currently the versions are always worker build IDs.
message CompatibleVersionSet {
// All the compatible versions, unordered, except for the last element, which is considered the set "default".
repeated string build_ids = 1;
}
// Reachability of tasks for a worker on a single task queue.
message TaskQueueReachability {
string task_queue = 1;
// Task reachability for a worker in a single task queue.
// See the TaskReachability docstring for information about each enum variant.
// If reachability is empty, this worker is considered unreachable in this task queue.
repeated temporal.api.enums.v1.TaskReachability reachability = 2;
}
// Reachability of tasks for a worker by build id, in one or more task queues.
message BuildIdReachability {
// A build id or empty if unversioned.
string build_id = 1;
// Reachability per task queue.
repeated TaskQueueReachability task_queue_reachability = 2;
}
message RampByPercentage {
// Acceptable range is [0,100).
float ramp_percentage = 1;
}
// Assignment rules are applied to *new* Workflow and Activity executions at
// schedule time to assign them to a Build ID.
//
// Assignment rules will not be used in the following cases:
// - Child Workflows or Continue-As-New Executions who inherit their
// parent/previous Workflow's assigned Build ID (by setting the
// `inherit_build_id` flag - default behavior in SDKs when the same Task Queue
// is used.)
// - An Activity that inherits the assigned Build ID of its Workflow (by
// setting the `use_workflow_build_id` flag - default behavior in SDKs
// when the same Task Queue is used.)
//
// In absence of (applicable) redirect rules (`CompatibleBuildIdRedirectRule`s)
// the task will be dispatched to Workers of the Build ID determined by the
// assignment rules (or inherited). Otherwise, the final Build ID will be
// determined by the redirect rules.
//
// Once a Workflow completes its first Workflow Task in a particular Build ID it
// stays in that Build ID regardless of changes to assignment rules. Redirect
// rules can be used to move the workflow to another compatible Build ID.
//
// When using Worker Versioning on a Task Queue, in the steady state,
// there should typically be a single assignment rule to send all new executions
// to the latest Build ID. Existence of at least one such "unconditional"
// rule at all times is enforces by the system, unless the `force` flag is used
// by the user when replacing/deleting these rules (for exceptional cases).
//
// During a deployment, one or more additional rules can be added to assign a
// subset of the tasks to a new Build ID based on a "ramp percentage".
//
// When there are multiple assignment rules for a Task Queue, the rules are
// evaluated in order, starting from index 0. The first applicable rule will be
// applied and the rest will be ignored.
//
// In the event that no assignment rule is applicable on a task (or the Task
// Queue is simply not versioned), the tasks will be dispatched to an
// unversioned Worker.
message BuildIdAssignmentRule {
string target_build_id = 1;
// If a ramp is provided, this rule will be applied only to a sample of
// tasks according to the provided percentage.
// This option can be used only on "terminal" Build IDs (the ones not used
// as source in any redirect rules).
oneof ramp {
// This ramp is useful for gradual Blue/Green deployments (and similar)
// where you want to send a certain portion of the traffic to the target
// Build ID.
RampByPercentage percentage_ramp = 3;
}
}
// These rules apply to tasks assigned to a particular Build ID
// (`source_build_id`) to redirect them to another *compatible* Build ID
// (`target_build_id`).
//
// It is user's responsibility to ensure that the target Build ID is compatible
// with the source Build ID (e.g. by using the Patching API).
//
// Most deployments are not expected to need these rules, however following
// situations can greatly benefit from redirects:
// - Need to move long-running Workflow Executions from an old Build ID to a
// newer one.
// - Need to hotfix some broken or stuck Workflow Executions.
//
// In steady state, redirect rules are beneficial when dealing with old
// Executions ran on now-decommissioned Build IDs:
// - To redirecting the Workflow Queries to the current (compatible) Build ID.
// - To be able to Reset an old Execution so it can run on the current
// (compatible) Build ID.
//
// Redirect rules can be chained.
message CompatibleBuildIdRedirectRule {
string source_build_id = 1;
// Target Build ID must be compatible with the Source Build ID; that is it
// must be able to process event histories made by the Source Build ID by
// using [Patching](https://docs.temporal.io/workflows#patching) or other
// means.
string target_build_id = 2;
}
message TimestampedBuildIdAssignmentRule {
BuildIdAssignmentRule rule = 1;
google.protobuf.Timestamp create_time = 2;
}
message TimestampedCompatibleBuildIdRedirectRule {
CompatibleBuildIdRedirectRule rule = 1;
google.protobuf.Timestamp create_time = 2;
}
message PollerGroupInfo {
string id = 1;
float weight = 2;
}
// Attached to task responses to give hints to the SDK about how it may adjust its number of
// pollers.
message PollerScalingDecision {
// How many poll requests to suggest should be added or removed, if any. As of now, server only
// scales up or down by 1. However, SDKs should allow for other values (while staying within
// defined min/max).
//
// The SDK is free to ignore this suggestion, EX: making more polls would not make sense because
// all slots are already occupied.
int32 poll_request_delta_suggestion = 1;
}
message RateLimit {
// Zero is a valid rate limit.
float requests_per_second = 1;
}
message ConfigMetadata {
// Reason for why the config was set.
string reason = 1;
// Identity of the last updater.
// Set by the request's identity field.
string update_identity = 2;
// Time of the last update.
google.protobuf.Timestamp update_time = 3;
}
message RateLimitConfig {
RateLimit rate_limit = 1;
ConfigMetadata metadata = 2;
}
message TaskQueueConfig {
// Unless modified, this is the system-defined rate limit.
RateLimitConfig queue_rate_limit = 1;
// If set, each individual fairness key will be limited to this rate, scaled by the weight of the fairness key.
RateLimitConfig fairness_keys_rate_limit_default = 2;
// If set, overrides the fairness weights for the corresponding fairness keys.
map<string, float> fairness_weight_overrides = 3;
}