Skip to content

Commit 76b8fcb

Browse files
stephanosdnr
andauthored
Fairness (#617)
**What changed?** Already [discussed and approved previously here](#513). **Breaking changes** N/A **Server PR** https://github.com/temporalio/temporal/tree/feature/fairness --------- Co-authored-by: David Reiss <[email protected]>
1 parent 0ba4284 commit 76b8fcb

File tree

3 files changed

+146
-34
lines changed

3 files changed

+146
-34
lines changed

openapi/openapiv2.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13127,10 +13127,19 @@
1312713127
"priorityKey": {
1312813128
"type": "integer",
1312913129
"format": "int32",
13130-
"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\nThe default priority is (min+max)/2. With the default max of 5 and min of\n1, that comes out to 3."
13130+
"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."
13131+
},
13132+
"fairnessKey": {
13133+
"type": "string",
13134+
"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 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."
13135+
},
13136+
"fairnessWeight": {
13137+
"type": "number",
13138+
"format": "float",
13139+
"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.\n\nWeight values are clamped to the range [0.001, 1000]."
1313113140
}
1313213141
},
13133-
"description": "Priority contains metadata that controls relative ordering of task processing\nwhen tasks are backlogged in a queue. Initially, Priority will be used in\nactivity and workflow task queues, which are typically where backlogs exist.\nOther queues in the server (such as transfer and timer queues) and rate\nlimiting decisions do not use Priority, but may in the future.\n\nPriority is attached to workflows and activities. Activities and child\nworkflows inherit Priority from the workflow that created them, but may\noverride fields when they are started or modified. For each field of a\nPriority on an activity/workflow, not present or equal to zero/empty string\nmeans to inherit the value from the calling workflow, or if there is no\ncalling workflow, then use the default (documented below).\n\nDespite being named \"Priority\", this message will also contains fields that\ncontrol \"fairness\" mechanisms.\n\nThe overall semantics of Priority are:\n1. First, consider \"priority_key\": lower number goes first.\n(more will be added here later)"
13142+
"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. Then, consider fairness: try to dispatch tasks for different fairness keys\n in proportion to their weight.\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.)"
1313413143
},
1313513144
"v1ProtocolMessageCommandAttributes": {
1313613145
"type": "object",

openapi/openapiv3.yaml

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9909,29 +9909,82 @@ components:
99099909
The maximum priority value (minimum priority) is determined by server
99109910
configuration, and defaults to 5.
99119911

9912-
The default priority is (min+max)/2. With the default max of 5 and min of
9913-
1, that comes out to 3.
9912+
If priority is not present (or zero), then the effective priority will be
9913+
the default priority, which is is calculated by (min+max)/2. With the
9914+
default max of 5, and min of 1, that comes out to 3.
99149915
format: int32
9916+
fairnessKey:
9917+
type: string
9918+
description: |-
9919+
Fairness key is a short string that's used as a key for a fairness
9920+
balancing mechanism. It may correspond to a tenant id, or to a fixed
9921+
string like "high" or "low". The default is the empty string.
9922+
9923+
The fairness mechanism attempts to dispatch tasks for a given key in
9924+
proportion to its weight. For example, using a thousand distinct tenant
9925+
ids, each with a weight of 1.0 (the default) will result in each tenant
9926+
getting a roughly equal share of task dispatch throughput.
9927+
9928+
(Note: this does not imply equal share of worker capacity! Fairness
9929+
decisions are made based on queue statistics, not
9930+
current worker load.)
9931+
9932+
As another example, using keys "high" and "low" with weight 9.0 and 1.0
9933+
respectively will prefer dispatching "high" tasks over "low" tasks at a
9934+
9:1 ratio, while allowing either key to use all worker capacity if the
9935+
other is not present.
9936+
9937+
All fairness mechanisms, including rate limits, are best-effort and
9938+
probabilistic. The results may not match what a "perfect" algorithm with
9939+
infinite resources would produce. The more unique keys are used, the less
9940+
accurate the results will be.
9941+
9942+
Fairness keys are limited to 64 bytes.
9943+
fairnessWeight:
9944+
type: number
9945+
description: |-
9946+
Fairness weight for a task can come from multiple sources for
9947+
flexibility. From highest to lowest precedence:
9948+
1. Weights for a small set of keys can be overridden in task queue
9949+
configuration with an API.
9950+
2. It can be attached to the workflow/activity in this field.
9951+
3. The default weight of 1.0 will be used.
9952+
9953+
Weight values are clamped to the range [0.001, 1000].
9954+
format: float
99159955
description: |-
99169956
Priority contains metadata that controls relative ordering of task processing
9917-
when tasks are backlogged in a queue. Initially, Priority will be used in
9918-
activity and workflow task queues, which are typically where backlogs exist.
9919-
Other queues in the server (such as transfer and timer queues) and rate
9920-
limiting decisions do not use Priority, but may in the future.
9921-
9922-
Priority is attached to workflows and activities. Activities and child
9923-
workflows inherit Priority from the workflow that created them, but may
9924-
override fields when they are started or modified. For each field of a
9925-
Priority on an activity/workflow, not present or equal to zero/empty string
9926-
means to inherit the value from the calling workflow, or if there is no
9927-
calling workflow, then use the default (documented below).
9928-
9929-
Despite being named "Priority", this message will also contains fields that
9957+
when tasks are backed up in a queue. Initially, Priority will be used in
9958+
matching (workflow and activity) task queues. Later it may be used in history
9959+
task queues and in rate limiting decisions.
9960+
9961+
Priority is attached to workflows and activities. By default, activities
9962+
inherit Priority from the workflow that created them, but may override fields
9963+
when an activity is started or modified.
9964+
9965+
Despite being named "Priority", this message also contains fields that
99309966
control "fairness" mechanisms.
99319967

9968+
For all fields, the field not present or equal to zero/empty string means to
9969+
inherit the value from the calling workflow, or if there is no calling
9970+
workflow, then use the default value.
9971+
9972+
For all fields other than fairness_key, the zero value isn't meaningful so
9973+
there's no confusion between inherit/default and a meaningful value. For
9974+
fairness_key, the empty string will be interpreted as "inherit". This means
9975+
that if a workflow has a non-empty fairness key, you can't override the
9976+
fairness key of its activity to the empty string.
9977+
99329978
The overall semantics of Priority are:
9933-
1. First, consider "priority_key": lower number goes first.
9934-
(more will be added here later)
9979+
1. First, consider "priority": higher priority (lower number) goes first.
9980+
2. Then, consider fairness: try to dispatch tasks for different fairness keys
9981+
in proportion to their weight.
9982+
9983+
Applications may use any subset of mechanisms that are useful to them and
9984+
leave the other fields to use default values.
9985+
9986+
Not all queues in the system may support the "full" semantics of all priority
9987+
fields. (Currently only support in matching task queues is planned.)
99359988
QueryRejected:
99369989
type: object
99379990
properties:

temporal/api/common/v1/message.proto

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -239,24 +239,37 @@ message Link {
239239
}
240240

241241
// Priority contains metadata that controls relative ordering of task processing
242-
// when tasks are backlogged in a queue. Initially, Priority will be used in
243-
// activity and workflow task queues, which are typically where backlogs exist.
244-
// Other queues in the server (such as transfer and timer queues) and rate
245-
// limiting decisions do not use Priority, but may in the future.
242+
// when tasks are backed up in a queue. Initially, Priority will be used in
243+
// matching (workflow and activity) task queues. Later it may be used in history
244+
// task queues and in rate limiting decisions.
246245
//
247-
// Priority is attached to workflows and activities. Activities and child
248-
// workflows inherit Priority from the workflow that created them, but may
249-
// override fields when they are started or modified. For each field of a
250-
// Priority on an activity/workflow, not present or equal to zero/empty string
251-
// means to inherit the value from the calling workflow, or if there is no
252-
// calling workflow, then use the default (documented below).
246+
// Priority is attached to workflows and activities. By default, activities
247+
// inherit Priority from the workflow that created them, but may override fields
248+
// when an activity is started or modified.
253249
//
254-
// Despite being named "Priority", this message will also contains fields that
250+
// Despite being named "Priority", this message also contains fields that
255251
// control "fairness" mechanisms.
256252
//
253+
// For all fields, the field not present or equal to zero/empty string means to
254+
// inherit the value from the calling workflow, or if there is no calling
255+
// workflow, then use the default value.
256+
//
257+
// For all fields other than fairness_key, the zero value isn't meaningful so
258+
// there's no confusion between inherit/default and a meaningful value. For
259+
// fairness_key, the empty string will be interpreted as "inherit". This means
260+
// that if a workflow has a non-empty fairness key, you can't override the
261+
// fairness key of its activity to the empty string.
262+
//
257263
// The overall semantics of Priority are:
258-
// 1. First, consider "priority_key": lower number goes first.
259-
// (more will be added here later)
264+
// 1. First, consider "priority": higher priority (lower number) goes first.
265+
// 2. Then, consider fairness: try to dispatch tasks for different fairness keys
266+
// in proportion to their weight.
267+
//
268+
// Applications may use any subset of mechanisms that are useful to them and
269+
// leave the other fields to use default values.
270+
//
271+
// Not all queues in the system may support the "full" semantics of all priority
272+
// fields. (Currently only support in matching task queues is planned.)
260273
message Priority {
261274
// Priority key is a positive integer from 1 to n, where smaller integers
262275
// correspond to higher priorities (tasks run sooner). In general, tasks in
@@ -266,9 +279,46 @@ message Priority {
266279
// The maximum priority value (minimum priority) is determined by server
267280
// configuration, and defaults to 5.
268281
//
269-
// The default priority is (min+max)/2. With the default max of 5 and min of
270-
// 1, that comes out to 3.
282+
// If priority is not present (or zero), then the effective priority will be
283+
// the default priority, which is is calculated by (min+max)/2. With the
284+
// default max of 5, and min of 1, that comes out to 3.
271285
int32 priority_key = 1;
286+
287+
// Fairness key is a short string that's used as a key for a fairness
288+
// balancing mechanism. It may correspond to a tenant id, or to a fixed
289+
// string like "high" or "low". The default is the empty string.
290+
//
291+
// The fairness mechanism attempts to dispatch tasks for a given key in
292+
// proportion to its weight. For example, using a thousand distinct tenant
293+
// ids, each with a weight of 1.0 (the default) will result in each tenant
294+
// getting a roughly equal share of task dispatch throughput.
295+
//
296+
// (Note: this does not imply equal share of worker capacity! Fairness
297+
// decisions are made based on queue statistics, not
298+
// current worker load.)
299+
//
300+
// As another example, using keys "high" and "low" with weight 9.0 and 1.0
301+
// respectively will prefer dispatching "high" tasks over "low" tasks at a
302+
// 9:1 ratio, while allowing either key to use all worker capacity if the
303+
// other is not present.
304+
//
305+
// All fairness mechanisms, including rate limits, are best-effort and
306+
// probabilistic. The results may not match what a "perfect" algorithm with
307+
// infinite resources would produce. The more unique keys are used, the less
308+
// accurate the results will be.
309+
//
310+
// Fairness keys are limited to 64 bytes.
311+
string fairness_key = 2;
312+
313+
// Fairness weight for a task can come from multiple sources for
314+
// flexibility. From highest to lowest precedence:
315+
// 1. Weights for a small set of keys can be overridden in task queue
316+
// configuration with an API.
317+
// 2. It can be attached to the workflow/activity in this field.
318+
// 3. The default weight of 1.0 will be used.
319+
//
320+
// Weight values are clamped to the range [0.001, 1000].
321+
float fairness_weight = 3;
272322
}
273323

274324
// This is used to send commands to a specific worker or a group of workers.

0 commit comments

Comments
 (0)