temporalio_common/priority.rs
1use crate::protos::temporal::api::common;
2
3/// Priority contains metadata that controls relative ordering of task processing
4/// when tasks are backlogged in a queue. Initially, Priority will be used in
5/// activity and workflow task queues, which are typically where backlogs exist.
6/// Other queues in the server (such as transfer and timer queues) and rate
7/// limiting decisions do not use Priority, but may in the future.
8///
9/// Priority is attached to workflows and activities. Activities and child
10/// workflows inherit Priority from the workflow that created them, but may
11/// override fields when they are started or modified.
12///
13/// All fields default to `None`, which means "inherit from the calling workflow"
14/// or, if there is no calling workflow, "use the server default."
15///
16/// Despite being named "Priority", this type also contains fields that
17/// control "fairness" mechanisms.
18///
19/// The overall semantics of Priority are:
20/// (more will be added here later)
21/// 1. First, consider "priority_key": lower number goes first.
22#[derive(Debug, Clone, Default, PartialEq)]
23pub struct Priority {
24 /// Priority key is a positive integer from 1 to n, where smaller integers
25 /// correspond to higher priorities (tasks run sooner). In general, tasks in
26 /// a queue should be processed in close to priority order, although small
27 /// deviations are possible.
28 ///
29 /// The maximum priority value (minimum priority) is determined by server
30 /// configuration, and defaults to 5.
31 ///
32 /// The server default priority is `(min + max) / 2`. With the default max
33 /// of 5 and min of 1, that comes out to 3.
34 ///
35 /// `None` means inherit from the calling workflow or use the server default.
36 pub priority_key: Option<u32>,
37
38 /// Fairness key is a short string that's used as a key for a fairness
39 /// balancing mechanism. It may correspond to a tenant id, or to a fixed
40 /// string like "high" or "low".
41 ///
42 /// The fairness mechanism attempts to dispatch tasks for a given key in
43 /// proportion to its weight. For example, using a thousand distinct tenant
44 /// ids, each with a weight of 1.0 (the default) will result in each tenant
45 /// getting a roughly equal share of task dispatch throughput.
46 ///
47 /// (Note: this does not imply equal share of worker capacity! Fairness
48 /// decisions are made based on queue statistics, not current worker load.)
49 ///
50 /// As another example, using keys "high" and "low" with weight 9.0 and 1.0
51 /// respectively will prefer dispatching "high" tasks over "low" tasks at a
52 /// 9:1 ratio, while allowing either key to use all worker capacity if the
53 /// other is not present.
54 ///
55 /// All fairness mechanisms, including rate limits, are best-effort and
56 /// probabilistic. The results may not match what a "perfect" algorithm with
57 /// infinite resources would produce. The more unique keys are used, the less
58 /// accurate the results will be.
59 ///
60 /// Fairness keys are limited to 64 bytes.
61 ///
62 /// `None` means inherit from the calling workflow or use the server default
63 /// (empty string).
64 pub fairness_key: Option<String>,
65
66 /// Fairness weight for a task can come from multiple sources for
67 /// flexibility. From highest to lowest precedence:
68 /// 1. Weights for a small set of keys can be overridden in task queue
69 /// configuration with an API.
70 /// 2. It can be attached to the workflow/activity in this field.
71 /// 3. The server default weight of 1.0 will be used.
72 ///
73 /// Weight values are clamped by the server to the range \[0.001, 1000\].
74 ///
75 /// `None` means inherit from the calling workflow or use the server default
76 /// (1.0).
77 pub fairness_weight: Option<f32>,
78}
79
80impl From<Priority> for common::v1::Priority {
81 fn from(priority: Priority) -> Self {
82 common::v1::Priority {
83 priority_key: priority.priority_key.unwrap_or(0) as i32,
84 fairness_key: priority.fairness_key.unwrap_or_default(),
85 fairness_weight: priority.fairness_weight.unwrap_or(0.0),
86 }
87 }
88}
89
90impl From<common::v1::Priority> for Priority {
91 fn from(priority: common::v1::Priority) -> Self {
92 Self {
93 priority_key: if priority.priority_key == 0 {
94 None
95 } else {
96 Some(priority.priority_key as u32)
97 },
98 fairness_key: if priority.fairness_key.is_empty() {
99 None
100 } else {
101 Some(priority.fairness_key)
102 },
103 fairness_weight: if priority.fairness_weight == 0.0 {
104 None
105 } else {
106 Some(priority.fairness_weight)
107 },
108 }
109 }
110}