@temporalio/core-bridge 0.16.4 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/Cargo.lock +339 -226
  2. package/Cargo.toml +7 -3
  3. package/common.js +50 -0
  4. package/index.d.ts +7 -0
  5. package/index.js +12 -0
  6. package/package.json +7 -4
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/{index.node → releases/index.node} +0 -0
  10. package/releases/x86_64-apple-darwin/index.node +0 -0
  11. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  12. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  13. package/scripts/build.js +10 -50
  14. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  15. package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
  16. package/sdk-core/.buildkite/pipeline.yml +2 -0
  17. package/sdk-core/Cargo.toml +1 -88
  18. package/sdk-core/README.md +30 -6
  19. package/sdk-core/bridge-ffi/Cargo.toml +24 -0
  20. package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
  21. package/sdk-core/bridge-ffi/build.rs +25 -0
  22. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
  23. package/sdk-core/bridge-ffi/src/lib.rs +829 -0
  24. package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
  25. package/sdk-core/client/Cargo.toml +32 -0
  26. package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
  27. package/sdk-core/client/src/metrics.rs +89 -0
  28. package/sdk-core/client/src/mocks.rs +167 -0
  29. package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
  30. package/sdk-core/core/Cargo.toml +96 -0
  31. package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
  32. package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
  33. package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
  34. package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
  35. package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
  36. package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
  37. package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
  38. package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
  39. package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
  40. package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
  41. package/sdk-core/core/src/lib.rs +374 -0
  42. package/sdk-core/{src → core/src}/log_export.rs +3 -27
  43. package/sdk-core/core/src/pending_activations.rs +162 -0
  44. package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
  45. package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
  46. package/sdk-core/core/src/protosext/mod.rs +396 -0
  47. package/sdk-core/core/src/replay/mod.rs +210 -0
  48. package/sdk-core/core/src/retry_logic.rs +144 -0
  49. package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
  50. package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
  51. package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
  52. package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
  53. package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
  55. package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
  56. package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
  57. package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
  58. package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
  59. package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
  60. package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
  61. package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
  62. package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
  63. package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
  64. package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
  65. package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
  66. package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
  67. package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
  68. package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
  69. package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
  70. package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
  71. package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
  72. package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
  73. package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
  74. package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
  75. package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
  76. package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
  77. package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
  78. package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
  79. package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
  80. package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
  81. package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
  82. package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
  83. package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
  84. package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
  85. package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
  86. package/sdk-core/{src → core-api/src}/errors.rs +42 -92
  87. package/sdk-core/core-api/src/lib.rs +158 -0
  88. package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
  89. package/sdk-core/etc/deps.svg +156 -0
  90. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
  92. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
  93. package/sdk-core/histories/fail_wf_task.bin +0 -0
  94. package/sdk-core/histories/timer_workflow_history.bin +0 -0
  95. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
  96. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
  97. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
  98. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
  99. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
  100. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
  101. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
  102. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
  103. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
  104. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  105. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
  106. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
  107. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
  108. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
  109. package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  110. package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
  111. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
  112. package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
  113. package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
  114. package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
  115. package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
  116. package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  117. package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
  118. package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
  119. package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
  120. package/sdk-core/sdk/Cargo.toml +32 -0
  121. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
  122. package/sdk-core/sdk/src/lib.rs +699 -0
  123. package/sdk-core/sdk/src/payload_converter.rs +11 -0
  124. package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
  125. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
  126. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
  127. package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
  128. package/sdk-core/sdk-core-protos/build.rs +28 -6
  129. package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  130. package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
  131. package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
  132. package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
  133. package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  134. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  135. package/sdk-core/test-utils/Cargo.toml +32 -0
  136. package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
  137. package/sdk-core/test-utils/src/histfetch.rs +28 -0
  138. package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
  139. package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
  140. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
  141. package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
  142. package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
  143. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
  144. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
  145. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
  146. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
  147. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
  148. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
  149. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
  150. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
  151. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
  152. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
  153. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
  154. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
  155. package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
  156. package/sdk-core/tests/load_tests.rs +6 -6
  157. package/sdk-core/tests/main.rs +2 -2
  158. package/src/conversions.rs +24 -21
  159. package/src/errors.rs +8 -0
  160. package/src/lib.rs +323 -211
  161. package/sdk-core/protos/local/activity_result.proto +0 -46
  162. package/sdk-core/protos/local/activity_task.proto +0 -66
  163. package/sdk-core/src/core_tests/retry.rs +0 -147
  164. package/sdk-core/src/lib.rs +0 -403
  165. package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
  166. package/sdk-core/src/pending_activations.rs +0 -249
  167. package/sdk-core/src/protosext/mod.rs +0 -160
  168. package/sdk-core/src/prototype_rust_sdk.rs +0 -412
  169. package/sdk-core/src/task_token.rs +0 -20
  170. package/sdk-core/src/test_help/history_info.rs +0 -157
@@ -1,117 +0,0 @@
1
- use rustfsm::{fsm, TransitionResult};
2
-
3
- fsm! {
4
- pub(super) name LocalActivityMachine;
5
- command LocalActivityCommand;
6
- error LocalActivityMachineError;
7
-
8
- Created --(CheckExecutionState, on_check_execution_state) --> Replaying;
9
- Created --(CheckExecutionState, on_check_execution_state) --> Executing;
10
-
11
- Executing --(Schedule, on_schedule) --> RequestPrepared;
12
-
13
- MarkerCommandCreated --(CommandRecordMarker, on_command_record_marker) --> ResultNotified;
14
-
15
- Replaying --(Schedule) --> WaitingMarkerEvent;
16
-
17
- RequestPrepared --(MarkAsSent) --> RequestSent;
18
-
19
- RequestSent --(NonReplayWorkflowTaskStarted) --> RequestSent;
20
- RequestSent --(HandleResult, on_handle_result) --> MarkerCommandCreated;
21
-
22
- ResultNotified --(MarkerRecorded, on_marker_recorded) --> MarkerCommandRecorded;
23
-
24
- WaitingMarkerEvent --(MarkerRecorded, on_marker_recorded) --> MarkerCommandRecorded;
25
- WaitingMarkerEvent --(NonReplayWorkflowTaskStarted, on_non_replay_workflow_task_started) --> RequestPrepared;
26
- }
27
-
28
- #[derive(thiserror::Error, Debug)]
29
- pub(super) enum LocalActivityMachineError {}
30
-
31
- pub(super) enum LocalActivityCommand {}
32
-
33
- #[derive(Default, Clone)]
34
- pub(super) struct Created {}
35
-
36
- impl Created {
37
- pub(super) fn on_check_execution_state(
38
- self,
39
- ) -> LocalActivityMachineTransition<ReplayingOrExecuting> {
40
- unimplemented!()
41
- }
42
- }
43
-
44
- #[derive(Default, Clone)]
45
- pub(super) struct Executing {}
46
-
47
- impl Executing {
48
- pub(super) fn on_schedule(self) -> LocalActivityMachineTransition<RequestPrepared> {
49
- unimplemented!()
50
- }
51
- }
52
-
53
- #[derive(Default, Clone)]
54
- pub(super) struct MarkerCommandCreated {}
55
-
56
- impl MarkerCommandCreated {
57
- pub(super) fn on_command_record_marker(self) -> LocalActivityMachineTransition<ResultNotified> {
58
- unimplemented!()
59
- }
60
- }
61
-
62
- #[derive(Default, Clone)]
63
- pub(super) struct MarkerCommandRecorded {}
64
-
65
- #[derive(Default, Clone)]
66
- pub(super) struct Replaying {}
67
-
68
- #[derive(Default, Clone)]
69
- pub(super) struct RequestPrepared {}
70
-
71
- #[derive(Default, Clone)]
72
- pub(super) struct RequestSent {}
73
-
74
- impl RequestSent {
75
- pub(super) fn on_handle_result(self) -> LocalActivityMachineTransition<MarkerCommandCreated> {
76
- unimplemented!()
77
- }
78
- }
79
-
80
- impl From<RequestPrepared> for RequestSent {
81
- fn from(_: RequestPrepared) -> Self {
82
- Self::default()
83
- }
84
- }
85
-
86
- #[derive(Default, Clone)]
87
- pub(super) struct ResultNotified {}
88
-
89
- impl ResultNotified {
90
- pub(super) fn on_marker_recorded(
91
- self,
92
- ) -> LocalActivityMachineTransition<MarkerCommandRecorded> {
93
- unimplemented!()
94
- }
95
- }
96
-
97
- #[derive(Default, Clone)]
98
- pub(super) struct WaitingMarkerEvent {}
99
-
100
- impl WaitingMarkerEvent {
101
- pub(super) fn on_marker_recorded(
102
- self,
103
- ) -> LocalActivityMachineTransition<MarkerCommandRecorded> {
104
- unimplemented!()
105
- }
106
- pub(super) fn on_non_replay_workflow_task_started(
107
- self,
108
- ) -> LocalActivityMachineTransition<RequestPrepared> {
109
- unimplemented!()
110
- }
111
- }
112
-
113
- impl From<Replaying> for WaitingMarkerEvent {
114
- fn from(_: Replaying) -> Self {
115
- Self::default()
116
- }
117
- }
@@ -1,249 +0,0 @@
1
- use parking_lot::RwLock;
2
- use slotmap::SlotMap;
3
- use std::{
4
- cmp::Ordering,
5
- collections::{HashMap, VecDeque},
6
- };
7
- use temporal_sdk_core_protos::coresdk::workflow_activation::{
8
- wf_activation_job, WfActivation, WfActivationJob,
9
- };
10
-
11
- /// Tracks pending activations using an internal queue, while also allowing lookup and removal of
12
- /// any pending activations by run ID.
13
- #[derive(Default)]
14
- pub struct PendingActivations {
15
- inner: RwLock<PaInner>,
16
- }
17
-
18
- slotmap::new_key_type! { struct ActivationKey; }
19
-
20
- #[derive(Default)]
21
- struct PaInner {
22
- activations: SlotMap<ActivationKey, WfActivation>,
23
- by_run_id: HashMap<String, ActivationKey>,
24
- // Holds the actual queue of activations
25
- queue: VecDeque<ActivationKey>,
26
- }
27
-
28
- impl PendingActivations {
29
- /// Push a pending activation
30
- ///
31
- /// Importantly, if there already exist activations for same workflow run in the queue, and the
32
- /// new activation (or pending one) is just an eviction job, it can be merged into the existing
33
- /// activation.
34
- ///
35
- /// Any other attempt to enqueue a pending activation while there is already one for a given
36
- /// run is a violation of our logic and will cause a panic. This is because there should never
37
- /// be new activations with real work in them queued up when one is already queued, because they
38
- /// should not be produced until the last one is completed (only one outstanding activation at
39
- /// a time rule). New work from the server similarily should not be pushed here, as it is
40
- /// buffered until any oustanding workflow task is completed.
41
- pub fn push(&self, v: WfActivation) {
42
- let mut inner = self.inner.write();
43
-
44
- // Check if an activation with the same ID already exists, and merge joblist if so
45
- if let Some(key) = inner.by_run_id.get(&v.run_id).copied() {
46
- let act = inner
47
- .activations
48
- .get_mut(key)
49
- .expect("PA run id mapping is always in sync with slot map");
50
- if v.is_only_eviction() || act.is_only_eviction() {
51
- merge_joblists(&mut act.jobs, v.jobs.into_iter());
52
- } else {
53
- panic!(
54
- "Cannot enqueue non-eviction pending activation for run with an \
55
- existing non-eviction PA: {:?}",
56
- v
57
- );
58
- }
59
- } else {
60
- let run_id = v.run_id.clone();
61
- let key = inner.activations.insert(v);
62
- inner.by_run_id.insert(run_id, key);
63
- inner.queue.push_back(key);
64
- };
65
- }
66
-
67
- pub fn pop_first_matching(&self, predicate: impl Fn(&str) -> bool) -> Option<WfActivation> {
68
- let mut inner = self.inner.write();
69
- let mut key_queue = inner.queue.iter().copied();
70
- let maybe_key = key_queue.position(|k| {
71
- inner
72
- .activations
73
- .get(k)
74
- .map_or(false, |activation| predicate(&activation.run_id))
75
- });
76
-
77
- let maybe_key = maybe_key.map(|pos| inner.queue.remove(pos).unwrap());
78
- maybe_key.and_then(|key| {
79
- if let Some(pa) = inner.activations.remove(key) {
80
- inner.by_run_id.remove(&pa.run_id);
81
- Some(pa)
82
- } else {
83
- // Keys no longer in the slot map are ignored, since they may have been removed
84
- // by run id or anything else. Try to pop the next thing from the queue. Recurse
85
- // to avoid double mutable borrow.
86
- drop(inner); // Will deadlock when we recurse w/o this
87
- self.pop()
88
- }
89
- })
90
- }
91
-
92
- pub fn pop(&self) -> Option<WfActivation> {
93
- self.pop_first_matching(|_| true)
94
- }
95
-
96
- pub fn has_pending(&self, run_id: &str) -> bool {
97
- self.inner.read().by_run_id.contains_key(run_id)
98
- }
99
-
100
- pub fn remove_all_with_run_id(&self, run_id: &str) {
101
- let mut inner = self.inner.write();
102
-
103
- if let Some(k) = inner.by_run_id.remove(run_id) {
104
- inner.activations.remove(k);
105
- }
106
- }
107
- }
108
-
109
- fn merge_joblists(
110
- existing_list: &mut Vec<WfActivationJob>,
111
- other_jobs: impl Iterator<Item = WfActivationJob>,
112
- ) {
113
- existing_list.extend(other_jobs);
114
- // Move any evictions to the end of the list
115
- existing_list
116
- .as_mut_slice()
117
- .sort_by(evictions_always_last_compare);
118
- // Drop any duplicate evictions
119
- let truncate_len = existing_list
120
- .iter()
121
- .rev()
122
- .position(|j| {
123
- !matches!(
124
- j.variant,
125
- Some(wf_activation_job::Variant::RemoveFromCache(_))
126
- )
127
- })
128
- .map_or(1, |last_non_evict_job| {
129
- existing_list.len() - last_non_evict_job + 1
130
- });
131
- existing_list.truncate(truncate_len);
132
- }
133
-
134
- fn evictions_always_last_compare(a: &WfActivationJob, b: &WfActivationJob) -> Ordering {
135
- if a == b {
136
- return Ordering::Equal;
137
- }
138
- // Any eviction always goes last
139
- if matches!(
140
- a.variant,
141
- Some(wf_activation_job::Variant::RemoveFromCache(_))
142
- ) {
143
- return Ordering::Greater;
144
- }
145
- if matches!(
146
- b.variant,
147
- Some(wf_activation_job::Variant::RemoveFromCache(_))
148
- ) {
149
- return Ordering::Less;
150
- }
151
- // All jobs should not change order except evictions
152
- Ordering::Equal
153
- }
154
-
155
- #[cfg(test)]
156
- mod tests {
157
- use super::*;
158
- use temporal_sdk_core_protos::coresdk::workflow_activation::create_evict_activation;
159
-
160
- #[test]
161
- fn merges_same_ids_with_evictions() {
162
- let pas = PendingActivations::default();
163
- let rid1 = "1".to_string();
164
- let rid2 = "2".to_string();
165
- pas.push(WfActivation {
166
- run_id: rid1.clone(),
167
- ..Default::default()
168
- });
169
- pas.push(create_evict_activation(
170
- rid1.clone(),
171
- "whatever".to_string(),
172
- ));
173
- pas.push(create_evict_activation(
174
- rid2.clone(),
175
- "whatever".to_string(),
176
- ));
177
- pas.push(WfActivation {
178
- run_id: rid2.clone(),
179
- ..Default::default()
180
- });
181
- assert!(pas.has_pending(&rid1));
182
- assert!(pas.has_pending(&rid2));
183
- let last = pas.pop().unwrap();
184
- assert_eq!(&last.run_id, &rid1);
185
- assert!(!pas.has_pending(&rid1));
186
- assert!(pas.has_pending(&rid2));
187
- // Should only be one id 2, they are all merged
188
- let last = pas.pop().unwrap();
189
- assert_eq!(&last.run_id, &rid2);
190
- assert!(!pas.has_pending(&rid2));
191
- assert!(pas.pop().is_none());
192
- }
193
-
194
- #[test]
195
- #[should_panic(expected = "Cannot enqueue non-eviction")]
196
- fn panics_merging_non_evict() {
197
- let pas = PendingActivations::default();
198
- let rid1 = "1".to_string();
199
- pas.push(WfActivation {
200
- run_id: rid1.clone(),
201
- ..Default::default()
202
- });
203
- pas.push(WfActivation {
204
- run_id: rid1,
205
- ..Default::default()
206
- });
207
- }
208
-
209
- #[test]
210
- fn can_remove_all_with_id() {
211
- let pas = PendingActivations::default();
212
- let remove_me = "2".to_string();
213
- pas.push(WfActivation {
214
- run_id: "1".to_owned(),
215
- ..Default::default()
216
- });
217
- pas.push(WfActivation {
218
- run_id: remove_me.clone(),
219
- ..Default::default()
220
- });
221
- pas.push(WfActivation {
222
- run_id: "3".to_owned(),
223
- ..Default::default()
224
- });
225
- pas.remove_all_with_run_id(&remove_me);
226
- assert!(!pas.has_pending(&remove_me));
227
- assert_eq!(&pas.pop().unwrap().run_id, "1");
228
- assert_eq!(&pas.pop().unwrap().run_id, "3");
229
- assert!(pas.pop().is_none());
230
- }
231
-
232
- #[test]
233
- fn can_ignore_specific_runs() {
234
- let pas = PendingActivations::default();
235
- pas.push(WfActivation {
236
- run_id: "1_1".to_owned(),
237
- ..Default::default()
238
- });
239
- pas.push(WfActivation {
240
- run_id: "1_2".to_owned(),
241
- ..Default::default()
242
- });
243
- assert_eq!(
244
- &pas.pop_first_matching(|rid| rid != "1_1").unwrap().run_id,
245
- "1_2"
246
- );
247
- assert_eq!(&pas.pop().unwrap().run_id, "1_1");
248
- }
249
- }
@@ -1,160 +0,0 @@
1
- use crate::{
2
- machines::{ProtoCommand, HAS_CHANGE_MARKER_NAME},
3
- task_token::TaskToken,
4
- workflow::LEGACY_QUERY_ID,
5
- };
6
- use std::convert::TryFrom;
7
- use temporal_sdk_core_protos::{
8
- coresdk::{
9
- common::decode_change_marker_details,
10
- workflow_activation::{wf_activation_job, QueryWorkflow, WfActivation, WfActivationJob},
11
- workflow_commands::{query_result, QueryResult},
12
- workflow_completion, FromPayloadsExt,
13
- },
14
- temporal::api::{
15
- common::v1::WorkflowExecution,
16
- enums::v1::EventType,
17
- history::v1::{history_event, History, HistoryEvent, MarkerRecordedEventAttributes},
18
- query::v1::WorkflowQuery,
19
- taskqueue::v1::StickyExecutionAttributes,
20
- workflowservice::v1::PollWorkflowTaskQueueResponse,
21
- },
22
- };
23
-
24
- /// A validated version of a [PollWorkflowTaskQueueResponse]
25
- #[derive(Debug, Clone, PartialEq)]
26
- #[allow(clippy::manual_non_exhaustive)] // Clippy doesn't understand it's only for *in* this crate
27
- pub struct ValidPollWFTQResponse {
28
- pub task_token: TaskToken,
29
- pub task_queue: String,
30
- pub workflow_execution: WorkflowExecution,
31
- pub workflow_type: String,
32
- pub history: History,
33
- pub next_page_token: Vec<u8>,
34
- pub attempt: u32,
35
- pub previous_started_event_id: i64,
36
- pub started_event_id: i64,
37
- /// If this is present, `history` will be empty. This is not a very "tight" design, but it's
38
- /// enforced at construction time. From the `query` field.
39
- pub legacy_query: Option<WorkflowQuery>,
40
- /// Query requests from the `queries` field
41
- pub query_requests: Vec<QueryWorkflow>,
42
-
43
- /// Zero-size field to prevent explicit construction
44
- _cant_construct_me: (),
45
- }
46
-
47
- impl TryFrom<PollWorkflowTaskQueueResponse> for ValidPollWFTQResponse {
48
- /// We return the poll response itself if it was invalid
49
- type Error = PollWorkflowTaskQueueResponse;
50
-
51
- fn try_from(value: PollWorkflowTaskQueueResponse) -> Result<Self, Self::Error> {
52
- match value {
53
- PollWorkflowTaskQueueResponse {
54
- task_token,
55
- workflow_execution_task_queue: Some(tq),
56
- workflow_execution: Some(workflow_execution),
57
- workflow_type: Some(workflow_type),
58
- history: Some(history),
59
- next_page_token,
60
- attempt,
61
- previous_started_event_id,
62
- started_event_id,
63
- query,
64
- queries,
65
- ..
66
- } => {
67
- let query_requests = queries
68
- .into_iter()
69
- .map(|(id, q)| QueryWorkflow {
70
- query_id: id,
71
- query_type: q.query_type,
72
- arguments: Vec::from_payloads(q.query_args),
73
- })
74
- .collect();
75
-
76
- Ok(Self {
77
- task_token: TaskToken(task_token),
78
- task_queue: tq.name,
79
- workflow_execution,
80
- workflow_type: workflow_type.name,
81
- history,
82
- next_page_token,
83
- attempt: attempt as u32,
84
- previous_started_event_id,
85
- started_event_id,
86
- legacy_query: query,
87
- query_requests,
88
- _cant_construct_me: (),
89
- })
90
- }
91
- _ => Err(value),
92
- }
93
- }
94
- }
95
-
96
- /// A version of [RespondWorkflowTaskCompletedRequest] that will finish being filled out by the
97
- /// server client
98
- #[derive(Debug, Clone, PartialEq)]
99
- pub struct WorkflowTaskCompletion {
100
- /// The task token that would've been received from [crate::Core::poll_workflow_activation] API.
101
- pub task_token: TaskToken,
102
- /// A list of new commands to send to the server, such as starting a timer.
103
- pub commands: Vec<ProtoCommand>,
104
- /// If set, indicate that next task should be queued on sticky queue with given attributes.
105
- pub sticky_attributes: Option<StickyExecutionAttributes>,
106
- /// Responses to queries in the `queries` field of the workflow task.
107
- pub query_responses: Vec<QueryResult>,
108
- pub return_new_workflow_task: bool,
109
- pub force_create_new_workflow_task: bool,
110
- }
111
-
112
- pub(crate) trait WfActivationExt {
113
- /// Returns true if this activation has one and only one job to perform a legacy query
114
- fn is_legacy_query(&self) -> bool;
115
- }
116
-
117
- impl WfActivationExt for WfActivation {
118
- fn is_legacy_query(&self) -> bool {
119
- matches!(&self.jobs.as_slice(), &[WfActivationJob {
120
- variant: Some(wf_activation_job::Variant::QueryWorkflow(qr))
121
- }] if qr.query_id == LEGACY_QUERY_ID)
122
- }
123
- }
124
-
125
- /// Create a legacy query failure result
126
- pub(crate) fn legacy_query_failure(fail: workflow_completion::Failure) -> QueryResult {
127
- QueryResult {
128
- query_id: LEGACY_QUERY_ID.to_string(),
129
- variant: Some(query_result::Variant::Failed(
130
- fail.failure.unwrap_or_default(),
131
- )),
132
- }
133
- }
134
-
135
- pub(crate) trait HistoryEventExt {
136
- /// If this history event represents a `changed` marker, return the info about
137
- /// it. Returns `None` if it is any other kind of event or marker.
138
- fn get_changed_marker_details(&self) -> Option<(String, bool)>;
139
- }
140
-
141
- impl HistoryEventExt for HistoryEvent {
142
- fn get_changed_marker_details(&self) -> Option<(String, bool)> {
143
- if self.event_type() == EventType::MarkerRecorded {
144
- match &self.attributes {
145
- Some(history_event::Attributes::MarkerRecordedEventAttributes(
146
- MarkerRecordedEventAttributes {
147
- marker_name,
148
- details,
149
- ..
150
- },
151
- )) if marker_name == HAS_CHANGE_MARKER_NAME => {
152
- decode_change_marker_details(details)
153
- }
154
- _ => None,
155
- }
156
- } else {
157
- None
158
- }
159
- }
160
- }