@temporalio/core-bridge 0.16.3 → 0.16.4
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.
- package/index.node +0 -0
- package/package.json +3 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/src/core_tests/workflow_tasks.rs +69 -0
- package/sdk-core/src/test_help/history_builder.rs +10 -0
- package/sdk-core/src/test_help/history_info.rs +19 -0
- package/sdk-core/src/test_help/mod.rs +5 -0
- package/sdk-core/src/worker/mod.rs +1 -0
package/index.node
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporalio/core-bridge",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.4",
|
|
4
4
|
"description": "Temporal.io SDK Core<>Node bridge",
|
|
5
5
|
"main": "index.node",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@opentelemetry/api": "^1.0.3",
|
|
22
|
-
"@temporalio/common": "^0.16.
|
|
22
|
+
"@temporalio/common": "^0.16.4",
|
|
23
23
|
"arg": "^5.0.1",
|
|
24
24
|
"cargo-cp-artifact": "^0.1.4",
|
|
25
25
|
"which": "^2.0.2"
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "884a10970cdbc3e8d7991709e0fa3fe79fce71bd"
|
|
44
44
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1665,3 +1665,72 @@ async fn failing_wft_doesnt_eat_permit_forever() {
|
|
|
1665
1665
|
|
|
1666
1666
|
core.shutdown().await;
|
|
1667
1667
|
}
|
|
1668
|
+
|
|
1669
|
+
#[tokio::test]
|
|
1670
|
+
async fn cache_miss_doesnt_eat_permit_forever() {
|
|
1671
|
+
let mut t = TestHistoryBuilder::default();
|
|
1672
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
1673
|
+
t.add_full_wf_task();
|
|
1674
|
+
t.add_we_signaled("sig", vec![]);
|
|
1675
|
+
t.add_full_wf_task();
|
|
1676
|
+
t.add_workflow_execution_completed();
|
|
1677
|
+
|
|
1678
|
+
let mut mh = MockPollCfg::from_resp_batches(
|
|
1679
|
+
"fake_wf_id",
|
|
1680
|
+
t,
|
|
1681
|
+
[
|
|
1682
|
+
ResponseType::ToTaskNum(1),
|
|
1683
|
+
ResponseType::OneTask(2),
|
|
1684
|
+
ResponseType::ToTaskNum(1),
|
|
1685
|
+
ResponseType::OneTask(2),
|
|
1686
|
+
ResponseType::ToTaskNum(1),
|
|
1687
|
+
ResponseType::OneTask(2),
|
|
1688
|
+
// Last one to complete successfully
|
|
1689
|
+
ResponseType::ToTaskNum(1),
|
|
1690
|
+
],
|
|
1691
|
+
MockServerGatewayApis::new(),
|
|
1692
|
+
);
|
|
1693
|
+
mh.num_expected_fails = Some(3);
|
|
1694
|
+
mh.expect_fail_wft_matcher =
|
|
1695
|
+
Box::new(|_, cause, _| matches!(cause, WorkflowTaskFailedCause::ResetStickyTaskQueue));
|
|
1696
|
+
let mut mock = build_mock_pollers(mh);
|
|
1697
|
+
mock.worker_cfg(TEST_Q, |cfg| {
|
|
1698
|
+
cfg.max_outstanding_workflow_tasks = 2;
|
|
1699
|
+
});
|
|
1700
|
+
let core = mock_core(mock);
|
|
1701
|
+
|
|
1702
|
+
// Spin missing the cache to verify that we don't get stuck
|
|
1703
|
+
for _ in 1..=3 {
|
|
1704
|
+
// Start
|
|
1705
|
+
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1706
|
+
core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, activation.run_id))
|
|
1707
|
+
.await
|
|
1708
|
+
.unwrap();
|
|
1709
|
+
// Evict
|
|
1710
|
+
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1711
|
+
assert_matches!(
|
|
1712
|
+
activation.jobs.as_slice(),
|
|
1713
|
+
[WfActivationJob {
|
|
1714
|
+
variant: Some(wf_activation_job::Variant::RemoveFromCache(_)),
|
|
1715
|
+
},]
|
|
1716
|
+
);
|
|
1717
|
+
core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, activation.run_id))
|
|
1718
|
+
.await
|
|
1719
|
+
.unwrap();
|
|
1720
|
+
assert_eq!(core.outstanding_wfts(TEST_Q), 0);
|
|
1721
|
+
assert_eq!(core.available_wft_permits(TEST_Q), 2);
|
|
1722
|
+
// When we loop back up, the poll will trigger a cache miss, which we should immediately
|
|
1723
|
+
// reply to WFT with failure, and then poll again, which will deliver the from-the-start
|
|
1724
|
+
// history
|
|
1725
|
+
}
|
|
1726
|
+
let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
1727
|
+
core.complete_workflow_activation(WfActivationCompletion::from_cmd(
|
|
1728
|
+
TEST_Q,
|
|
1729
|
+
activation.run_id,
|
|
1730
|
+
CompleteWorkflowExecution { result: None }.into(),
|
|
1731
|
+
))
|
|
1732
|
+
.await
|
|
1733
|
+
.unwrap();
|
|
1734
|
+
|
|
1735
|
+
core.shutdown().await;
|
|
1736
|
+
}
|
|
@@ -342,6 +342,16 @@ impl TestHistoryBuilder {
|
|
|
342
342
|
HistoryInfo::new_from_history(&self.events.clone().into(), None)
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
+
pub(crate) fn get_one_wft(
|
|
346
|
+
&self,
|
|
347
|
+
from_wft_number: usize,
|
|
348
|
+
) -> Result<HistoryInfo, HistoryInfoError> {
|
|
349
|
+
let mut histinfo =
|
|
350
|
+
HistoryInfo::new_from_history(&self.events.clone().into(), Some(from_wft_number))?;
|
|
351
|
+
histinfo.make_incremental();
|
|
352
|
+
Ok(histinfo)
|
|
353
|
+
}
|
|
354
|
+
|
|
345
355
|
fn build_and_push_event(&mut self, event_type: EventType, attribs: Attributes) {
|
|
346
356
|
self.current_event_id += 1;
|
|
347
357
|
let evt = HistoryEvent {
|
|
@@ -100,6 +100,18 @@ impl HistoryInfo {
|
|
|
100
100
|
unreachable!()
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
/// Remove events from the beginning of this history such that it looks like what would've been
|
|
104
|
+
/// delivered on a sticky queue where the previously started task was the one before the last
|
|
105
|
+
/// task in this history.
|
|
106
|
+
pub(crate) fn make_incremental(&mut self) {
|
|
107
|
+
let last_complete_ix = self
|
|
108
|
+
.events
|
|
109
|
+
.iter()
|
|
110
|
+
.rposition(|he| he.event_type() == EventType::WorkflowTaskCompleted)
|
|
111
|
+
.expect("Must be a WFT completed event in history");
|
|
112
|
+
self.events.drain(0..=last_complete_ix);
|
|
113
|
+
}
|
|
114
|
+
|
|
103
115
|
pub(crate) fn events(&self) -> &[HistoryEvent] {
|
|
104
116
|
&self.events
|
|
105
117
|
}
|
|
@@ -135,4 +147,11 @@ mod tests {
|
|
|
135
147
|
let history_info = t.get_history_info(2).unwrap();
|
|
136
148
|
assert_eq!(8, history_info.events.len());
|
|
137
149
|
}
|
|
150
|
+
|
|
151
|
+
#[test]
|
|
152
|
+
fn incremental_works() {
|
|
153
|
+
let t = canned_histories::single_timer("timer1");
|
|
154
|
+
let hi = t.get_one_wft(2).unwrap();
|
|
155
|
+
dbg!(hi.events);
|
|
156
|
+
}
|
|
138
157
|
}
|
|
@@ -53,6 +53,10 @@ pub static NO_MORE_WORK_ERROR_MSG: &str = "No more work to do";
|
|
|
53
53
|
#[derive(derive_more::From, Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
|
54
54
|
pub enum ResponseType {
|
|
55
55
|
ToTaskNum(usize),
|
|
56
|
+
/// Returns just the history after the WFT completed of the provided task number - 1, through to
|
|
57
|
+
/// the next WFT started. Simulating the incremental history for just the provided task number
|
|
58
|
+
#[from(ignore)]
|
|
59
|
+
OneTask(usize),
|
|
56
60
|
AllHistory,
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -495,6 +499,7 @@ pub fn hist_to_poll_resp(
|
|
|
495
499
|
};
|
|
496
500
|
let hist_info = match response_type {
|
|
497
501
|
ResponseType::ToTaskNum(tn) => t.get_history_info(tn).unwrap(),
|
|
502
|
+
ResponseType::OneTask(tn) => t.get_one_wft(tn).unwrap(),
|
|
498
503
|
ResponseType::AllHistory => t.get_full_history_info().unwrap(),
|
|
499
504
|
};
|
|
500
505
|
let batch = hist_info.events().to_vec();
|