@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.
- package/Cargo.lock +339 -226
- package/Cargo.toml +7 -3
- package/common.js +50 -0
- package/index.d.ts +7 -0
- package/index.js +12 -0
- package/package.json +7 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/{index.node → releases/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/scripts/build.js +10 -50
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/Cargo.toml +1 -88
- package/sdk-core/README.md +30 -6
- package/sdk-core/bridge-ffi/Cargo.toml +24 -0
- package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
- package/sdk-core/bridge-ffi/build.rs +25 -0
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
- package/sdk-core/bridge-ffi/src/lib.rs +829 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
- package/sdk-core/client/Cargo.toml +32 -0
- package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
- package/sdk-core/client/src/metrics.rs +89 -0
- package/sdk-core/client/src/mocks.rs +167 -0
- package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
- package/sdk-core/core/Cargo.toml +96 -0
- package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
- package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
- package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
- package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
- package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
- package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
- package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
- package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
- package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
- package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
- package/sdk-core/core/src/lib.rs +374 -0
- package/sdk-core/{src → core/src}/log_export.rs +3 -27
- package/sdk-core/core/src/pending_activations.rs +162 -0
- package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
- package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
- package/sdk-core/core/src/protosext/mod.rs +396 -0
- package/sdk-core/core/src/replay/mod.rs +210 -0
- package/sdk-core/core/src/retry_logic.rs +144 -0
- package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
- package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
- package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
- package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
- package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
- package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
- package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
- package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
- package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
- package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
- package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
- package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
- package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
- package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
- package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
- package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
- package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
- package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
- package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
- package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
- package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
- package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
- package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
- package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
- package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
- package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
- package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
- package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
- package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
- package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
- package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
- package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
- package/sdk-core/{src → core-api/src}/errors.rs +42 -92
- package/sdk-core/core-api/src/lib.rs +158 -0
- package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
- package/sdk-core/etc/deps.svg +156 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
- package/sdk-core/histories/fail_wf_task.bin +0 -0
- package/sdk-core/histories/timer_workflow_history.bin +0 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
- package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
- package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
- package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
- package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
- package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
- package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
- package/sdk-core/sdk/Cargo.toml +32 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
- package/sdk-core/sdk/src/lib.rs +699 -0
- package/sdk-core/sdk/src/payload_converter.rs +11 -0
- package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
- package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
- package/sdk-core/sdk-core-protos/build.rs +28 -6
- package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
- package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
- package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- package/sdk-core/test-utils/Cargo.toml +32 -0
- package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
- package/sdk-core/test-utils/src/histfetch.rs +28 -0
- package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
- package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
- package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
- package/sdk-core/tests/load_tests.rs +6 -6
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +24 -21
- package/src/errors.rs +8 -0
- package/src/lib.rs +323 -211
- package/sdk-core/protos/local/activity_result.proto +0 -46
- package/sdk-core/protos/local/activity_task.proto +0 -66
- package/sdk-core/src/core_tests/retry.rs +0 -147
- package/sdk-core/src/lib.rs +0 -403
- package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
- package/sdk-core/src/pending_activations.rs +0 -249
- package/sdk-core/src/protosext/mod.rs +0 -160
- package/sdk-core/src/prototype_rust_sdk.rs +0 -412
- package/sdk-core/src/task_token.rs +0 -20
- package/sdk-core/src/test_help/history_info.rs +0 -157
package/src/lib.rs
CHANGED
|
@@ -4,27 +4,42 @@ mod errors;
|
|
|
4
4
|
use crate::conversions::ObjectHandleConversionsExt;
|
|
5
5
|
use errors::*;
|
|
6
6
|
use neon::prelude::*;
|
|
7
|
+
use once_cell::sync::OnceCell;
|
|
7
8
|
use opentelemetry::trace::{FutureExt, SpanContext, TraceContextExt};
|
|
8
9
|
use prost::Message;
|
|
9
10
|
use std::{
|
|
10
11
|
fmt::Display,
|
|
11
12
|
future::Future,
|
|
13
|
+
ops::Deref,
|
|
12
14
|
sync::Arc,
|
|
13
15
|
time::{Duration, SystemTime, UNIX_EPOCH},
|
|
14
16
|
};
|
|
15
17
|
use temporal_sdk_core::{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
api::{
|
|
19
|
+
errors::{
|
|
20
|
+
CompleteActivityError, CompleteWfError, CoreInitError, PollActivityError, PollWfError,
|
|
21
|
+
},
|
|
22
|
+
Core,
|
|
18
23
|
},
|
|
19
|
-
init,
|
|
24
|
+
init,
|
|
25
|
+
protos::{
|
|
26
|
+
coresdk::{
|
|
27
|
+
workflow_completion::WorkflowActivationCompletion, ActivityHeartbeat,
|
|
28
|
+
ActivityTaskCompletion,
|
|
29
|
+
},
|
|
30
|
+
temporal::api::history::v1::History,
|
|
31
|
+
},
|
|
32
|
+
replay::{init_core_replay, ReplayCore, ReplayCoreImpl},
|
|
33
|
+
CoreInitOptionsBuilder, CoreSDK, WorkerConfig,
|
|
20
34
|
};
|
|
21
|
-
use
|
|
22
|
-
|
|
35
|
+
use tokio::{
|
|
36
|
+
runtime::Runtime,
|
|
37
|
+
sync::mpsc::{unbounded_channel, UnboundedSender},
|
|
23
38
|
};
|
|
24
|
-
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
|
25
39
|
|
|
26
40
|
/// A request from JS to bridge to core
|
|
27
|
-
|
|
41
|
+
#[derive(Debug)]
|
|
42
|
+
enum Request {
|
|
28
43
|
/// A request to shutdown Core, any registered workers will be shutdown as well.
|
|
29
44
|
/// Breaks from the thread loop.
|
|
30
45
|
Shutdown {
|
|
@@ -45,6 +60,15 @@ pub enum Request {
|
|
|
45
60
|
/// Used to send the result back into JS
|
|
46
61
|
callback: Root<JsFunction>,
|
|
47
62
|
},
|
|
63
|
+
/// A request to register a replay worker. Will only work against a replay core instance.
|
|
64
|
+
RegisterReplayWorker {
|
|
65
|
+
/// Worker configuration. Must have unique task queue name.
|
|
66
|
+
config: WorkerConfig,
|
|
67
|
+
/// The history this worker should replay
|
|
68
|
+
history: History,
|
|
69
|
+
/// Used to send the result back into JS
|
|
70
|
+
callback: Root<JsFunction>,
|
|
71
|
+
},
|
|
48
72
|
/// A request to poll for workflow activations
|
|
49
73
|
PollWorkflowActivation {
|
|
50
74
|
/// Name of queue to poll on
|
|
@@ -55,7 +79,7 @@ pub enum Request {
|
|
|
55
79
|
},
|
|
56
80
|
/// A request to complete a single workflow activation
|
|
57
81
|
CompleteWorkflowActivation {
|
|
58
|
-
completion:
|
|
82
|
+
completion: WorkflowActivationCompletion,
|
|
59
83
|
otel_span: SpanContext,
|
|
60
84
|
/// Used to send the result back into JS
|
|
61
85
|
callback: Root<JsFunction>,
|
|
@@ -85,27 +109,51 @@ pub enum Request {
|
|
|
85
109
|
}
|
|
86
110
|
|
|
87
111
|
#[derive(Clone)]
|
|
88
|
-
|
|
112
|
+
struct CoreHandle {
|
|
89
113
|
sender: UnboundedSender<Request>,
|
|
90
114
|
}
|
|
91
|
-
|
|
92
115
|
/// Box it so we can use Core from JS
|
|
93
116
|
type BoxedCore = JsBox<CoreHandle>;
|
|
94
|
-
|
|
95
117
|
impl Finalize for CoreHandle {}
|
|
96
118
|
|
|
97
119
|
/// Worker struct, hold a reference for the channel sender responsible for sending requests from
|
|
98
120
|
/// JS to a bridge thread which forwards them to core
|
|
99
|
-
|
|
121
|
+
struct Worker {
|
|
100
122
|
core: CoreHandle,
|
|
101
123
|
queue: String,
|
|
102
124
|
}
|
|
103
|
-
|
|
104
125
|
/// Box it so we can use Worker from JS
|
|
105
126
|
type BoxedWorker = JsBox<Worker>;
|
|
106
|
-
|
|
107
127
|
impl Finalize for Worker {}
|
|
108
128
|
|
|
129
|
+
enum CoreType {
|
|
130
|
+
Real(CoreSDK),
|
|
131
|
+
Replay(ReplayCoreImpl),
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
impl Deref for CoreType {
|
|
135
|
+
type Target = dyn Core;
|
|
136
|
+
|
|
137
|
+
fn deref(&self) -> &Self::Target {
|
|
138
|
+
match self {
|
|
139
|
+
CoreType::Real(ref r) => r,
|
|
140
|
+
CoreType::Replay(ref r) => r,
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/// Lazy-inits or returns a global tokio runtime that we use for interactions with Core(s)
|
|
146
|
+
fn tokio_runtime() -> &'static Runtime {
|
|
147
|
+
static INSTANCE: OnceCell<Runtime> = OnceCell::new();
|
|
148
|
+
INSTANCE.get_or_init(|| {
|
|
149
|
+
tokio::runtime::Builder::new_multi_thread()
|
|
150
|
+
.enable_all()
|
|
151
|
+
.thread_name("core")
|
|
152
|
+
.build()
|
|
153
|
+
.expect("Tokio runtime must construct properly")
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
|
|
109
157
|
/// Send a result to JS via callback using an [EventQueue]
|
|
110
158
|
fn send_result<F, T>(queue: Arc<EventQueue>, callback: Root<JsFunction>, res_fn: F)
|
|
111
159
|
where
|
|
@@ -196,222 +244,243 @@ async fn void_future_to_js<E, F, ER, EF>(
|
|
|
196
244
|
/// Bridges requests from JS to core and sends responses back to JS using a neon::EventQueue.
|
|
197
245
|
/// Blocks current thread until a [BreakPoller] request is received in channel.
|
|
198
246
|
fn start_bridge_loop(
|
|
199
|
-
|
|
247
|
+
core_init_fut: impl Future<Output = Result<CoreType, CoreInitError>>,
|
|
200
248
|
event_queue: Arc<EventQueue>,
|
|
201
249
|
callback: Root<JsFunction>,
|
|
202
250
|
) {
|
|
203
251
|
let (sender, mut receiver) = unbounded_channel::<Request>();
|
|
204
252
|
|
|
205
|
-
|
|
206
|
-
.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
253
|
+
tokio_runtime().block_on(async {
|
|
254
|
+
match core_init_fut.await {
|
|
255
|
+
Err(err) => {
|
|
256
|
+
send_error(event_queue.clone(), callback, |cx| match err {
|
|
257
|
+
CoreInitError::GatewayInitError(err) => TRANSPORT_ERROR.from_error(cx, err),
|
|
258
|
+
e @ CoreInitError::TelemetryInitError(_) => UNEXPECTED_ERROR.from_error(cx, e),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
Ok(result) => {
|
|
262
|
+
let core = Arc::new(result);
|
|
263
|
+
let core_handle = CoreHandle { sender };
|
|
264
|
+
// Clone once to send back to JS via event queue
|
|
265
|
+
let cloned_core_handle = core_handle.clone();
|
|
266
|
+
send_result(event_queue.clone(), callback, |cx| {
|
|
267
|
+
Ok(cx.boxed(cloned_core_handle))
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
loop {
|
|
271
|
+
let request_option = receiver.recv().await;
|
|
272
|
+
let request = match request_option {
|
|
273
|
+
None => break,
|
|
274
|
+
Some(request) => request,
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
let core = core.clone();
|
|
278
|
+
let event_queue = event_queue.clone();
|
|
279
|
+
|
|
280
|
+
match request {
|
|
281
|
+
Request::Shutdown { callback } => {
|
|
282
|
+
void_future_to_js(
|
|
283
|
+
event_queue,
|
|
284
|
+
callback,
|
|
285
|
+
async move {
|
|
286
|
+
core.shutdown().await;
|
|
287
|
+
// Wrap the empty result in a valid Result object
|
|
288
|
+
let result: Result<(), String> = Ok(());
|
|
289
|
+
result
|
|
290
|
+
},
|
|
291
|
+
|cx, err| UNEXPECTED_ERROR.from_error(cx, err),
|
|
292
|
+
)
|
|
293
|
+
.await;
|
|
294
|
+
break;
|
|
215
295
|
}
|
|
216
|
-
|
|
217
|
-
|
|
296
|
+
Request::PollLogs { callback } => {
|
|
297
|
+
let logs = core.fetch_buffered_logs();
|
|
298
|
+
send_result(event_queue.clone(), callback, |cx| {
|
|
299
|
+
let logarr = cx.empty_array();
|
|
300
|
+
for (i, cl) in logs.into_iter().enumerate() {
|
|
301
|
+
// Not much to do here except for panic when there's an
|
|
302
|
+
// error here.
|
|
303
|
+
let logobj = cx.empty_object();
|
|
304
|
+
let level = cx.string(cl.level.to_string());
|
|
305
|
+
logobj.set(cx, "level", level).unwrap();
|
|
306
|
+
let ts = system_time_to_js(cx, cl.timestamp).unwrap();
|
|
307
|
+
logobj.set(cx, "timestamp", ts).unwrap();
|
|
308
|
+
let msg = cx.string(cl.message);
|
|
309
|
+
logobj.set(cx, "message", msg).unwrap();
|
|
310
|
+
logarr.set(cx, i as u32, logobj).unwrap();
|
|
311
|
+
}
|
|
312
|
+
Ok(logarr)
|
|
313
|
+
});
|
|
218
314
|
}
|
|
219
|
-
|
|
220
|
-
|
|
315
|
+
Request::ShutdownWorker {
|
|
316
|
+
task_queue,
|
|
317
|
+
callback,
|
|
318
|
+
} => {
|
|
319
|
+
tokio::spawn(void_future_to_js(
|
|
320
|
+
event_queue,
|
|
321
|
+
callback,
|
|
322
|
+
async move {
|
|
323
|
+
core.shutdown_worker(&task_queue).await;
|
|
324
|
+
// Wrap the empty result in a valid Result object
|
|
325
|
+
let result: Result<(), String> = Ok(());
|
|
326
|
+
result
|
|
327
|
+
},
|
|
328
|
+
|cx, err| UNEXPECTED_ERROR.from_error(cx, err),
|
|
329
|
+
));
|
|
221
330
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
callback,
|
|
249
|
-
async move {
|
|
250
|
-
core.shutdown().await;
|
|
251
|
-
// Wrap the empty result in a valid Result object
|
|
252
|
-
let result: Result<(), String> = Ok(());
|
|
253
|
-
result
|
|
254
|
-
},
|
|
255
|
-
|cx, err| UNEXPECTED_ERROR.from_error(cx, err),
|
|
331
|
+
Request::RegisterWorker { config, callback } => {
|
|
332
|
+
let task_queue = config.task_queue.clone();
|
|
333
|
+
match core.register_worker(config) {
|
|
334
|
+
Ok(_) => {
|
|
335
|
+
let core_handle = core_handle.clone();
|
|
336
|
+
send_result(event_queue.clone(), callback, |cx| {
|
|
337
|
+
Ok(cx.boxed(Worker {
|
|
338
|
+
core: core_handle,
|
|
339
|
+
queue: task_queue,
|
|
340
|
+
}))
|
|
341
|
+
})
|
|
342
|
+
}
|
|
343
|
+
Err(err) => send_error(event_queue.clone(), callback, |cx| {
|
|
344
|
+
UNEXPECTED_ERROR.from_error(cx, err)
|
|
345
|
+
}),
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
Request::RegisterReplayWorker {
|
|
349
|
+
config,
|
|
350
|
+
history,
|
|
351
|
+
callback,
|
|
352
|
+
} => match *core {
|
|
353
|
+
CoreType::Real(_) => {
|
|
354
|
+
panic!(
|
|
355
|
+
"Attempted to use a real core instance to register a \
|
|
356
|
+
replay worker. This is a bug in the TS SDK."
|
|
256
357
|
)
|
|
257
|
-
.await;
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
260
|
-
Request::PollLogs { callback } => {
|
|
261
|
-
let logs = core.fetch_buffered_logs();
|
|
262
|
-
send_result(event_queue.clone(), callback, |cx| {
|
|
263
|
-
let logarr = cx.empty_array();
|
|
264
|
-
for (i, cl) in logs.into_iter().enumerate() {
|
|
265
|
-
// Not much to do here except for panic when there's an
|
|
266
|
-
// error here.
|
|
267
|
-
let logobj = cx.empty_object();
|
|
268
|
-
let level = cx.string(cl.level.to_string());
|
|
269
|
-
logobj.set(cx, "level", level).unwrap();
|
|
270
|
-
let ts = system_time_to_js(cx, cl.timestamp).unwrap();
|
|
271
|
-
logobj.set(cx, "timestamp", ts).unwrap();
|
|
272
|
-
let msg = cx.string(cl.message);
|
|
273
|
-
logobj.set(cx, "message", msg).unwrap();
|
|
274
|
-
logarr.set(cx, i as u32, logobj).unwrap();
|
|
275
|
-
}
|
|
276
|
-
Ok(logarr)
|
|
277
|
-
});
|
|
278
358
|
}
|
|
279
|
-
|
|
280
|
-
task_queue
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
callback,
|
|
286
|
-
async move {
|
|
287
|
-
core.shutdown_worker(&task_queue).await;
|
|
288
|
-
// Wrap the empty result in a valid Result object
|
|
289
|
-
let result: Result<(), String> = Ok(());
|
|
290
|
-
result
|
|
291
|
-
},
|
|
292
|
-
|cx, err| UNEXPECTED_ERROR.from_error(cx, err),
|
|
293
|
-
));
|
|
294
|
-
}
|
|
295
|
-
Request::RegisterWorker { config, callback } => {
|
|
296
|
-
let task_queue = config.clone().task_queue;
|
|
297
|
-
let core_handle = core_handle.clone();
|
|
298
|
-
tokio::spawn(async move {
|
|
299
|
-
match core.register_worker(config).await {
|
|
300
|
-
Ok(_) => send_result(event_queue.clone(), callback, |cx| {
|
|
359
|
+
CoreType::Replay(ref rc) => {
|
|
360
|
+
let task_queue = config.task_queue.clone();
|
|
361
|
+
match rc.make_replay_worker(config, &history) {
|
|
362
|
+
Ok(_) => {
|
|
363
|
+
let core_handle = core_handle.clone();
|
|
364
|
+
send_result(event_queue.clone(), callback, |cx| {
|
|
301
365
|
Ok(cx.boxed(Worker {
|
|
302
366
|
core: core_handle,
|
|
303
367
|
queue: task_queue,
|
|
304
368
|
}))
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
};
|
|
312
|
-
});
|
|
369
|
+
})
|
|
370
|
+
}
|
|
371
|
+
Err(err) => send_error(event_queue.clone(), callback, |cx| {
|
|
372
|
+
UNEXPECTED_ERROR.from_error(cx, err)
|
|
373
|
+
}),
|
|
374
|
+
};
|
|
313
375
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
376
|
+
},
|
|
377
|
+
Request::PollWorkflowActivation {
|
|
378
|
+
queue_name,
|
|
379
|
+
otel_span,
|
|
380
|
+
callback,
|
|
381
|
+
} => {
|
|
382
|
+
// dbg!(&queue_name);
|
|
383
|
+
tokio::spawn(async move {
|
|
384
|
+
handle_poll_workflow_activation_request(
|
|
320
385
|
queue_name,
|
|
321
386
|
otel_span,
|
|
322
|
-
core,
|
|
387
|
+
core.as_ref().deref(),
|
|
323
388
|
event_queue,
|
|
324
389
|
callback,
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
390
|
+
)
|
|
391
|
+
.await
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
Request::PollActivityTask {
|
|
395
|
+
queue_name,
|
|
396
|
+
otel_span,
|
|
397
|
+
callback,
|
|
398
|
+
} => {
|
|
399
|
+
tokio::spawn(async move {
|
|
400
|
+
handle_poll_activity_task_request(
|
|
333
401
|
queue_name,
|
|
334
402
|
otel_span,
|
|
335
|
-
core,
|
|
403
|
+
core.as_ref().deref(),
|
|
336
404
|
event_queue,
|
|
337
405
|
callback,
|
|
338
|
-
)
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
406
|
+
)
|
|
407
|
+
.await
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
Request::CompleteWorkflowActivation {
|
|
411
|
+
completion,
|
|
412
|
+
otel_span,
|
|
413
|
+
callback,
|
|
414
|
+
} => {
|
|
415
|
+
let otel_ctx =
|
|
416
|
+
opentelemetry::Context::new().with_remote_span_context(otel_span);
|
|
417
|
+
tokio::spawn(void_future_to_js(
|
|
418
|
+
event_queue,
|
|
343
419
|
callback,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
otel_span,
|
|
420
|
+
async move {
|
|
421
|
+
core.complete_workflow_activation(completion)
|
|
422
|
+
.with_context(otel_ctx)
|
|
423
|
+
.await
|
|
424
|
+
},
|
|
425
|
+
|cx, err| match err {
|
|
426
|
+
CompleteWfError::NoWorkerForQueue(queue_name) => {
|
|
427
|
+
let args = vec![cx.string(queue_name).upcast()];
|
|
428
|
+
NO_WORKER_ERROR.construct(cx, args)
|
|
429
|
+
}
|
|
430
|
+
CompleteWfError::TonicError(_) => {
|
|
431
|
+
TRANSPORT_ERROR.from_error(cx, err)
|
|
432
|
+
}
|
|
433
|
+
CompleteWfError::MalformedWorkflowCompletion {
|
|
434
|
+
reason, ..
|
|
435
|
+
} => Ok(JsError::type_error(cx, reason)?.upcast()),
|
|
436
|
+
},
|
|
437
|
+
));
|
|
438
|
+
}
|
|
439
|
+
Request::CompleteActivityTask {
|
|
440
|
+
completion,
|
|
441
|
+
otel_span,
|
|
442
|
+
callback,
|
|
443
|
+
} => {
|
|
444
|
+
let otel_ctx =
|
|
445
|
+
opentelemetry::Context::new().with_remote_span_context(otel_span);
|
|
446
|
+
tokio::spawn(void_future_to_js(
|
|
447
|
+
event_queue,
|
|
373
448
|
callback,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
},
|
|
398
|
-
));
|
|
399
|
-
}
|
|
400
|
-
Request::RecordActivityHeartbeat { heartbeat } => {
|
|
401
|
-
core.record_activity_heartbeat(heartbeat)
|
|
402
|
-
}
|
|
449
|
+
async move {
|
|
450
|
+
core.complete_activity_task(completion)
|
|
451
|
+
.with_context(otel_ctx)
|
|
452
|
+
.await
|
|
453
|
+
},
|
|
454
|
+
|cx, err| match err {
|
|
455
|
+
CompleteActivityError::MalformedActivityCompletion {
|
|
456
|
+
reason,
|
|
457
|
+
..
|
|
458
|
+
} => Ok(JsError::type_error(cx, reason)?.upcast()),
|
|
459
|
+
CompleteActivityError::TonicError(_) => {
|
|
460
|
+
TRANSPORT_ERROR.from_error(cx, err)
|
|
461
|
+
}
|
|
462
|
+
CompleteActivityError::NoWorkerForQueue(queue_name) => {
|
|
463
|
+
let args = vec![cx.string(queue_name).upcast()];
|
|
464
|
+
NO_WORKER_ERROR.construct(cx, args)
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
));
|
|
468
|
+
}
|
|
469
|
+
Request::RecordActivityHeartbeat { heartbeat } => {
|
|
470
|
+
core.record_activity_heartbeat(heartbeat)
|
|
403
471
|
}
|
|
404
472
|
}
|
|
405
473
|
}
|
|
406
474
|
}
|
|
407
|
-
}
|
|
475
|
+
}
|
|
476
|
+
})
|
|
408
477
|
}
|
|
409
478
|
|
|
410
479
|
/// Called within the poll loop thread, calls core and triggers JS callback with result
|
|
411
480
|
async fn handle_poll_workflow_activation_request(
|
|
412
481
|
queue_name: String,
|
|
413
482
|
span_context: SpanContext,
|
|
414
|
-
core:
|
|
483
|
+
core: &dyn Core,
|
|
415
484
|
event_queue: Arc<EventQueue>,
|
|
416
485
|
callback: Root<JsFunction>,
|
|
417
486
|
) {
|
|
@@ -462,7 +531,7 @@ async fn handle_poll_workflow_activation_request(
|
|
|
462
531
|
async fn handle_poll_activity_task_request(
|
|
463
532
|
queue_name: String,
|
|
464
533
|
span_context: SpanContext,
|
|
465
|
-
core:
|
|
534
|
+
core: &dyn Core,
|
|
466
535
|
event_queue: Arc<EventQueue>,
|
|
467
536
|
callback: Root<JsFunction>,
|
|
468
537
|
) {
|
|
@@ -517,21 +586,30 @@ fn core_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
|
517
586
|
|
|
518
587
|
let callback = cx.argument::<JsFunction>(1)?.root(&mut cx);
|
|
519
588
|
let queue = Arc::new(cx.queue());
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
)
|
|
530
|
-
});
|
|
589
|
+
let core_init_fut = async move {
|
|
590
|
+
let opts = CoreInitOptionsBuilder::default()
|
|
591
|
+
.gateway_opts(gateway_opts)
|
|
592
|
+
.telemetry_opts(telemetry_opts)
|
|
593
|
+
.build()
|
|
594
|
+
.expect("Core init options must be valid");
|
|
595
|
+
Ok(CoreType::Real(init(opts).await?))
|
|
596
|
+
};
|
|
597
|
+
std::thread::spawn(move || start_bridge_loop(core_init_fut, queue, callback));
|
|
531
598
|
|
|
532
599
|
Ok(cx.undefined())
|
|
533
600
|
}
|
|
534
601
|
|
|
602
|
+
/// Create a new "replay" instance of core, which can only be used for replaying static histories.
|
|
603
|
+
fn replay_core_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
604
|
+
let telem_options = cx.argument::<JsObject>(0)?;
|
|
605
|
+
let telem_options = telem_options.as_telemetry_options(&mut cx)?;
|
|
606
|
+
let callback = cx.argument::<JsFunction>(1)?.root(&mut cx);
|
|
607
|
+
let queue = Arc::new(cx.queue());
|
|
608
|
+
let core_init_fut = async { Ok(CoreType::Replay(init_core_replay(telem_options))) };
|
|
609
|
+
std::thread::spawn(move || start_bridge_loop(core_init_fut, queue, callback));
|
|
610
|
+
Ok(cx.undefined())
|
|
611
|
+
}
|
|
612
|
+
|
|
535
613
|
/// Create a new worker asynchronously.
|
|
536
614
|
/// Worker is registered on supplied core instance and returned to JS using supplied callback.
|
|
537
615
|
fn worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
@@ -552,6 +630,38 @@ fn worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
|
552
630
|
Ok(cx.undefined())
|
|
553
631
|
}
|
|
554
632
|
|
|
633
|
+
/// Create a new replay worker asynchronously.
|
|
634
|
+
/// Worker is registered on supplied core instance and returned to JS using supplied callback.
|
|
635
|
+
/// The provided core instance must be a replay core.
|
|
636
|
+
fn replay_worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
637
|
+
let core = cx.argument::<BoxedCore>(0)?;
|
|
638
|
+
let worker_options = cx.argument::<JsObject>(1)?;
|
|
639
|
+
let history_binary = cx.argument::<JsArrayBuffer>(2)?;
|
|
640
|
+
let callback = cx.argument::<JsFunction>(3)?;
|
|
641
|
+
|
|
642
|
+
let config = worker_options.as_worker_config(&mut cx)?;
|
|
643
|
+
|
|
644
|
+
match cx.borrow(&history_binary, |data| {
|
|
645
|
+
History::decode_length_delimited(data.as_slice::<u8>())
|
|
646
|
+
}) {
|
|
647
|
+
Ok(history) => {
|
|
648
|
+
let request = Request::RegisterReplayWorker {
|
|
649
|
+
config,
|
|
650
|
+
history,
|
|
651
|
+
callback: callback.root(&mut cx),
|
|
652
|
+
};
|
|
653
|
+
if let Err(err) = core.sender.send(request) {
|
|
654
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
Err(_) => callback_with_error(&mut cx, callback, |cx| {
|
|
658
|
+
JsError::type_error(cx, "Cannot decode History from buffer")
|
|
659
|
+
})?,
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
Ok(cx.undefined())
|
|
663
|
+
}
|
|
664
|
+
|
|
555
665
|
/// Shutdown the Core instance and break out of the thread loop
|
|
556
666
|
fn core_shutdown(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
557
667
|
let core = cx.argument::<BoxedCore>(0)?;
|
|
@@ -619,12 +729,12 @@ fn worker_complete_workflow_activation(mut cx: FunctionContext) -> JsResult<JsUn
|
|
|
619
729
|
let completion = cx.argument::<JsArrayBuffer>(2)?;
|
|
620
730
|
let callback = cx.argument::<JsFunction>(3)?;
|
|
621
731
|
let result = cx.borrow(&completion, |data| {
|
|
622
|
-
|
|
732
|
+
WorkflowActivationCompletion::decode_length_delimited(data.as_slice::<u8>())
|
|
623
733
|
});
|
|
624
734
|
match result {
|
|
625
735
|
Ok(completion) => {
|
|
626
736
|
// Add the task queue from our Worker
|
|
627
|
-
let completion =
|
|
737
|
+
let completion = WorkflowActivationCompletion {
|
|
628
738
|
task_queue: worker.queue.clone(),
|
|
629
739
|
..completion
|
|
630
740
|
};
|
|
@@ -634,7 +744,7 @@ fn worker_complete_workflow_activation(mut cx: FunctionContext) -> JsResult<JsUn
|
|
|
634
744
|
callback: callback.root(&mut cx),
|
|
635
745
|
};
|
|
636
746
|
if let Err(err) = worker.core.sender.send(request) {
|
|
637
|
-
|
|
747
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
638
748
|
};
|
|
639
749
|
}
|
|
640
750
|
Err(_) => callback_with_error(&mut cx, callback, |cx| {
|
|
@@ -732,7 +842,7 @@ where
|
|
|
732
842
|
let ts = cx.empty_array();
|
|
733
843
|
ts.set(cx, 0, ts_seconds).unwrap();
|
|
734
844
|
ts.set(cx, 1, only_nanos).unwrap();
|
|
735
|
-
|
|
845
|
+
Ok(ts)
|
|
736
846
|
}
|
|
737
847
|
|
|
738
848
|
/// Helper to get the current time in nanosecond resolution.
|
|
@@ -745,7 +855,9 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
|
|
745
855
|
cx.export_function("getTimeOfDay", get_time_of_day)?;
|
|
746
856
|
cx.export_function("registerErrors", errors::register_errors)?;
|
|
747
857
|
cx.export_function("newCore", core_new)?;
|
|
858
|
+
cx.export_function("newReplayCore", replay_core_new)?;
|
|
748
859
|
cx.export_function("newWorker", worker_new)?;
|
|
860
|
+
cx.export_function("newReplayWorker", replay_worker_new)?;
|
|
749
861
|
cx.export_function("workerShutdown", worker_shutdown)?;
|
|
750
862
|
cx.export_function("coreShutdown", core_shutdown)?;
|
|
751
863
|
cx.export_function("corePollLogs", core_poll_logs)?;
|