diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 000000000..b962fdb8d --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,135 @@ +name: "Create release" + +on: + workflow_dispatch: + inputs: + branch: + description: "Branch to be tagged" + required: true + default: master + tag: + description: "Tag for new version (v1.23.4)" + required: true + base_tag: + description: "Base tag to generate commit list for release notes" + required: true + skip_sdk_check: + description: "Skip sdk-go compatibility check" + type: boolean + +jobs: + prepare-inputs: + name: "Prepare inputs" + runs-on: ubuntu-latest + outputs: + api_commit_sha: ${{ steps.pin_commits.outputs.api_commit_sha }} + api_go_commit_sha: ${{ steps.pin_commits.outputs.api_go_commit_sha }} + steps: + - name: Checkout api + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.branch }} + fetch-depth: 0 + fetch-tags: true + path: api + + - name: Checkout api-go + uses: actions/checkout@v4 + with: + repository: temporalio/api-go + ref: ${{ github.event.inputs.branch }} + submodules: true + path: api-go + + - name: Validate inputs + env: + BRANCH: ${{ github.event.inputs.branch }} + TAG: ${{ github.event.inputs.tag }} + BASE_TAG: ${{ github.event.inputs.base_tag }} + working-directory: ./api + run: | + if ! [[ "${TAG}" =~ ^v.* ]]; then + echo "::error::Tag is not prefixed with 'v'" + exit 1 + fi + + if [[ -n "$(git tag -l "$TAG")" ]]; then + echo "::error::Tag already exists" + exit 1 + fi + + if [[ -z "$BASE_TAG" || -z "$(git tag -l "$BASE_TAG")" ]]; then + echo "::error::Base tag not specified or does not exist" + exit 1 + fi + + - name: Pin commits sha + id: pin_commits + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: ${{ github.event.inputs.branch }} + run: | + API_COMMIT_SHA=$(git -C ./api rev-parse HEAD) + API_GO_COMMIT_SHA=$(git -C ./api-go rev-parse HEAD) + API_GO_API_COMMIT_SHA=$(git -C ./api-go rev-parse HEAD:proto/api) + if [[ "${API_GO_API_COMMIT_SHA}" != "${API_COMMIT_SHA}" ]]; then + echo "::error::api-go ref ${API_GO_COMMIT_SHA} does not reference api ref ${API_COMMIT_SHA}, api-go repo might not be up-to-date." + exit 1 + fi + echo "api_commit_sha=$API_COMMIT_SHA" >> "$GITHUB_OUTPUT" + echo "api_go_commit_sha=$API_GO_COMMIT_SHA" >> "$GITHUB_OUTPUT" + + check-compatibility-sdk-go: + needs: prepare-inputs + if: ${{ github.event.inputs.skip_sdk_check == false || github.event.inputs.skip_sdk_check == 'false' }} + uses: temporalio/api-go/.github/workflows/check-sdk-compat.yml@master + with: + sdk_ref: latest + api_ref: ${{ needs.prepare-inputs.outputs.api_go_commit_sha }} + + create-release: + name: "Create release" + needs: [prepare-inputs, check-compatibility-sdk-go] + if: | + !cancelled() && + needs.prepare-inputs.result == 'success' && + contains(fromJSON('["success", "skipped"]'), needs.check-compatibility-sdk-go.result) + runs-on: ubuntu-latest + + steps: + - name: Generate token + id: generate_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.TEMPORAL_CICD_APP_ID }} + private-key: ${{ secrets.TEMPORAL_CICD_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ needs.prepare-inputs.outputs.api_commit_sha }} + token: ${{ steps.generate_token.outputs.token }} + + - name: Create release + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + REF: ${{ needs.prepare-inputs.outputs.api_commit_sha }} + TAG: ${{ github.event.inputs.tag }} + BASE_TAG: ${{ github.event.inputs.base_tag }} + run: | + gh repo set-default ${{ github.repository }} + gh release create "$TAG" --target "$REF" --latest --generate-notes --notes-start-tag "$BASE_TAG" --draft + + release-api-go: + needs: [prepare-inputs, create-release] + if: | + !cancelled() && + needs.create-release.result == 'success' + uses: temporalio/api-go/.github/workflows/create-release.yml@master + with: + ref: ${{ needs.prepare-inputs.outputs.api_go_commit_sha }} + tag: ${{ github.event.inputs.tag }} + api_commit_sha: ${{ needs.prepare-inputs.outputs.api_commit_sha }} + base_tag: ${{ github.event.inputs.base_tag }} + secrets: inherit diff --git a/.github/workflows/trigger-api-go-delete-release.yml b/.github/workflows/trigger-api-go-delete-release.yml new file mode 100644 index 000000000..e5b30efa0 --- /dev/null +++ b/.github/workflows/trigger-api-go-delete-release.yml @@ -0,0 +1,13 @@ +name: "Trigger api-go delete release" + +on: + release: + types: [deleted] + +jobs: + trigger-api-go-delete-release: + uses: temporalio/api-go/.github/workflows/delete-release.yml@master + with: + tag: ${{ github.event.release.tag_name }} + api_commit_sha: ${{ github.event.release.target_commitish }} + secrets: inherit diff --git a/.github/workflows/trigger-api-go-publish-release.yml b/.github/workflows/trigger-api-go-publish-release.yml new file mode 100644 index 000000000..e8c7c6f75 --- /dev/null +++ b/.github/workflows/trigger-api-go-publish-release.yml @@ -0,0 +1,13 @@ +name: "Trigger api-go publish release" + +on: + release: + types: [published] + +jobs: + trigger-api-go-publish-release: + uses: temporalio/api-go/.github/workflows/publish-release.yml@master + with: + tag: ${{ github.event.release.tag_name }} + api_commit_sha: ${{ github.event.release.target_commitish }} + secrets: inherit diff --git a/Makefile b/Makefile index 243b54914..2023d3404 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SHELL=/bin/bash -o pipefail +SHELL=bash -o pipefail $(VERBOSE).SILENT: ############################# Main targets ############################# diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index b961ba800..8c7ef5354 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -6367,6 +6367,10 @@ "versioningOverride": { "$ref": "#/definitions/v1VersioningOverride", "description": "If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion.\nTo unset the override after the workflow is running, use UpdateWorkflowExecutionOptions." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } } }, @@ -6552,6 +6556,10 @@ "versioningOverride": { "$ref": "#/definitions/v1VersioningOverride", "description": "If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion.\nTo unset the override after the workflow is running, use UpdateWorkflowExecutionOptions." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } } }, @@ -7179,6 +7187,10 @@ "useWorkflowBuildId": { "type": "boolean", "description": "If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise,\nAssignment rules of the activity's Task Queue will be used to determine the Build ID." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "description": "Priority metadata. If this message is not present, or any fields are not\npresent, they inherit the values from the workflow." } } }, @@ -9729,6 +9741,10 @@ "versioningOverride": { "$ref": "#/definitions/v1VersioningOverride", "description": "If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion.\nTo unset the override after the workflow is running, use UpdateWorkflowExecutionOptions." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } }, "description": "NewWorkflowExecutionInfo is a shared message that encapsulates all the\nrequired arguments to starting a workflow in different contexts." @@ -10100,6 +10116,10 @@ "lastDeployment": { "$ref": "#/definitions/v1Deployment", "description": "The deployment this activity was dispatched to most recently. Present only if the activity\nwas dispatched to a versioned worker." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } } }, @@ -10320,6 +10340,10 @@ "retryPolicy": { "$ref": "#/definitions/v1RetryPolicy", "description": "This is the retry policy the service uses which may be different from the one provided\n(or not) during activity scheduling. The service can override the provided one if some\nvalues are not specified or exceed configured system limits." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } } }, @@ -10452,6 +10476,36 @@ } } }, + "v1Priority": { + "type": "object", + "properties": { + "priorityKey": { + "type": "integer", + "format": "int32", + "description": "Priority key is a positive integer from 1 to n, where smaller integers\ncorrespond to higher priorities (tasks run sooner). In general, tasks in\na queue should be processed in close to priority order, although small\ndeviations are possible.\n\nThe maximum priority value (minimum priority) is determined by server\nconfiguration, and defaults to 5.\n\nIf priority is not present (or zero), then the effective priority will be\nthe default priority, which is is calculated by (min+max)/2. With the\ndefault max of 5, and min of 1, that comes out to 3." + }, + "fairnessKey": { + "type": "string", + "description": "Fairness key is a short string that's used as a key for a fairness\nbalancing mechanism. It may correspond to a tenant id, or to a fixed\nstring like \"high\" or \"low\". The default is the empty string.\n\nThe fairness mechanism attempts to dispatch tasks for a given key in\nproportion to its weight. For example, using a thousand distinct tenant\nids, each with a weight of 1.0 (the default) will result in each tenant\ngetting a roughly equal share of task dispatch throughput.\n\n(Note: this does not imply equal share of worker capacity! Fairness\ndecisions are made only at dispatch time based on queue statistics, not\ncurrent worker load.)\n\nAs another example, using keys \"high\" and \"low\" with weight 9.0 and 1.0\nrespectively will prefer dispatching \"high\" tasks over \"low\" tasks at a\n9:1 ratio, while allowing either key to use all worker capacity if the\nother is not present.\n\nAll fairness mechanisms, including rate limits, are best-effort and\nprobabilistic. The results may not match what a \"perfect\" algorithm with\ninfinite resources would produce. The more unique keys are used, the less\naccurate the results will be.\n\nFairness keys are limited to 64 bytes." + }, + "fairnessWeight": { + "type": "number", + "format": "float", + "description": "Fairness weight for a task can come from multiple sources for\nflexibility. From highest to lowest precedence:\n1. Weights for a small set of keys can be overridden in task queue\n configuration with an API.\n2. It can be attached to the workflow/activity in this field.\n3. The default weight of 1.0 will be used.\nNote that if the weight for a key is attached in this field, for best\nresults, the same weight should be used for the same key for a reasonable\namount of time (minutes). It may change, but it may take some time for\nthe change to be reflected.\n\nThe recommended range of usable weights is [0.001, 1000]." + }, + "fairnessRateLimit": { + "type": "number", + "format": "float", + "description": "The fairness mechanism can also enforce rate limits per fairness key.\nRate limits are specified in tasks dispatched per second.\nAs with weights, rate limits can come from different sources:\n1. Rate limits for a small set of keys can be overridden in task queue\n configuration with an API.\n2. It can be attached to the workflow/activity in this field.\n3. The \"default\" rate limit for keys that are not overridden can be set\n in task queue configuration also.\n4. Otherwise, a very high rate limit will be applied." + }, + "orderingKey": { + "type": "string", + "format": "int64", + "description": "Ordering key is a positive integer from 1 to MaxInt64. After priority and\nfairness mechanisms are applied, tasks will be finally ordered by\nordering_key. Note that fine-grained values are allowed here, as opposed\nto priority.\n\nFor example, applications might use the start time of a workflow (in\nseconds since the unix epoch) as ordering key for the workflow and all\nactivities in it. This will have the effect of prioritizing activities of\nworkflows that were started earlier, encouring completing older workflows\nover making progress in newer ones." + } + }, + "description": "Priority contains metadata that controls relative ordering of task processing\nwhen tasks are backed up in a queue. Initially, Priority will be used in\nmatching (workflow and activity) task queues. Later it may be used in history\ntask queues and in rate limiting decisions.\n\nPriority is attached to workflows and activities. By default, activities\ninherit Priority from the workflow that created them, but may override fields\nwhen an activity is started or modified.\n\nDespite being named \"Priority\", this message also contains fields that\ncontrol \"fairness\" mechanisms.\n\nFor all fields, the field not present or equal to zero/empty string means to\ninherit the value from the calling workflow, or if there is no calling\nworkflow, then use the default value.\n\nFor all fields other than fairness_key, the zero value isn't meaningful so\nthere's no confusion between inherit/default and a meaningful value. For\nfairness_key, the empty string will be interpreted as \"inherit\". This means\nthat if a workflow has a non-empty fairness key, you can't override the\nfairness key of its activity to the empty string.\n\nThe overall semantics of Priority are:\n1. First, consider \"priority\": higher priority (lower number) goes first.\n2. Next, consider fairness: try to dispatch tasks for different fairness keys\n in proportion to their weight.\n3. Finally, tasks may be ordered by an additional ordering key.\n\nApplications may use any subset of mechanisms that are useful to them and\nleave the other fields to use default values.\n\nNot all queues in the system may support the \"full\" semantics of all priority\nfields. (Currently only support in matching task queues is planned.)" + }, "v1ProtocolMessageCommandAttributes": { "type": "object", "properties": { @@ -10537,6 +10591,10 @@ "cancelRequested": { "type": "boolean", "description": "Will be set to true if the activity has been asked to cancel itself. The SDK should then\nnotify the activity of cancellation if it is still running." + }, + "activityPaused": { + "type": "boolean", + "description": "Will be set to true if the activity is paused." } } }, @@ -11154,6 +11212,10 @@ "useWorkflowBuildId": { "type": "boolean", "description": "If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise,\nAssignment rules of the activity's Task Queue will be used to determine the Build ID." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "description": "Priority metadata. If this message is not present, or any fields are not\npresent, they inherit the values from the workflow." } } }, @@ -11699,6 +11761,10 @@ "inheritBuildId": { "type": "boolean", "description": "If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment\nrules of the child's Task Queue will be used to independently assign a Build ID to it." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "description": "Priority metadata. If this message is not present, or any fields are not\npresent, they inherit the values from the workflow." } } }, @@ -11816,6 +11882,10 @@ "inheritBuildId": { "type": "boolean", "description": "If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment\nrules of the child's Task Queue will be used to independently assign a Build ID to it." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } } }, @@ -12004,6 +12074,10 @@ "versioningOverride": { "$ref": "#/definitions/v1VersioningOverride", "description": "If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion.\nTo unset the override after the workflow is running, use UpdateWorkflowExecutionOptions." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } } }, @@ -13055,6 +13129,10 @@ "versioningInfo": { "$ref": "#/definitions/v1WorkflowExecutionVersioningInfo", "description": "Absent value means the workflow execution is not versioned. When present, the execution might\nbe versioned or unversioned, depending on `versioning_info.behavior` and `versioning_info.versioning_override`.\nExperimental. Versioning info is experimental and might change in the future." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } }, "description": "Hold basic information about a workflow execution.\nThis structure is a part of visibility, and thus contain a limited subset of information." @@ -13073,7 +13151,11 @@ "properties": { "versioningOverride": { "$ref": "#/definitions/v1VersioningOverride", - "description": "Versioning override in the mutable state after event has been applied." + "description": "Versioning override upserted in this event.\nIgnored if nil or if unset_versioning_override is true." + }, + "unsetVersioningOverride": { + "type": "boolean", + "description": "Versioning override removed in this event." } } }, @@ -13237,6 +13319,10 @@ "versioningOverride": { "$ref": "#/definitions/v1VersioningOverride", "description": "Versioning override applied to this workflow when it was started." + }, + "priority": { + "$ref": "#/definitions/v1Priority", + "title": "Priority metadata" } }, "title": "Always the first event in workflow history" diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 015474359..33048b886 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -5119,6 +5119,12 @@ components: description: |- If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise, Assignment rules of the activity's Task Queue will be used to determine the Build ID. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: |- + Priority metadata. If this message is not present, or any fields are not + present, they inherit the values from the workflow. ActivityTaskStartedEventAttributes: type: object properties: @@ -7235,6 +7241,10 @@ components: description: |- If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion. To unset the override after the workflow is running, use UpdateWorkflowExecutionOptions. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: Priority metadata description: |- NewWorkflowExecutionInfo is a shared message that encapsulates all the required arguments to starting a workflow in different contexts. @@ -7589,6 +7599,10 @@ components: description: |- The deployment this activity was dispatched to most recently. Present only if the activity was dispatched to a versioned worker. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: Priority metadata PendingChildExecutionInfo: type: object properties: @@ -7807,6 +7821,127 @@ components: description: |- If a worker has opted into the worker versioning feature while polling, its capabilities will appear here. + Priority: + type: object + properties: + priorityKey: + type: integer + description: |- + Priority key is a positive integer from 1 to n, where smaller integers + correspond to higher priorities (tasks run sooner). In general, tasks in + a queue should be processed in close to priority order, although small + deviations are possible. + + The maximum priority value (minimum priority) is determined by server + configuration, and defaults to 5. + + If priority is not present (or zero), then the effective priority will be + the default priority, which is is calculated by (min+max)/2. With the + default max of 5, and min of 1, that comes out to 3. + format: int32 + fairnessKey: + type: string + description: |- + Fairness key is a short string that's used as a key for a fairness + balancing mechanism. It may correspond to a tenant id, or to a fixed + string like "high" or "low". The default is the empty string. + + The fairness mechanism attempts to dispatch tasks for a given key in + proportion to its weight. For example, using a thousand distinct tenant + ids, each with a weight of 1.0 (the default) will result in each tenant + getting a roughly equal share of task dispatch throughput. + + (Note: this does not imply equal share of worker capacity! Fairness + decisions are made only at dispatch time based on queue statistics, not + current worker load.) + + As another example, using keys "high" and "low" with weight 9.0 and 1.0 + respectively will prefer dispatching "high" tasks over "low" tasks at a + 9:1 ratio, while allowing either key to use all worker capacity if the + other is not present. + + All fairness mechanisms, including rate limits, are best-effort and + probabilistic. The results may not match what a "perfect" algorithm with + infinite resources would produce. The more unique keys are used, the less + accurate the results will be. + + Fairness keys are limited to 64 bytes. + fairnessWeight: + type: number + description: |- + Fairness weight for a task can come from multiple sources for + flexibility. From highest to lowest precedence: + 1. Weights for a small set of keys can be overridden in task queue + configuration with an API. + 2. It can be attached to the workflow/activity in this field. + 3. The default weight of 1.0 will be used. + Note that if the weight for a key is attached in this field, for best + results, the same weight should be used for the same key for a reasonable + amount of time (minutes). It may change, but it may take some time for + the change to be reflected. + + The recommended range of usable weights is [0.001, 1000]. + format: float + fairnessRateLimit: + type: number + description: |- + The fairness mechanism can also enforce rate limits per fairness key. + Rate limits are specified in tasks dispatched per second. + As with weights, rate limits can come from different sources: + 1. Rate limits for a small set of keys can be overridden in task queue + configuration with an API. + 2. It can be attached to the workflow/activity in this field. + 3. The "default" rate limit for keys that are not overridden can be set + in task queue configuration also. + 4. Otherwise, a very high rate limit will be applied. + format: float + orderingKey: + type: string + description: |- + Ordering key is a positive integer from 1 to MaxInt64. After priority and + fairness mechanisms are applied, tasks will be finally ordered by + ordering_key. Note that fine-grained values are allowed here, as opposed + to priority. + + For example, applications might use the start time of a workflow (in + seconds since the unix epoch) as ordering key for the workflow and all + activities in it. This will have the effect of prioritizing activities of + workflows that were started earlier, encouring completing older workflows + over making progress in newer ones. + description: |- + Priority contains metadata that controls relative ordering of task processing + when tasks are backed up in a queue. Initially, Priority will be used in + matching (workflow and activity) task queues. Later it may be used in history + task queues and in rate limiting decisions. + + Priority is attached to workflows and activities. By default, activities + inherit Priority from the workflow that created them, but may override fields + when an activity is started or modified. + + Despite being named "Priority", this message also contains fields that + control "fairness" mechanisms. + + For all fields, the field not present or equal to zero/empty string means to + inherit the value from the calling workflow, or if there is no calling + workflow, then use the default value. + + For all fields other than fairness_key, the zero value isn't meaningful so + there's no confusion between inherit/default and a meaningful value. For + fairness_key, the empty string will be interpreted as "inherit". This means + that if a workflow has a non-empty fairness key, you can't override the + fairness key of its activity to the empty string. + + The overall semantics of Priority are: + 1. First, consider "priority": higher priority (lower number) goes first. + 2. Next, consider fairness: try to dispatch tasks for different fairness keys + in proportion to their weight. + 3. Finally, tasks may be ordered by an additional ordering key. + + Applications may use any subset of mechanisms that are useful to them and + leave the other fields to use default values. + + Not all queues in the system may support the "full" semantics of all priority + fields. (Currently only support in matching task queues is planned.) QueryRejected: type: object properties: @@ -7906,6 +8041,9 @@ components: description: |- Will be set to true if the activity has been asked to cancel itself. The SDK should then notify the activity of cancellation if it is still running. + activityPaused: + type: boolean + description: Will be set to true if the activity is paused. RecordActivityTaskHeartbeatRequest: type: object properties: @@ -9060,6 +9198,10 @@ components: description: |- If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion. To unset the override after the workflow is running, use UpdateWorkflowExecutionOptions. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: Priority metadata SignalWithStartWorkflowExecutionResponse: type: object properties: @@ -9256,6 +9398,10 @@ components: description: |- If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment rules of the child's Task Queue will be used to independently assign a Build ID to it. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: Priority metadata StartWorkflowExecutionRequest: type: object properties: @@ -9379,6 +9525,10 @@ components: description: |- If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion. To unset the override after the workflow is running, use UpdateWorkflowExecutionOptions. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: Priority metadata StartWorkflowExecutionResponse: type: object properties: @@ -10553,6 +10703,10 @@ components: Absent value means the workflow execution is not versioned. When present, the execution might be versioned or unversioned, depending on `versioning_info.behavior` and `versioning_info.versioning_override`. Experimental. Versioning info is experimental and might change in the future. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: Priority metadata description: |- Hold basic information about a workflow execution. This structure is a part of visibility, and thus contain a limited subset of information. @@ -10569,7 +10723,12 @@ components: versioningOverride: allOf: - $ref: '#/components/schemas/VersioningOverride' - description: Versioning override in the mutable state after event has been applied. + description: |- + Versioning override upserted in this event. + Ignored if nil or if unset_versioning_override is true. + unsetVersioningOverride: + type: boolean + description: Versioning override removed in this event. WorkflowExecutionSignaledEventAttributes: type: object properties: @@ -10743,6 +10902,10 @@ components: allOf: - $ref: '#/components/schemas/VersioningOverride' description: Versioning override applied to this workflow when it was started. + priority: + allOf: + - $ref: '#/components/schemas/Priority' + description: Priority metadata description: Always the first event in workflow history WorkflowExecutionTerminatedEventAttributes: type: object diff --git a/temporal/api/command/v1/message.proto b/temporal/api/command/v1/message.proto index 3b8c9d9fe..48513fe43 100644 --- a/temporal/api/command/v1/message.proto +++ b/temporal/api/command/v1/message.proto @@ -85,6 +85,9 @@ message ScheduleActivityTaskCommandAttributes { // If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise, // Assignment rules of the activity's Task Queue will be used to determine the Build ID. bool use_workflow_build_id = 13; + // Priority metadata. If this message is not present, or any fields are not + // present, they inherit the values from the workflow. + temporal.api.common.v1.Priority priority = 14; } message RequestCancelActivityTaskCommandAttributes { @@ -226,6 +229,9 @@ message StartChildWorkflowExecutionCommandAttributes { // If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment // rules of the child's Task Queue will be used to independently assign a Build ID to it. bool inherit_build_id = 17; + // Priority metadata. If this message is not present, or any fields are not + // present, they inherit the values from the workflow. + temporal.api.common.v1.Priority priority = 18; } message ProtocolMessageCommandAttributes { diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 69713fb53..6a79c1339 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -246,3 +246,114 @@ message Link { BatchJob batch_job = 2; } } + +// Priority contains metadata that controls relative ordering of task processing +// when tasks are backed up in a queue. Initially, Priority will be used in +// matching (workflow and activity) task queues. Later it may be used in history +// task queues and in rate limiting decisions. +// +// Priority is attached to workflows and activities. By default, activities +// inherit Priority from the workflow that created them, but may override fields +// when an activity is started or modified. +// +// Despite being named "Priority", this message also contains fields that +// control "fairness" mechanisms. +// +// For all fields, the field not present or equal to zero/empty string means to +// inherit the value from the calling workflow, or if there is no calling +// workflow, then use the default value. +// +// For all fields other than fairness_key, the zero value isn't meaningful so +// there's no confusion between inherit/default and a meaningful value. For +// fairness_key, the empty string will be interpreted as "inherit". This means +// that if a workflow has a non-empty fairness key, you can't override the +// fairness key of its activity to the empty string. +// +// The overall semantics of Priority are: +// 1. First, consider "priority": higher priority (lower number) goes first. +// 2. Next, consider fairness: try to dispatch tasks for different fairness keys +// in proportion to their weight. +// 3. Finally, tasks may be ordered by an additional ordering key. +// +// Applications may use any subset of mechanisms that are useful to them and +// leave the other fields to use default values. +// +// Not all queues in the system may support the "full" semantics of all priority +// fields. (Currently only support in matching task queues is planned.) +message Priority { + // Priority key is a positive integer from 1 to n, where smaller integers + // correspond to higher priorities (tasks run sooner). In general, tasks in + // a queue should be processed in close to priority order, although small + // deviations are possible. + // + // The maximum priority value (minimum priority) is determined by server + // configuration, and defaults to 5. + // + // If priority is not present (or zero), then the effective priority will be + // the default priority, which is is calculated by (min+max)/2. With the + // default max of 5, and min of 1, that comes out to 3. + int32 priority_key = 1; + + // Fairness key is a short string that's used as a key for a fairness + // balancing mechanism. It may correspond to a tenant id, or to a fixed + // string like "high" or "low". The default is the empty string. + // + // The fairness mechanism attempts to dispatch tasks for a given key in + // proportion to its weight. For example, using a thousand distinct tenant + // ids, each with a weight of 1.0 (the default) will result in each tenant + // getting a roughly equal share of task dispatch throughput. + // + // (Note: this does not imply equal share of worker capacity! Fairness + // decisions are made only at dispatch time based on queue statistics, not + // current worker load.) + // + // As another example, using keys "high" and "low" with weight 9.0 and 1.0 + // respectively will prefer dispatching "high" tasks over "low" tasks at a + // 9:1 ratio, while allowing either key to use all worker capacity if the + // other is not present. + // + // All fairness mechanisms, including rate limits, are best-effort and + // probabilistic. The results may not match what a "perfect" algorithm with + // infinite resources would produce. The more unique keys are used, the less + // accurate the results will be. + // + // Fairness keys are limited to 64 bytes. + string fairness_key = 2; + + // Fairness weight for a task can come from multiple sources for + // flexibility. From highest to lowest precedence: + // 1. Weights for a small set of keys can be overridden in task queue + // configuration with an API. + // 2. It can be attached to the workflow/activity in this field. + // 3. The default weight of 1.0 will be used. + // Note that if the weight for a key is attached in this field, for best + // results, the same weight should be used for the same key for a reasonable + // amount of time (minutes). It may change, but it may take some time for + // the change to be reflected. + // + // The recommended range of usable weights is [0.001, 1000]. + float fairness_weight = 3; + + // The fairness mechanism can also enforce rate limits per fairness key. + // Rate limits are specified in tasks dispatched per second. + // As with weights, rate limits can come from different sources: + // 1. Rate limits for a small set of keys can be overridden in task queue + // configuration with an API. + // 2. It can be attached to the workflow/activity in this field. + // 3. The "default" rate limit for keys that are not overridden can be set + // in task queue configuration also. + // 4. Otherwise, a very high rate limit will be applied. + float fairness_rate_limit = 4; + + // Ordering key is a positive integer from 1 to MaxInt64. After priority and + // fairness mechanisms are applied, tasks will be finally ordered by + // ordering_key. Note that fine-grained values are allowed here, as opposed + // to priority. + // + // For example, applications might use the start time of a workflow (in + // seconds since the unix epoch) as ordering key for the workflow and all + // activities in it. This will have the effect of prioritizing activities of + // workflows that were started earlier, encouring completing older workflows + // over making progress in newer ones. + int64 ordering_key = 5; +} diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index 065f2bbad..0582eb662 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -133,6 +133,8 @@ message WorkflowExecutionStartedEventAttributes { string inherited_build_id = 32; // Versioning override applied to this workflow when it was started. temporal.api.workflow.v1.VersioningOverride versioning_override = 33; + // Priority metadata + temporal.api.common.v1.Priority priority = 34; } message WorkflowExecutionCompletedEventAttributes { @@ -333,6 +335,9 @@ message ActivityTaskScheduledEventAttributes { // If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise, // Assignment rules of the activity's Task Queue will be used to determine the Build ID. bool use_workflow_build_id = 13; + // Priority metadata. If this message is not present, or any fields are not + // present, they inherit the values from the workflow. + temporal.api.common.v1.Priority priority = 14; } message ActivityTaskStartedEventAttributes { @@ -640,6 +645,8 @@ message StartChildWorkflowExecutionInitiatedEventAttributes { // If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment // rules of the child's Task Queue will be used to independently assign a Build ID to it. bool inherit_build_id = 19; + // Priority metadata + temporal.api.common.v1.Priority priority = 20; } message StartChildWorkflowExecutionFailedEventAttributes { @@ -741,8 +748,11 @@ message ChildWorkflowExecutionTerminatedEventAttributes { } message WorkflowExecutionOptionsUpdatedEventAttributes { - // Versioning override in the mutable state after event has been applied. + // Versioning override upserted in this event. + // Ignored if nil or if unset_versioning_override is true. temporal.api.workflow.v1.VersioningOverride versioning_override = 1; + // Versioning override removed in this event. + bool unset_versioning_override = 2; } // Not used anywhere. Use case is replaced by WorkflowExecutionOptionsUpdatedEventAttributes diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index ec5162fa2..db0f7a94d 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -110,6 +110,9 @@ message WorkflowExecutionInfo { // be versioned or unversioned, depending on `versioning_info.behavior` and `versioning_info.versioning_override`. // Experimental. Versioning info is experimental and might change in the future. WorkflowExecutionVersioningInfo versioning_info = 22; + + // Priority metadata + temporal.api.common.v1.Priority priority = 23; } // Holds all the extra information about workflow execution that is not part of Visibility. @@ -242,6 +245,9 @@ message PendingActivityInfo { // The deployment this activity was dispatched to most recently. Present only if the activity // was dispatched to a versioned worker. temporal.api.deployment.v1.Deployment last_deployment = 20; + + // Priority metadata + temporal.api.common.v1.Priority priority = 21; } message PendingChildExecutionInfo { @@ -320,6 +326,8 @@ message NewWorkflowExecutionInfo { // If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion. // To unset the override after the workflow is running, use UpdateWorkflowExecutionOptions. VersioningOverride versioning_override = 15; + // Priority metadata + temporal.api.common.v1.Priority priority = 16; } // CallbackInfo contains the state of an attached workflow callback. diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index f84e3e2ce..bc3ffe4dc 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -206,6 +206,8 @@ message StartWorkflowExecutionRequest { // If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion. // To unset the override after the workflow is running, use UpdateWorkflowExecutionOptions. temporal.api.workflow.v1.VersioningOverride versioning_override = 25; + // Priority metadata + temporal.api.common.v1.Priority priority = 26; } message StartWorkflowExecutionResponse { @@ -478,6 +480,8 @@ message PollActivityTaskQueueResponse { // (or not) during activity scheduling. The service can override the provided one if some // values are not specified or exceed configured system limits. temporal.api.common.v1.RetryPolicy retry_policy = 17; + // Priority metadata + temporal.api.common.v1.Priority priority = 18; } message RecordActivityTaskHeartbeatRequest { @@ -518,6 +522,9 @@ message RecordActivityTaskHeartbeatByIdResponse { // Will be set to true if the activity has been asked to cancel itself. The SDK should then // notify the activity of cancellation if it is still running. bool cancel_requested = 1; + + // Will be set to true if the activity is paused. + bool activity_paused = 2; } message RespondActivityTaskCompletedRequest { @@ -751,6 +758,8 @@ message SignalWithStartWorkflowExecutionRequest { // If set, takes precedence over the Versioning Behavior sent by the SDK on Workflow Task completion. // To unset the override after the workflow is running, use UpdateWorkflowExecutionOptions. temporal.api.workflow.v1.VersioningOverride versioning_override = 25; + // Priority metadata + temporal.api.common.v1.Priority priority = 26; } message SignalWithStartWorkflowExecutionResponse {