@temporalio/core-bridge 1.11.1 → 1.11.3

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 (79) hide show
  1. package/Cargo.lock +86 -88
  2. package/lib/errors.d.ts +2 -0
  3. package/lib/errors.js +5 -1
  4. package/lib/errors.js.map +1 -1
  5. package/lib/index.d.ts +3 -0
  6. package/lib/index.js.map +1 -1
  7. package/package.json +3 -3
  8. package/releases/aarch64-apple-darwin/index.node +0 -0
  9. package/releases/aarch64-unknown-linux-gnu/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/sdk-core/.github/workflows/per-pr.yml +7 -1
  14. package/sdk-core/Cargo.toml +1 -1
  15. package/sdk-core/client/Cargo.toml +3 -3
  16. package/sdk-core/client/src/lib.rs +1 -1
  17. package/sdk-core/client/src/metrics.rs +2 -2
  18. package/sdk-core/client/src/raw.rs +39 -13
  19. package/sdk-core/client/src/retry.rs +108 -62
  20. package/sdk-core/client/src/workflow_handle/mod.rs +1 -2
  21. package/sdk-core/core/Cargo.toml +4 -5
  22. package/sdk-core/core/src/abstractions.rs +2 -3
  23. package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
  24. package/sdk-core/core/src/core_tests/local_activities.rs +2 -2
  25. package/sdk-core/core/src/core_tests/queries.rs +8 -4
  26. package/sdk-core/core/src/core_tests/updates.rs +2 -2
  27. package/sdk-core/core/src/core_tests/workflow_cancels.rs +3 -3
  28. package/sdk-core/core/src/core_tests/workflow_tasks.rs +55 -54
  29. package/sdk-core/core/src/ephemeral_server/mod.rs +5 -3
  30. package/sdk-core/core/src/protosext/mod.rs +3 -0
  31. package/sdk-core/core/src/telemetry/mod.rs +0 -8
  32. package/sdk-core/core/src/telemetry/otel.rs +7 -3
  33. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +11 -0
  34. package/sdk-core/core/src/worker/activities.rs +1 -1
  35. package/sdk-core/core/src/worker/mod.rs +6 -6
  36. package/sdk-core/core/src/worker/slot_provider.rs +4 -3
  37. package/sdk-core/core/src/worker/tuner/resource_based.rs +1 -1
  38. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +28 -2
  39. package/sdk-core/core/src/worker/workflow/history_update.rs +2 -2
  40. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +8 -5
  41. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -1
  42. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -1
  43. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +7 -7
  44. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +10 -15
  45. package/sdk-core/core/src/worker/workflow/machines/mod.rs +1 -1
  46. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +3 -2
  47. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -1
  48. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +4 -4
  49. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +30 -20
  50. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +2 -2
  51. package/sdk-core/core/src/worker/workflow/managed_run.rs +20 -4
  52. package/sdk-core/core/src/worker/workflow/mod.rs +33 -29
  53. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +2 -2
  54. package/sdk-core/core-api/src/telemetry.rs +1 -0
  55. package/sdk-core/docker/docker-compose-telem.yaml +4 -4
  56. package/sdk-core/etc/otel-collector-config.yaml +12 -9
  57. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +2 -2
  58. package/sdk-core/sdk/src/lib.rs +30 -3
  59. package/sdk-core/sdk/src/workflow_context.rs +15 -2
  60. package/sdk-core/sdk/src/workflow_future.rs +28 -8
  61. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +31 -12
  62. package/sdk-core/sdk-core-protos/src/lib.rs +104 -63
  63. package/sdk-core/test-utils/src/lib.rs +4 -3
  64. package/sdk-core/tests/integ_tests/client_tests.rs +36 -7
  65. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -1
  66. package/sdk-core/tests/integ_tests/metrics_tests.rs +50 -4
  67. package/sdk-core/tests/integ_tests/queries_tests.rs +95 -62
  68. package/sdk-core/tests/integ_tests/update_tests.rs +16 -9
  69. package/sdk-core/tests/integ_tests/visibility_tests.rs +1 -1
  70. package/sdk-core/tests/integ_tests/worker_tests.rs +82 -1
  71. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +46 -8
  72. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +81 -2
  73. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +139 -4
  74. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +43 -28
  75. package/sdk-core/tests/integ_tests/workflow_tests.rs +2 -1
  76. package/sdk-core/tests/main.rs +28 -19
  77. package/sdk-core/tests/runner.rs +7 -2
  78. package/ts/errors.ts +9 -2
  79. package/ts/index.ts +3 -0
@@ -90,13 +90,13 @@ fsm! {
90
90
 
91
91
  #[derive(Debug, derive_more::Display)]
92
92
  pub(super) enum ActivityMachineCommand {
93
- #[display(fmt = "Complete")]
93
+ #[display("Complete")]
94
94
  Complete(Option<Payloads>),
95
- #[display(fmt = "Fail")]
95
+ #[display("Fail")]
96
96
  Fail(Failure),
97
- #[display(fmt = "Cancel")]
97
+ #[display("Cancel")]
98
98
  Cancel(Option<ActivityTaskCanceledEventAttributes>),
99
- #[display(fmt = "RequestCancellation")]
99
+ #[display("RequestCancellation")]
100
100
  RequestCancellation(Command),
101
101
  }
102
102
 
@@ -166,6 +166,7 @@ impl ActivityMachine {
166
166
  failure: Some(new_cancel_failure(&self.shared_state, attrs)),
167
167
  })),
168
168
  }),
169
+ is_local: false,
169
170
  }
170
171
  }
171
172
  }
@@ -265,6 +266,7 @@ impl WFMachinesAdapter for ActivityMachine {
265
266
  result: convert_payloads(event_info, result)?,
266
267
  })),
267
268
  }),
269
+ is_local: false,
268
270
  }
269
271
  .into()]
270
272
  }
@@ -276,6 +278,7 @@ impl WFMachinesAdapter for ActivityMachine {
276
278
  failure: Some(failure),
277
279
  })),
278
280
  }),
281
+ is_local: false,
279
282
  }
280
283
  .into()]
281
284
  }
@@ -838,7 +841,7 @@ mod test {
838
841
  assert_matches!(
839
842
  a.jobs.as_slice(),
840
843
  [WorkflowActivationJob {
841
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
844
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
842
845
  }]
843
846
  )
844
847
  });
@@ -51,7 +51,7 @@ pub(super) struct SharedState {
51
51
  pub(super) enum CancelExternalCommand {
52
52
  /// The target workflow has been notified of the cancel
53
53
  Requested,
54
- #[display(fmt = "Failed")]
54
+ #[display("Failed")]
55
55
  Failed(CancelExternalWorkflowExecutionFailedCause),
56
56
  }
57
57
 
@@ -133,7 +133,7 @@ mod tests {
133
133
  assert_matches!(
134
134
  a.jobs.as_slice(),
135
135
  [WorkflowActivationJob {
136
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
136
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
137
137
  }]
138
138
  )
139
139
  });
@@ -105,19 +105,19 @@ pub(super) struct ChildWorkflowExecutionStartedEvent {
105
105
 
106
106
  #[derive(Debug, derive_more::Display)]
107
107
  pub(super) enum ChildWorkflowCommand {
108
- #[display(fmt = "Start")]
108
+ #[display("Start")]
109
109
  Start(WorkflowExecution),
110
- #[display(fmt = "Complete")]
110
+ #[display("Complete")]
111
111
  Complete(Option<Payloads>),
112
- #[display(fmt = "Fail")]
112
+ #[display("Fail")]
113
113
  Fail(Failure),
114
- #[display(fmt = "Cancel")]
114
+ #[display("Cancel")]
115
115
  Cancel,
116
- #[display(fmt = "StartFail")]
116
+ #[display("StartFail")]
117
117
  StartFail(StartChildWorkflowExecutionFailedCause),
118
- #[display(fmt = "StartCancel")]
118
+ #[display("StartCancel")]
119
119
  StartCancel(Failure),
120
- #[display(fmt = "CancelAfterStarted")]
120
+ #[display("CancelAfterStarted")]
121
121
  IssueCancelAfterStarted { reason: String },
122
122
  }
123
123
 
@@ -8,7 +8,7 @@ use crate::{
8
8
  worker::{
9
9
  workflow::{
10
10
  machines::{activity_state_machine::activity_fail_info, HistEventData},
11
- InternalFlagsRef, OutgoingJob,
11
+ InternalFlagsRef,
12
12
  },
13
13
  LocalActivityExecutionResult,
14
14
  },
@@ -342,17 +342,17 @@ impl SharedState {
342
342
  #[derive(Debug, derive_more::Display)]
343
343
  pub(super) enum LocalActivityCommand {
344
344
  RequestActivityExecution(ValidScheduleLA),
345
- #[display(fmt = "Resolved")]
345
+ #[display("Resolved")]
346
346
  Resolved(ResolveDat),
347
347
  /// The fake marker is used to avoid special casing marker recorded event handling.
348
348
  /// If we didn't have the fake marker, there would be no "outgoing command" to match
349
349
  /// against the event. This way there is, but the command never will be issued to
350
350
  /// server because it is understood to be meaningless.
351
- #[display(fmt = "FakeMarker")]
351
+ #[display("FakeMarker")]
352
352
  FakeMarker,
353
353
  /// Indicate we want to cancel an LA that is currently executing, or look up if we have
354
354
  /// processed a marker with resolution data since the machine was constructed.
355
- #[display(fmt = "Cancel")]
355
+ #[display("Cancel")]
356
356
  RequestCancel,
357
357
  }
358
358
 
@@ -631,9 +631,6 @@ impl Cancellable for LocalActivityMachine {
631
631
  }
632
632
  }
633
633
 
634
- #[derive(Default, Clone)]
635
- pub(super) struct Abandoned {}
636
-
637
634
  impl WFMachinesAdapter for LocalActivityMachine {
638
635
  fn adapt_response(
639
636
  &self,
@@ -737,14 +734,12 @@ impl WFMachinesAdapter for LocalActivityMachine {
737
734
  };
738
735
 
739
736
  let mut responses = vec![
740
- MachineResponse::PushWFJob(OutgoingJob {
741
- variant: ResolveActivity {
742
- seq: self.shared_state.attrs.seq,
743
- result: Some(resolution),
744
- }
745
- .into(),
746
- is_la_resolution: true,
747
- }),
737
+ ResolveActivity {
738
+ seq: self.shared_state.attrs.seq,
739
+ result: Some(resolution),
740
+ is_local: true,
741
+ }
742
+ .into(),
748
743
  MachineResponse::UpdateWFTime(complete_time),
749
744
  ];
750
745
 
@@ -236,7 +236,7 @@ trait WFMachinesAdapter: StateMachine {
236
236
  /// Wraps a history event with extra relevant data that a machine might care about while the event
237
237
  /// is being applied to it.
238
238
  #[derive(Debug, derive_more::Display)]
239
- #[display(fmt = "{event}")]
239
+ #[display("{event}")]
240
240
  struct HistEventData {
241
241
  event: HistoryEvent,
242
242
  /// Is the current workflow task under replay or not during application of this event?
@@ -551,10 +551,11 @@ mod tests {
551
551
 
552
552
  let mut aai = ActivationAssertionsInterceptor::default();
553
553
  aai.then(move |act| {
554
- // replaying cases should immediately get a resolve change activation when marker is present
554
+ // replaying cases should immediately get a resolve change activation when marker is
555
+ // present
555
556
  if replaying && marker_type != MarkerType::NoMarker {
556
557
  assert_matches!(
557
- &act.jobs[0],
558
+ &act.jobs[1],
558
559
  WorkflowActivationJob {
559
560
  variant: Some(workflow_activation_job::Variant::NotifyHasPatch(
560
561
  NotifyHasPatch {
@@ -60,7 +60,7 @@ pub(super) struct SharedState {
60
60
  #[derive(Debug, derive_more::Display)]
61
61
  pub(super) enum SignalExternalCommand {
62
62
  Signaled,
63
- #[display(fmt = "Failed")]
63
+ #[display("Failed")]
64
64
  Failed(SignalExternalWorkflowExecutionFailedCause),
65
65
  Cancelled,
66
66
  }
@@ -59,13 +59,13 @@ fsm! {
59
59
 
60
60
  #[derive(Debug, derive_more::Display)]
61
61
  pub(super) enum UpdateMachineCommand {
62
- #[display(fmt = "Accept")]
62
+ #[display("Accept")]
63
63
  Accept(update::v1::Request),
64
- #[display(fmt = "Reject")]
64
+ #[display("Reject")]
65
65
  Reject(update::v1::Request, Failure),
66
- #[display(fmt = "Complete")]
66
+ #[display("Complete")]
67
67
  Complete(Payload),
68
- #[display(fmt = "Fail")]
68
+ #[display("Fail")]
69
69
  Fail(Failure),
70
70
  }
71
71
 
@@ -163,7 +163,7 @@ pub(crate) struct WorkflowMachines {
163
163
  }
164
164
 
165
165
  #[derive(Debug, derive_more::Display)]
166
- #[display(fmt = "Cmd&Machine({command})")]
166
+ #[display("Cmd&Machine({command})")]
167
167
  struct CommandAndMachine {
168
168
  command: MachineAssociatedCommand,
169
169
  machine: MachineKey,
@@ -172,7 +172,7 @@ struct CommandAndMachine {
172
172
  #[derive(Debug, derive_more::Display)]
173
173
  enum MachineAssociatedCommand {
174
174
  Real(Box<ProtoCommand>),
175
- #[display(fmt = "FakeLocalActivityMarker({_0})")]
175
+ #[display("FakeLocalActivityMarker({_0})")]
176
176
  FakeLocalActivityMarker(u32),
177
177
  }
178
178
 
@@ -186,7 +186,7 @@ struct ChangeInfo {
186
186
  #[must_use]
187
187
  #[allow(clippy::large_enum_variant)]
188
188
  pub(super) enum MachineResponse {
189
- #[display(fmt = "PushWFJob({_0})")]
189
+ #[display("PushWFJob({_0})")]
190
190
  PushWFJob(OutgoingJob),
191
191
 
192
192
  /// Pushes a new command into the list that will be sent to server once we respond with the
@@ -198,31 +198,31 @@ pub(super) enum MachineResponse {
198
198
  /// The machine requests the creation of another *different* machine. This acts as if lang
199
199
  /// had replied to the activation with a command, but we use a special set of IDs to avoid
200
200
  /// collisions.
201
- #[display(fmt = "NewCoreOriginatedCommand({_0:?})")]
201
+ #[display("NewCoreOriginatedCommand({_0:?})")]
202
202
  NewCoreOriginatedCommand(ProtoCmdAttrs),
203
- #[display(fmt = "IssueFakeLocalActivityMarker({_0})")]
203
+ #[display("IssueFakeLocalActivityMarker({_0})")]
204
204
  IssueFakeLocalActivityMarker(u32),
205
- #[display(fmt = "TriggerWFTaskStarted")]
205
+ #[display("TriggerWFTaskStarted")]
206
206
  TriggerWFTaskStarted {
207
207
  task_started_event_id: i64,
208
208
  time: SystemTime,
209
209
  },
210
- #[display(fmt = "UpdateRunIdOnWorkflowReset({run_id})")]
210
+ #[display("UpdateRunIdOnWorkflowReset({run_id})")]
211
211
  UpdateRunIdOnWorkflowReset { run_id: String },
212
212
 
213
213
  /// Queue a local activity to be processed by the worker
214
- #[display(fmt = "QueueLocalActivity")]
214
+ #[display("QueueLocalActivity")]
215
215
  QueueLocalActivity(ValidScheduleLA),
216
216
  /// Request cancellation of an executing local activity
217
- #[display(fmt = "RequestCancelLocalActivity({_0})")]
217
+ #[display("RequestCancelLocalActivity({_0})")]
218
218
  RequestCancelLocalActivity(u32),
219
219
  /// Indicates we are abandoning the indicated LA, so we can remove it from "outstanding" LAs
220
220
  /// and we will not try to WFT heartbeat because of it.
221
- #[display(fmt = "AbandonLocalActivity({_0:?})")]
221
+ #[display("AbandonLocalActivity({_0:?})")]
222
222
  AbandonLocalActivity(u32),
223
223
 
224
224
  /// Set the workflow time to the provided time
225
- #[display(fmt = "UpdateWFTime({_0:?})")]
225
+ #[display("UpdateWFTime({_0:?})")]
226
226
  UpdateWFTime(Option<SystemTime>),
227
227
  }
228
228
 
@@ -449,7 +449,7 @@ impl WorkflowMachines {
449
449
  self.drive_me
450
450
  .peek_pending_jobs()
451
451
  .iter()
452
- .any(|v| v.is_la_resolution)
452
+ .any(|v| v.variant.is_local_activity_resolution())
453
453
  }
454
454
 
455
455
  pub(crate) fn get_metadata_for_wft_complete(&mut self) -> WorkflowTaskCompletedMetadata {
@@ -701,7 +701,16 @@ impl WorkflowMachines {
701
701
  }
702
702
  let mut delayed_actions = vec![];
703
703
  // Scan through to the next WFT, searching for any patch / la markers, so that we can
704
- // pre-resolve them.
704
+ // pre-resolve them. This lookahead is necessary because we need these things to be already
705
+ // resolved in the same activations they would have been resolved in during initial
706
+ // execution. For example: If a workflow asks to run an LA and then waits on it, we will
707
+ // write the completion marker at the end of that WFT (as a command). So, upon replay,
708
+ // we need to lookahead and see that that LA is in fact resolved, so that we don't decide
709
+ // to execute it anew when lang says it wants to run it.
710
+ //
711
+ // Alternatively, lookahead can seemingly be avoided if we were to consider the commands
712
+ // that follow a WFT to be _part of_ that wft rather than the next one. That change might
713
+ // make sense to do, and maybe simplifies things slightly, but is a substantial alteration.
705
714
  for e in self
706
715
  .last_history_from_server
707
716
  .peek_next_wft_sequence(last_handled_wft_started_id)
@@ -1152,6 +1161,9 @@ impl WorkflowMachines {
1152
1161
  );
1153
1162
  }
1154
1163
  ProtoCmdAttrs::UpsertWorkflowSearchAttributesCommandAttributes(attrs) => {
1164
+ // We explicitly do not update the workflows current SAs here since
1165
+ // core-generated upserts aren't meant to be modified or used within
1166
+ // workflows by users (but rather, just for them to search with).
1155
1167
  self.add_cmd_to_wf_task(
1156
1168
  upsert_search_attrs_internal(attrs),
1157
1169
  CommandIdKind::NeverResolves,
@@ -1262,6 +1274,8 @@ impl WorkflowMachines {
1262
1274
  self.add_cmd_to_wf_task(new_timer(attrs), CommandID::Timer(seq).into());
1263
1275
  }
1264
1276
  WFCommand::UpsertSearchAttributes(attrs) => {
1277
+ self.drive_me
1278
+ .search_attributes_update(attrs.search_attributes.clone());
1265
1279
  self.add_cmd_to_wf_task(
1266
1280
  upsert_search_attrs(
1267
1281
  attrs,
@@ -1538,17 +1552,13 @@ impl WorkflowMachines {
1538
1552
  .map(Into::into)
1539
1553
  .unwrap_or_default();
1540
1554
  }
1541
- if attrs.search_attributes.is_empty() {
1542
- attrs.search_attributes = started_info
1543
- .search_attrs
1544
- .clone()
1545
- .map(Into::into)
1546
- .unwrap_or_default();
1547
- }
1548
1555
  if attrs.retry_policy.is_none() {
1549
1556
  attrs.retry_policy.clone_from(&started_info.retry_policy);
1550
1557
  }
1551
1558
  }
1559
+ if attrs.search_attributes.is_empty() {
1560
+ attrs.search_attributes = self.drive_me.get_current_search_attributes();
1561
+ }
1552
1562
  attrs
1553
1563
  }
1554
1564
 
@@ -44,12 +44,12 @@ impl WorkflowTaskMachine {
44
44
  #[derive(Debug, derive_more::Display)]
45
45
  pub(super) enum WFTaskMachineCommand {
46
46
  /// Issued to (possibly) trigger the event loop
47
- #[display(fmt = "WFTaskStartedTrigger")]
47
+ #[display("WFTaskStartedTrigger")]
48
48
  WFTaskStartedTrigger {
49
49
  task_started_event_id: i64,
50
50
  time: SystemTime,
51
51
  },
52
- #[display(fmt = "RunIdOnWorkflowResetUpdate({run_id})")]
52
+ #[display("RunIdOnWorkflowResetUpdate({run_id})")]
53
53
  RunIdOnWorkflowResetUpdate { run_id: String },
54
54
  }
55
55
 
@@ -52,9 +52,9 @@ pub(super) type RunUpdateAct = Option<ActivationOrAuto>;
52
52
 
53
53
  /// Manages access to a specific workflow run. Everything inside is entirely synchronous and should
54
54
  /// remain that way.
55
- #[derive(derive_more::DebugCustom)]
55
+ #[derive(derive_more::Debug)]
56
56
  #[debug(
57
- fmt = "ManagedRun {{ wft: {:?}, activation: {:?}, task_buffer: {:?} \
57
+ "ManagedRun {{ wft: {:?}, activation: {:?}, task_buffer: {:?} \
58
58
  trying_to_evict: {} }}",
59
59
  wft,
60
60
  activation,
@@ -562,6 +562,7 @@ impl ManagedRun {
562
562
  reason,
563
563
  EvictionReason::Unspecified | EvictionReason::PaginationOrHistoryFetch
564
564
  );
565
+
565
566
  let (should_report, rur) = if is_no_report_query_fail {
566
567
  (false, None)
567
568
  } else {
@@ -580,6 +581,7 @@ impl ManagedRun {
580
581
  let rur = evict_req_outcome.into_run_update_resp();
581
582
  (should_report, rur)
582
583
  };
584
+
583
585
  let outcome = if self.pending_work_is_legacy_query() {
584
586
  if is_no_report_query_fail {
585
587
  ActivationCompleteOutcome::WFTFailedDontReport
@@ -617,6 +619,7 @@ impl ManagedRun {
617
619
  } else {
618
620
  ActivationCompleteOutcome::WFTFailedDontReport
619
621
  };
622
+
620
623
  self.metrics
621
624
  .with_new_attrs([metrics::failure_reason(cause.into())])
622
625
  .wf_task_failed();
@@ -870,6 +873,19 @@ impl ManagedRun {
870
873
 
871
874
  if !self.activation_is_eviction() && self.trying_to_evict.is_none() {
872
875
  debug!(run_id=%info.run_id, reason=%info.message, "Eviction requested");
876
+ // If we've requested an eviction because of failure related reasons then we want to
877
+ // delete any pending queries, since handling them no longer makes sense. Evictions
878
+ // because the cache is full should get a chance to finish processing properly.
879
+ if !matches!(info.reason, EvictionReason::CacheFull)
880
+ // If the wft was just a legacy query, still reply, otherwise we might try to
881
+ // reply to the task as if it were a task rather than a query.
882
+ && !self.pending_work_is_legacy_query()
883
+ {
884
+ if let Some(wft) = self.wft.as_mut() {
885
+ wft.pending_queries.clear();
886
+ }
887
+ }
888
+
873
889
  self.trying_to_evict = Some(info);
874
890
  EvictionRequestResult::EvictionRequested(attempts, self.check_more_activations())
875
891
  } else {
@@ -1456,8 +1472,8 @@ enum ActOrFulfill {
1456
1472
  FulfillableComplete(Option<FulfillableActivationComplete>),
1457
1473
  }
1458
1474
 
1459
- #[derive(derive_more::DebugCustom)]
1460
- #[debug(fmt = "RunUpdateErr({source:?})")]
1475
+ #[derive(derive_more::Debug)]
1476
+ #[debug("RunUpdateErr({source:?})")]
1461
1477
  struct RunUpdateErr {
1462
1478
  source: WFMachinesError,
1463
1479
  complete_resp_chan: Option<oneshot::Sender<ActivationCompleteResult>>,
@@ -44,12 +44,10 @@ use itertools::Itertools;
44
44
  use prost_types::TimestampError;
45
45
  use std::{
46
46
  cell::RefCell,
47
- cmp::Ordering,
48
47
  collections::VecDeque,
49
48
  fmt::Debug,
50
49
  future::Future,
51
50
  mem,
52
- mem::discriminant,
53
51
  ops::DerefMut,
54
52
  rc::Rc,
55
53
  result,
@@ -722,10 +720,7 @@ impl Workflows {
722
720
  /// Returned when a cache miss happens and we need to fetch history from the beginning to
723
721
  /// replay a run
724
722
  #[derive(Debug, derive_more::Display)]
725
- #[display(
726
- fmt = "CacheMissFetchReq(run_id: {})",
727
- "original_wft.work.execution.run_id"
728
- )]
723
+ #[display("CacheMissFetchReq(run_id: {})", "original_wft.work.execution.run_id")]
729
724
  #[must_use]
730
725
  struct CacheMissFetchReq {
731
726
  original_wft: PermittedWFT,
@@ -751,11 +746,11 @@ enum ActivationOrAuto {
751
746
  /// This type should only be filled with an empty activation which is ready to have queries
752
747
  /// inserted into the joblist
753
748
  ReadyForQueries(WorkflowActivation),
754
- #[display(fmt = "Autocomplete(run_id={run_id})")]
749
+ #[display("Autocomplete(run_id={run_id})")]
755
750
  Autocomplete {
756
751
  run_id: String,
757
752
  },
758
- #[display(fmt = "AutoFail(run_id={run_id})")]
753
+ #[display("AutoFail(run_id={run_id})")]
759
754
  AutoFail {
760
755
  run_id: String,
761
756
  machines_err: WFMachinesError,
@@ -764,8 +759,8 @@ enum ActivationOrAuto {
764
759
 
765
760
  /// A WFT which is considered to be using a slot for metrics purposes and being or about to be
766
761
  /// applied to workflow state.
767
- #[derive(derive_more::DebugCustom)]
768
- #[debug(fmt = "PermittedWft({work:?})")]
762
+ #[derive(derive_more::Debug)]
763
+ #[debug("PermittedWft({work:?})")]
769
764
  pub(crate) struct PermittedWFT {
770
765
  work: PreparedWFT,
771
766
  permit: UsedMeteredSemPermit<WorkflowSlotKind>,
@@ -1247,19 +1242,13 @@ struct WorkflowStartedInfo {
1247
1242
 
1248
1243
  /// Wraps outgoing activation job protos with some internal details core might care about
1249
1244
  #[derive(Debug, derive_more::Display)]
1250
- #[display(fmt = "{variant}")]
1245
+ #[display("{variant}")]
1251
1246
  struct OutgoingJob {
1252
1247
  variant: workflow_activation_job::Variant,
1253
- /// Since LA resolutions are not distinguished from non-LA resolutions as far as lang is
1254
- /// concerned, but core cares about that sometimes, attach that info here.
1255
- is_la_resolution: bool,
1256
1248
  }
1257
1249
  impl<WA: Into<workflow_activation_job::Variant>> From<WA> for OutgoingJob {
1258
1250
  fn from(wa: WA) -> Self {
1259
- Self {
1260
- variant: wa.into(),
1261
- is_la_resolution: false,
1262
- }
1251
+ Self { variant: wa.into() }
1263
1252
  }
1264
1253
  }
1265
1254
  impl From<OutgoingJob> for WorkflowActivationJob {
@@ -1333,8 +1322,17 @@ impl LocalActivityRequestSink for LAReqSink {
1333
1322
  /// Sorts jobs in an activation to be in the order lang expects, and confirms any invariants
1334
1323
  /// activations must uphold.
1335
1324
  ///
1336
- /// ## Ordering
1337
- /// `patches -> signals/updates -> other -> queries -> evictions`
1325
+ /// ## Job Ordering
1326
+ /// 1. init workflow
1327
+ /// 2. patches
1328
+ /// 3. random-seed-updates
1329
+ /// 4. signals/updates
1330
+ /// 5. all others
1331
+ /// 6. local activity resolutions
1332
+ /// 7. queries
1333
+ /// 8. evictions
1334
+ ///
1335
+ /// See the [WorkflowActivation] docstring for more detail
1338
1336
  ///
1339
1337
  /// ## Invariants:
1340
1338
  /// * Queries always go in their own activation
@@ -1361,26 +1359,26 @@ fn prepare_to_ship_activation(wfa: &mut WorkflowActivation) {
1361
1359
  // Unwrapping is fine here since we'll never issue empty variants
1362
1360
  let j1v = j1.variant.as_ref().unwrap();
1363
1361
  let j2v = j2.variant.as_ref().unwrap();
1364
- if discriminant(j1v) == discriminant(j2v) {
1365
- return Ordering::Equal;
1366
- }
1367
1362
  fn variant_ordinal(v: &workflow_activation_job::Variant) -> u8 {
1368
1363
  match v {
1364
+ workflow_activation_job::Variant::InitializeWorkflow(_) => 0,
1369
1365
  workflow_activation_job::Variant::NotifyHasPatch(_) => 1,
1370
- workflow_activation_job::Variant::SignalWorkflow(_) => 2,
1371
- workflow_activation_job::Variant::DoUpdate(_) => 2,
1366
+ workflow_activation_job::Variant::UpdateRandomSeed(_) => 2,
1367
+ workflow_activation_job::Variant::SignalWorkflow(_) => 3,
1368
+ workflow_activation_job::Variant::DoUpdate(_) => 3,
1369
+ workflow_activation_job::Variant::ResolveActivity(ra) if ra.is_local => 5,
1372
1370
  // In principle we should never actually need to sort these with the others, since
1373
1371
  // queries always get their own activation, but, maintaining the semantic is
1374
1372
  // reasonable.
1375
- workflow_activation_job::Variant::QueryWorkflow(_) => 4,
1373
+ workflow_activation_job::Variant::QueryWorkflow(_) => 6,
1376
1374
  // Also shouldn't ever end up anywhere but the end by construction, but no harm in
1377
1375
  // double-checking.
1378
- workflow_activation_job::Variant::RemoveFromCache(_) => 5,
1379
- _ => 3,
1376
+ workflow_activation_job::Variant::RemoveFromCache(_) => 7,
1377
+ _ => 4,
1380
1378
  }
1381
1379
  }
1382
1380
  variant_ordinal(j1v).cmp(&variant_ordinal(j2v))
1383
- })
1381
+ });
1384
1382
  }
1385
1383
 
1386
1384
  #[cfg(test)]
@@ -1421,6 +1419,11 @@ mod tests {
1421
1419
  Default::default(),
1422
1420
  )),
1423
1421
  },
1422
+ WorkflowActivationJob {
1423
+ variant: Some(workflow_activation_job::Variant::UpdateRandomSeed(
1424
+ Default::default(),
1425
+ )),
1426
+ },
1424
1427
  WorkflowActivationJob {
1425
1428
  variant: Some(workflow_activation_job::Variant::SignalWorkflow(
1426
1429
  SignalWorkflow {
@@ -1442,6 +1445,7 @@ mod tests {
1442
1445
  variants.as_slice(),
1443
1446
  &[
1444
1447
  workflow_activation_job::Variant::NotifyHasPatch(_),
1448
+ workflow_activation_job::Variant::UpdateRandomSeed(_),
1445
1449
  workflow_activation_job::Variant::SignalWorkflow(ref s1),
1446
1450
  workflow_activation_job::Variant::DoUpdate(_),
1447
1451
  workflow_activation_job::Variant::SignalWorkflow(ref s2),
@@ -571,8 +571,8 @@ enum WFStreamInput {
571
571
  }
572
572
 
573
573
  /// A non-poller-received input to the [WFStream]
574
- #[derive(derive_more::DebugCustom)]
575
- #[debug(fmt = "LocalInput {{ {input:?} }}")]
574
+ #[derive(derive_more::Debug)]
575
+ #[debug("LocalInput {{ {input:?} }}")]
576
576
  pub(super) struct LocalInput {
577
577
  pub(super) input: LocalInputs,
578
578
  pub(super) span: Span,
@@ -54,6 +54,7 @@ pub struct OtelCollectorOptions {
54
54
  /// export to this same collector.
55
55
  pub url: Url,
56
56
  /// Optional set of HTTP headers to send to the Collector, e.g for authentication.
57
+ #[builder(default = "HashMap::new()")]
57
58
  pub headers: HashMap<String, String>,
58
59
  /// Optionally specify how frequently metrics should be exported. Defaults to 1 second.
59
60
  #[builder(default = "Duration::from_secs(1)")]
@@ -10,9 +10,9 @@ services:
10
10
 
11
11
  otel-collector:
12
12
  image: otel/opentelemetry-collector:latest
13
- command: ['--config=/etc/otel-collector-config.yaml']
13
+ command: [ '--config=/etc/otel-collector-config.yaml' ]
14
14
  volumes:
15
- - ../../etc/otel-collector-config.yaml:/etc/otel-collector-config.yaml
15
+ - ../etc/otel-collector-config.yaml:/etc/otel-collector-config.yaml
16
16
  ports:
17
17
  # - "1888:1888" # pprof extension
18
18
  # It's useful to be able to manually inspect metrics during dev
@@ -20,7 +20,7 @@ services:
20
20
  - '8889:8889' # Prometheus exporter metrics
21
21
  # - "13133:13133" # health_check extension
22
22
  - '4317:4317' # OTLP gRPC receiver
23
- # - "55670:55679" # zpages extension
23
+ # - "55679:55679" # zpages extension
24
24
  depends_on:
25
25
  - jaeger
26
26
 
@@ -28,6 +28,6 @@ services:
28
28
  container_name: prometheus
29
29
  image: prom/prometheus:latest
30
30
  volumes:
31
- - ../../etc/prometheus.yaml:/etc/prometheus/prometheus.yml
31
+ - ../etc/prometheus.yaml:/etc/prometheus/prometheus.yml
32
32
  ports:
33
33
  - '9090:9090'
@@ -2,16 +2,19 @@ receivers:
2
2
  otlp:
3
3
  protocols:
4
4
  grpc:
5
+ endpoint: 0.0.0.0:4317
6
+ http:
7
+ endpoint: 0.0.0.0:4318
5
8
 
6
9
  exporters:
7
10
  prometheus:
8
11
  endpoint: '0.0.0.0:8889'
9
12
  namespace: temporal_sdk
13
+
10
14
  logging:
11
15
 
12
- jaeger:
16
+ otlp/jaeger:
13
17
  endpoint: jaeger:14250
14
- insecure: true
15
18
 
16
19
  processors:
17
20
  batch:
@@ -24,13 +27,13 @@ extensions:
24
27
  endpoint: :55679
25
28
 
26
29
  service:
27
- extensions: [pprof, zpages, health_check]
30
+ extensions: [ pprof, zpages, health_check ]
28
31
  pipelines:
29
32
  traces:
30
- receivers: [otlp]
31
- processors: [batch]
32
- exporters: [logging, jaeger]
33
+ receivers: [ otlp ]
34
+ processors: [ batch ]
35
+ exporters: [ logging, otlp/jaeger ]
33
36
  metrics:
34
- receivers: [otlp]
35
- processors: [batch]
36
- exporters: [logging, prometheus]
37
+ receivers: [ otlp ]
38
+ processors: [ batch ]
39
+ exporters: [ logging, prometheus ]