@temporalio/core-bridge 0.19.2 → 0.20.2
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 +90 -157
- package/Cargo.toml +1 -0
- package/index.d.ts +11 -27
- 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/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +1 -1
- package/sdk-core/.cargo/config.toml +1 -0
- package/sdk-core/CODEOWNERS +1 -1
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +119 -86
- package/sdk-core/bridge-ffi/src/lib.rs +311 -315
- package/sdk-core/bridge-ffi/src/wrappers.rs +108 -113
- package/sdk-core/client/Cargo.toml +13 -9
- package/sdk-core/client/LICENSE.txt +23 -0
- package/sdk-core/client/src/lib.rs +286 -174
- package/sdk-core/client/src/metrics.rs +86 -12
- package/sdk-core/client/src/raw.rs +566 -0
- package/sdk-core/client/src/retry.rs +137 -99
- package/sdk-core/core/Cargo.toml +15 -10
- package/sdk-core/core/LICENSE.txt +23 -0
- package/sdk-core/core/benches/workflow_replay.rs +79 -0
- package/sdk-core/core/src/abstractions.rs +38 -0
- package/sdk-core/core/src/core_tests/activity_tasks.rs +108 -182
- package/sdk-core/core/src/core_tests/child_workflows.rs +16 -11
- package/sdk-core/core/src/core_tests/determinism.rs +24 -12
- package/sdk-core/core/src/core_tests/local_activities.rs +53 -27
- package/sdk-core/core/src/core_tests/mod.rs +30 -43
- package/sdk-core/core/src/core_tests/queries.rs +82 -81
- package/sdk-core/core/src/core_tests/workers.rs +111 -296
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +4 -4
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +257 -242
- package/sdk-core/core/src/lib.rs +73 -318
- package/sdk-core/core/src/pollers/mod.rs +4 -6
- package/sdk-core/core/src/pollers/poll_buffer.rs +20 -14
- package/sdk-core/core/src/protosext/mod.rs +7 -10
- package/sdk-core/core/src/replay/mod.rs +11 -150
- package/sdk-core/core/src/telemetry/metrics.rs +35 -2
- package/sdk-core/core/src/telemetry/mod.rs +49 -16
- package/sdk-core/core/src/telemetry/prometheus_server.rs +14 -35
- package/sdk-core/core/src/test_help/mod.rs +104 -170
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +57 -34
- package/sdk-core/core/src/worker/activities/local_activities.rs +95 -23
- package/sdk-core/core/src/worker/activities.rs +23 -16
- package/sdk-core/core/src/worker/client/mocks.rs +86 -0
- package/sdk-core/core/src/worker/client.rs +209 -0
- package/sdk-core/core/src/worker/mod.rs +207 -108
- package/sdk-core/core/src/workflow/driven_workflow.rs +21 -6
- package/sdk-core/core/src/workflow/history_update.rs +107 -24
- package/sdk-core/core/src/workflow/machines/activity_state_machine.rs +2 -3
- package/sdk-core/core/src/workflow/machines/child_workflow_state_machine.rs +2 -3
- package/sdk-core/core/src/workflow/machines/mod.rs +20 -17
- package/sdk-core/core/src/workflow/machines/signal_external_state_machine.rs +56 -19
- package/sdk-core/core/src/workflow/machines/transition_coverage.rs +5 -0
- package/sdk-core/core/src/workflow/machines/upsert_search_attributes_state_machine.rs +230 -22
- package/sdk-core/core/src/workflow/machines/workflow_machines.rs +81 -115
- package/sdk-core/core/src/workflow/machines/workflow_task_state_machine.rs +4 -4
- package/sdk-core/core/src/workflow/mod.rs +13 -1
- package/sdk-core/core/src/workflow/workflow_tasks/concurrency_manager.rs +70 -11
- package/sdk-core/core/src/workflow/workflow_tasks/mod.rs +65 -41
- package/sdk-core/core-api/Cargo.toml +9 -1
- package/sdk-core/core-api/LICENSE.txt +23 -0
- package/sdk-core/core-api/src/errors.rs +7 -38
- package/sdk-core/core-api/src/lib.rs +44 -52
- package/sdk-core/core-api/src/worker.rs +10 -2
- package/sdk-core/etc/deps.svg +127 -96
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +11 -7
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +10 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +6 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +2 -1
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +12 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +25 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +4 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +19 -35
- package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +2 -6
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +53 -11
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +14 -7
- package/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +3 -5
- package/sdk-core/sdk/Cargo.toml +16 -2
- package/sdk-core/sdk/LICENSE.txt +23 -0
- package/sdk-core/sdk/src/interceptors.rs +11 -0
- package/sdk-core/sdk/src/lib.rs +139 -151
- package/sdk-core/sdk/src/workflow_context/options.rs +86 -1
- package/sdk-core/sdk/src/workflow_context.rs +36 -17
- package/sdk-core/sdk/src/workflow_future.rs +19 -25
- package/sdk-core/sdk-core-protos/Cargo.toml +1 -1
- package/sdk-core/sdk-core-protos/build.rs +1 -0
- package/sdk-core/sdk-core-protos/src/history_info.rs +17 -4
- package/sdk-core/sdk-core-protos/src/lib.rs +251 -47
- package/sdk-core/test-utils/Cargo.toml +3 -1
- package/sdk-core/test-utils/src/canned_histories.rs +27 -0
- package/sdk-core/test-utils/src/histfetch.rs +3 -3
- package/sdk-core/test-utils/src/lib.rs +223 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +27 -4
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +93 -14
- package/sdk-core/tests/integ_tests/polling_tests.rs +18 -12
- package/sdk-core/tests/integ_tests/queries_tests.rs +50 -53
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +117 -103
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +8 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +10 -5
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +7 -1
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +32 -9
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +7 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +76 -15
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +19 -3
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +39 -42
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +84 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +30 -8
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +21 -6
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +26 -16
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +66 -0
- package/sdk-core/tests/integ_tests/workflow_tests.rs +78 -74
- package/sdk-core/tests/load_tests.rs +9 -6
- package/sdk-core/tests/main.rs +43 -10
- package/src/conversions.rs +7 -12
- package/src/lib.rs +322 -357
- package/sdk-core/client/src/mocks.rs +0 -167
- package/sdk-core/core/src/worker/dispatcher.rs +0 -171
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +0 -61
package/src/lib.rs
CHANGED
|
@@ -10,18 +10,18 @@ use prost::Message;
|
|
|
10
10
|
use std::{
|
|
11
11
|
fmt::Display,
|
|
12
12
|
future::Future,
|
|
13
|
-
ops::Deref,
|
|
14
13
|
sync::Arc,
|
|
15
14
|
time::{Duration, SystemTime, UNIX_EPOCH},
|
|
16
15
|
};
|
|
16
|
+
use temporal_client::{
|
|
17
|
+
AnyClient, ClientInitError, ConfiguredClient, WorkflowServiceClientWithMetrics,
|
|
18
|
+
};
|
|
17
19
|
use temporal_sdk_core::{
|
|
18
20
|
api::{
|
|
19
|
-
errors::{
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
Core,
|
|
21
|
+
errors::{CompleteActivityError, CompleteWfError, PollActivityError, PollWfError},
|
|
22
|
+
Worker as CoreWorker,
|
|
23
23
|
},
|
|
24
|
-
|
|
24
|
+
fetch_global_buffered_logs, init_replay_worker, init_worker,
|
|
25
25
|
protos::{
|
|
26
26
|
coresdk::{
|
|
27
27
|
workflow_completion::WorkflowActivationCompletion, ActivityHeartbeat,
|
|
@@ -29,39 +29,49 @@ use temporal_sdk_core::{
|
|
|
29
29
|
},
|
|
30
30
|
temporal::api::history::v1::History,
|
|
31
31
|
},
|
|
32
|
-
|
|
33
|
-
CoreInitOptionsBuilder, CoreSDK, WorkerConfig,
|
|
32
|
+
telemetry_init, ClientOptions, RetryClient, WorkerConfig,
|
|
34
33
|
};
|
|
35
34
|
use tokio::{
|
|
36
35
|
runtime::Runtime,
|
|
37
|
-
sync::mpsc::{unbounded_channel, UnboundedSender},
|
|
36
|
+
sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
|
38
37
|
};
|
|
39
38
|
|
|
39
|
+
type RawClient = RetryClient<ConfiguredClient<WorkflowServiceClientWithMetrics>>;
|
|
40
|
+
|
|
40
41
|
/// A request from JS to bridge to core
|
|
41
|
-
#[derive(Debug)]
|
|
42
42
|
enum Request {
|
|
43
|
-
/// A request to shutdown
|
|
44
|
-
/// Breaks from the thread loop.
|
|
43
|
+
/// A request to shutdown the runtime, breaks from the thread loop.
|
|
45
44
|
Shutdown {
|
|
46
45
|
/// Used to send the result back into JS
|
|
47
46
|
callback: Root<JsFunction>,
|
|
48
47
|
},
|
|
48
|
+
/// A request to create a client in a runtime
|
|
49
|
+
CreateClient {
|
|
50
|
+
runtime: Arc<RuntimeHandle>,
|
|
51
|
+
options: ClientOptions,
|
|
52
|
+
/// Used to send the result back into JS
|
|
53
|
+
callback: Root<JsFunction>,
|
|
54
|
+
},
|
|
49
55
|
/// A request to shutdown a worker, the worker instance will remain active to
|
|
50
56
|
/// allow draining of pending tasks
|
|
51
57
|
ShutdownWorker {
|
|
52
|
-
|
|
58
|
+
worker: Arc<dyn CoreWorker>,
|
|
53
59
|
/// Used to send the result back into JS
|
|
54
60
|
callback: Root<JsFunction>,
|
|
55
61
|
},
|
|
56
|
-
/// A request to
|
|
57
|
-
|
|
62
|
+
/// A request to create a new Worker using a connected client
|
|
63
|
+
InitWorker {
|
|
64
|
+
runtime: Arc<RuntimeHandle>,
|
|
58
65
|
/// Worker configuration e.g. limits and task queue
|
|
59
66
|
config: WorkerConfig,
|
|
67
|
+
/// A client created with a [CreateClient] request
|
|
68
|
+
client: Arc<RawClient>,
|
|
60
69
|
/// Used to send the result back into JS
|
|
61
70
|
callback: Root<JsFunction>,
|
|
62
71
|
},
|
|
63
|
-
/// A request to register a replay worker
|
|
64
|
-
|
|
72
|
+
/// A request to register a replay worker
|
|
73
|
+
InitReplayWorker {
|
|
74
|
+
runtime: Arc<RuntimeHandle>,
|
|
65
75
|
/// Worker configuration. Must have unique task queue name.
|
|
66
76
|
config: WorkerConfig,
|
|
67
77
|
/// The history this worker should replay
|
|
@@ -71,14 +81,14 @@ enum Request {
|
|
|
71
81
|
},
|
|
72
82
|
/// A request to poll for workflow activations
|
|
73
83
|
PollWorkflowActivation {
|
|
74
|
-
|
|
75
|
-
queue_name: String,
|
|
84
|
+
worker: Arc<dyn CoreWorker>,
|
|
76
85
|
otel_span: SpanContext,
|
|
77
86
|
/// Used to send the result back into JS
|
|
78
87
|
callback: Root<JsFunction>,
|
|
79
88
|
},
|
|
80
89
|
/// A request to complete a single workflow activation
|
|
81
90
|
CompleteWorkflowActivation {
|
|
91
|
+
worker: Arc<dyn CoreWorker>,
|
|
82
92
|
completion: WorkflowActivationCompletion,
|
|
83
93
|
otel_span: SpanContext,
|
|
84
94
|
/// Used to send the result back into JS
|
|
@@ -86,21 +96,24 @@ enum Request {
|
|
|
86
96
|
},
|
|
87
97
|
/// A request to poll for activity tasks
|
|
88
98
|
PollActivityTask {
|
|
89
|
-
|
|
90
|
-
queue_name: String,
|
|
99
|
+
worker: Arc<dyn CoreWorker>,
|
|
91
100
|
otel_span: SpanContext,
|
|
92
101
|
/// Used to report completion or error back into JS
|
|
93
102
|
callback: Root<JsFunction>,
|
|
94
103
|
},
|
|
95
104
|
/// A request to complete a single activity task
|
|
96
105
|
CompleteActivityTask {
|
|
106
|
+
worker: Arc<dyn CoreWorker>,
|
|
97
107
|
completion: ActivityTaskCompletion,
|
|
98
108
|
otel_span: SpanContext,
|
|
99
109
|
/// Used to send the result back into JS
|
|
100
110
|
callback: Root<JsFunction>,
|
|
101
111
|
},
|
|
102
112
|
/// A request to send a heartbeat from a running activity
|
|
103
|
-
RecordActivityHeartbeat {
|
|
113
|
+
RecordActivityHeartbeat {
|
|
114
|
+
worker: Arc<dyn CoreWorker>,
|
|
115
|
+
heartbeat: ActivityHeartbeat,
|
|
116
|
+
},
|
|
104
117
|
/// A request to drain logs from core so they can be emitted in node
|
|
105
118
|
PollLogs {
|
|
106
119
|
/// Logs are sent to this function
|
|
@@ -108,40 +121,34 @@ enum Request {
|
|
|
108
121
|
},
|
|
109
122
|
}
|
|
110
123
|
|
|
111
|
-
|
|
112
|
-
struct CoreHandle {
|
|
124
|
+
struct RuntimeHandle {
|
|
113
125
|
sender: UnboundedSender<Request>,
|
|
114
126
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
127
|
+
|
|
128
|
+
/// Box it so we can use the runtime from JS
|
|
129
|
+
type BoxedRuntime = JsBox<Arc<RuntimeHandle>>;
|
|
130
|
+
impl Finalize for RuntimeHandle {}
|
|
131
|
+
|
|
132
|
+
#[derive(Clone)]
|
|
133
|
+
struct Client {
|
|
134
|
+
runtime: Arc<RuntimeHandle>,
|
|
135
|
+
core_client: Arc<RawClient>,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
type BoxedClient = JsBox<Client>;
|
|
139
|
+
impl Finalize for Client {}
|
|
118
140
|
|
|
119
141
|
/// Worker struct, hold a reference for the channel sender responsible for sending requests from
|
|
120
142
|
/// JS to a bridge thread which forwards them to core
|
|
121
143
|
struct Worker {
|
|
122
|
-
|
|
123
|
-
|
|
144
|
+
runtime: Arc<RuntimeHandle>,
|
|
145
|
+
core_worker: Arc<dyn CoreWorker>,
|
|
124
146
|
}
|
|
147
|
+
|
|
125
148
|
/// Box it so we can use Worker from JS
|
|
126
149
|
type BoxedWorker = JsBox<Worker>;
|
|
127
150
|
impl Finalize for Worker {}
|
|
128
151
|
|
|
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
152
|
/// Lazy-inits or returns a global tokio runtime that we use for interactions with Core(s)
|
|
146
153
|
fn tokio_runtime() -> &'static Runtime {
|
|
147
154
|
static INSTANCE: OnceCell<Runtime> = OnceCell::new();
|
|
@@ -183,7 +190,7 @@ where
|
|
|
183
190
|
});
|
|
184
191
|
}
|
|
185
192
|
|
|
186
|
-
/// Call
|
|
193
|
+
/// Call `callback` with given error
|
|
187
194
|
fn callback_with_error<'a, C, E, F>(
|
|
188
195
|
cx: &mut C,
|
|
189
196
|
callback: Handle<JsFunction>,
|
|
@@ -202,6 +209,7 @@ where
|
|
|
202
209
|
Ok(())
|
|
203
210
|
}
|
|
204
211
|
|
|
212
|
+
/// Call `callback` with an UnexpectedError created from `err`
|
|
205
213
|
fn callback_with_unexpected_error<'a, C, E>(
|
|
206
214
|
cx: &mut C,
|
|
207
215
|
callback: Handle<JsFunction>,
|
|
@@ -242,234 +250,213 @@ async fn void_future_to_js<E, F, ER, EF>(
|
|
|
242
250
|
|
|
243
251
|
/// Builds a tokio runtime and starts polling on [Request]s via an internal channel.
|
|
244
252
|
/// Bridges requests from JS to core and sends responses back to JS using a neon::EventQueue.
|
|
245
|
-
/// Blocks current thread until a [
|
|
246
|
-
fn start_bridge_loop(
|
|
247
|
-
core_init_fut: impl Future<Output = Result<CoreType, CoreInitError>>,
|
|
248
|
-
event_queue: Arc<EventQueue>,
|
|
249
|
-
callback: Root<JsFunction>,
|
|
250
|
-
) {
|
|
251
|
-
let (sender, mut receiver) = unbounded_channel::<Request>();
|
|
252
|
-
|
|
253
|
+
/// Blocks current thread until a [Shutdown] request is received in channel.
|
|
254
|
+
fn start_bridge_loop(event_queue: Arc<EventQueue>, receiver: &mut UnboundedReceiver<Request>) {
|
|
253
255
|
tokio_runtime().block_on(async {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
});
|
|
256
|
+
loop {
|
|
257
|
+
let request_option = receiver.recv().await;
|
|
258
|
+
let request = match request_option {
|
|
259
|
+
None => break,
|
|
260
|
+
Some(request) => request,
|
|
261
|
+
};
|
|
269
262
|
|
|
270
|
-
|
|
271
|
-
let request_option = receiver.recv().await;
|
|
272
|
-
let request = match request_option {
|
|
273
|
-
None => break,
|
|
274
|
-
Some(request) => request,
|
|
275
|
-
};
|
|
263
|
+
let event_queue = event_queue.clone();
|
|
276
264
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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();
|
|
265
|
+
match request {
|
|
266
|
+
Request::Shutdown { callback } => {
|
|
267
|
+
send_result(event_queue, callback, |cx| Ok(cx.undefined()));
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
Request::CreateClient {
|
|
271
|
+
runtime,
|
|
272
|
+
options,
|
|
273
|
+
callback,
|
|
274
|
+
} => {
|
|
275
|
+
// `metrics_meter` (second arg) can be None here since we don't use the
|
|
276
|
+
// returned client directly at the moment, when we repurpose the client to be
|
|
277
|
+
// used by a Worker, `init_worker` will attach the correct metrics meter for
|
|
278
|
+
// us.
|
|
279
|
+
match options.connect_no_namespace(None).await {
|
|
280
|
+
Err(err) => {
|
|
281
|
+
send_error(event_queue.clone(), callback, |cx| match err {
|
|
282
|
+
ClientInitError::SystemInfoCallError(e) => TRANSPORT_ERROR
|
|
283
|
+
.from_error(cx, format!("Failed to call GetSystemInfo: {}", e)),
|
|
284
|
+
ClientInitError::TonicTransportError(e) => {
|
|
285
|
+
TRANSPORT_ERROR.from_error(cx, e)
|
|
286
|
+
}
|
|
287
|
+
ClientInitError::InvalidUri(e) => {
|
|
288
|
+
Ok(JsError::type_error(cx, format!("{}", e))?.upcast())
|
|
311
289
|
}
|
|
312
|
-
Ok(logarr)
|
|
313
290
|
});
|
|
314
291
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
-
));
|
|
292
|
+
Ok(client) => {
|
|
293
|
+
send_result(event_queue.clone(), callback, |cx| {
|
|
294
|
+
Ok(cx.boxed(Client {
|
|
295
|
+
runtime,
|
|
296
|
+
core_client: Arc::new(client),
|
|
297
|
+
}))
|
|
298
|
+
});
|
|
330
299
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
Request::PollLogs { callback } => {
|
|
303
|
+
let logs = fetch_global_buffered_logs();
|
|
304
|
+
send_result(event_queue.clone(), callback, |cx| {
|
|
305
|
+
let logarr = cx.empty_array();
|
|
306
|
+
for (i, cl) in logs.into_iter().enumerate() {
|
|
307
|
+
// Not much to do here except for panic when there's an
|
|
308
|
+
// error here.
|
|
309
|
+
let logobj = cx.empty_object();
|
|
310
|
+
let level = cx.string(cl.level.to_string());
|
|
311
|
+
logobj.set(cx, "level", level).unwrap();
|
|
312
|
+
let ts = system_time_to_js(cx, cl.timestamp).unwrap();
|
|
313
|
+
logobj.set(cx, "timestamp", ts).unwrap();
|
|
314
|
+
let msg = cx.string(cl.message);
|
|
315
|
+
logobj.set(cx, "message", msg).unwrap();
|
|
316
|
+
logarr.set(cx, i as u32, logobj).unwrap();
|
|
347
317
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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| {
|
|
365
|
-
Ok(cx.boxed(Worker {
|
|
366
|
-
core: core_handle,
|
|
367
|
-
queue: task_queue,
|
|
368
|
-
}))
|
|
369
|
-
})
|
|
370
|
-
}
|
|
371
|
-
Err(err) => send_error(event_queue.clone(), callback, |cx| {
|
|
372
|
-
UNEXPECTED_ERROR.from_error(cx, err)
|
|
373
|
-
}),
|
|
374
|
-
};
|
|
375
|
-
}
|
|
318
|
+
Ok(logarr)
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
Request::ShutdownWorker { worker, callback } => {
|
|
322
|
+
tokio::spawn(void_future_to_js(
|
|
323
|
+
event_queue,
|
|
324
|
+
callback,
|
|
325
|
+
async move {
|
|
326
|
+
worker.shutdown().await;
|
|
327
|
+
// Wrap the empty result in a valid Result object
|
|
328
|
+
let result: Result<(), String> = Ok(());
|
|
329
|
+
result
|
|
376
330
|
},
|
|
377
|
-
|
|
378
|
-
|
|
331
|
+
|cx, err| UNEXPECTED_ERROR.from_error(cx, err),
|
|
332
|
+
));
|
|
333
|
+
}
|
|
334
|
+
Request::InitWorker {
|
|
335
|
+
runtime,
|
|
336
|
+
config,
|
|
337
|
+
client,
|
|
338
|
+
callback,
|
|
339
|
+
} => {
|
|
340
|
+
let client = (*client).clone();
|
|
341
|
+
let worker =
|
|
342
|
+
init_worker(config, AnyClient::LowLevel(Box::new(client.into_inner())));
|
|
343
|
+
send_result(event_queue.clone(), callback, |cx| {
|
|
344
|
+
Ok(cx.boxed(Worker {
|
|
345
|
+
core_worker: Arc::new(worker),
|
|
346
|
+
runtime,
|
|
347
|
+
}))
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
Request::InitReplayWorker {
|
|
351
|
+
runtime,
|
|
352
|
+
config,
|
|
353
|
+
history,
|
|
354
|
+
callback,
|
|
355
|
+
} => {
|
|
356
|
+
match init_replay_worker(config, &history) {
|
|
357
|
+
Ok(worker) => send_result(event_queue.clone(), callback, |cx| {
|
|
358
|
+
Ok(cx.boxed(Worker {
|
|
359
|
+
core_worker: Arc::new(worker),
|
|
360
|
+
runtime,
|
|
361
|
+
}))
|
|
362
|
+
}),
|
|
363
|
+
Err(err) => send_error(event_queue.clone(), callback, |cx| {
|
|
364
|
+
UNEXPECTED_ERROR.from_error(cx, err)
|
|
365
|
+
}),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
Request::PollWorkflowActivation {
|
|
369
|
+
worker,
|
|
370
|
+
otel_span,
|
|
371
|
+
callback,
|
|
372
|
+
} => {
|
|
373
|
+
tokio::spawn(async move {
|
|
374
|
+
handle_poll_workflow_activation_request(
|
|
375
|
+
&*worker,
|
|
379
376
|
otel_span,
|
|
377
|
+
event_queue,
|
|
380
378
|
callback,
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
Request::PollActivityTask {
|
|
395
|
-
queue_name,
|
|
379
|
+
)
|
|
380
|
+
.await
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
Request::PollActivityTask {
|
|
384
|
+
worker,
|
|
385
|
+
otel_span,
|
|
386
|
+
callback,
|
|
387
|
+
} => {
|
|
388
|
+
tokio::spawn(async move {
|
|
389
|
+
handle_poll_activity_task_request(
|
|
390
|
+
&*worker,
|
|
396
391
|
otel_span,
|
|
392
|
+
event_queue,
|
|
397
393
|
callback,
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
394
|
+
)
|
|
395
|
+
.await
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
Request::CompleteWorkflowActivation {
|
|
399
|
+
worker,
|
|
400
|
+
completion,
|
|
401
|
+
otel_span,
|
|
402
|
+
callback,
|
|
403
|
+
} => {
|
|
404
|
+
let otel_ctx =
|
|
405
|
+
opentelemetry::Context::new().with_remote_span_context(otel_span);
|
|
406
|
+
tokio::spawn(void_future_to_js(
|
|
407
|
+
event_queue,
|
|
408
|
+
callback,
|
|
409
|
+
async move {
|
|
410
|
+
worker
|
|
411
|
+
.complete_workflow_activation(completion)
|
|
412
|
+
.with_context(otel_ctx)
|
|
407
413
|
.await
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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)
|
|
471
|
-
}
|
|
472
|
-
}
|
|
414
|
+
},
|
|
415
|
+
|cx, err| match err {
|
|
416
|
+
CompleteWfError::NoWorkerForQueue(queue_name) => {
|
|
417
|
+
let args = vec![cx.string(queue_name).upcast()];
|
|
418
|
+
NO_WORKER_ERROR.construct(cx, args)
|
|
419
|
+
}
|
|
420
|
+
CompleteWfError::TonicError(_) => TRANSPORT_ERROR.from_error(cx, err),
|
|
421
|
+
CompleteWfError::MalformedWorkflowCompletion { reason, .. } => {
|
|
422
|
+
Ok(JsError::type_error(cx, reason)?.upcast())
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
));
|
|
426
|
+
}
|
|
427
|
+
Request::CompleteActivityTask {
|
|
428
|
+
worker,
|
|
429
|
+
completion,
|
|
430
|
+
otel_span,
|
|
431
|
+
callback,
|
|
432
|
+
} => {
|
|
433
|
+
let otel_ctx =
|
|
434
|
+
opentelemetry::Context::new().with_remote_span_context(otel_span);
|
|
435
|
+
tokio::spawn(void_future_to_js(
|
|
436
|
+
event_queue,
|
|
437
|
+
callback,
|
|
438
|
+
async move {
|
|
439
|
+
worker
|
|
440
|
+
.complete_activity_task(completion)
|
|
441
|
+
.with_context(otel_ctx)
|
|
442
|
+
.await
|
|
443
|
+
},
|
|
444
|
+
|cx, err| match err {
|
|
445
|
+
CompleteActivityError::MalformedActivityCompletion {
|
|
446
|
+
reason, ..
|
|
447
|
+
} => Ok(JsError::type_error(cx, reason)?.upcast()),
|
|
448
|
+
CompleteActivityError::TonicError(_) => {
|
|
449
|
+
TRANSPORT_ERROR.from_error(cx, err)
|
|
450
|
+
}
|
|
451
|
+
CompleteActivityError::NoWorkerForQueue(queue_name) => {
|
|
452
|
+
let args = vec![cx.string(queue_name).upcast()];
|
|
453
|
+
NO_WORKER_ERROR.construct(cx, args)
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
));
|
|
457
|
+
}
|
|
458
|
+
Request::RecordActivityHeartbeat { worker, heartbeat } => {
|
|
459
|
+
worker.record_activity_heartbeat(heartbeat)
|
|
473
460
|
}
|
|
474
461
|
}
|
|
475
462
|
}
|
|
@@ -478,15 +465,14 @@ fn start_bridge_loop(
|
|
|
478
465
|
|
|
479
466
|
/// Called within the poll loop thread, calls core and triggers JS callback with result
|
|
480
467
|
async fn handle_poll_workflow_activation_request(
|
|
481
|
-
|
|
468
|
+
worker: &dyn CoreWorker,
|
|
482
469
|
span_context: SpanContext,
|
|
483
|
-
core: &dyn Core,
|
|
484
470
|
event_queue: Arc<EventQueue>,
|
|
485
471
|
callback: Root<JsFunction>,
|
|
486
472
|
) {
|
|
487
473
|
let otel_ctx = opentelemetry::Context::new().with_remote_span_context(span_context);
|
|
488
|
-
match
|
|
489
|
-
.poll_workflow_activation(
|
|
474
|
+
match worker
|
|
475
|
+
.poll_workflow_activation()
|
|
490
476
|
.with_context(otel_ctx)
|
|
491
477
|
.await
|
|
492
478
|
{
|
|
@@ -507,12 +493,7 @@ async fn handle_poll_workflow_activation_request(
|
|
|
507
493
|
send_error(event_queue, callback, move |cx| match err {
|
|
508
494
|
PollWfError::ShutDown => SHUTDOWN_ERROR.from_error(cx, err),
|
|
509
495
|
PollWfError::AutocompleteError(CompleteWfError::NoWorkerForQueue(_)) => {
|
|
510
|
-
UNEXPECTED_ERROR
|
|
511
|
-
.from_error(cx, format!("No worker registered for queue {}", queue_name))
|
|
512
|
-
}
|
|
513
|
-
PollWfError::NoWorkerForQueue(queue_name) => {
|
|
514
|
-
let args = vec![cx.string(queue_name).upcast()];
|
|
515
|
-
NO_WORKER_ERROR.construct(cx, args)
|
|
496
|
+
UNEXPECTED_ERROR.from_error(cx, "TODO this error shouldn't exist")
|
|
516
497
|
}
|
|
517
498
|
PollWfError::TonicError(_)
|
|
518
499
|
| PollWfError::AutocompleteError(CompleteWfError::TonicError(_)) => {
|
|
@@ -529,18 +510,13 @@ async fn handle_poll_workflow_activation_request(
|
|
|
529
510
|
|
|
530
511
|
/// Called within the poll loop thread, calls core and triggers JS callback with result
|
|
531
512
|
async fn handle_poll_activity_task_request(
|
|
532
|
-
|
|
513
|
+
worker: &dyn CoreWorker,
|
|
533
514
|
span_context: SpanContext,
|
|
534
|
-
core: &dyn Core,
|
|
535
515
|
event_queue: Arc<EventQueue>,
|
|
536
516
|
callback: Root<JsFunction>,
|
|
537
517
|
) {
|
|
538
518
|
let otel_ctx = opentelemetry::Context::new().with_remote_span_context(span_context);
|
|
539
|
-
match
|
|
540
|
-
.poll_activity_task(queue_name.as_str())
|
|
541
|
-
.with_context(otel_ctx)
|
|
542
|
-
.await
|
|
543
|
-
{
|
|
519
|
+
match worker.poll_activity_task().with_context(otel_ctx).await {
|
|
544
520
|
Ok(task) => {
|
|
545
521
|
send_result(event_queue, callback, move |cx| {
|
|
546
522
|
let len = task.encoded_len();
|
|
@@ -557,10 +533,6 @@ async fn handle_poll_activity_task_request(
|
|
|
557
533
|
Err(err) => {
|
|
558
534
|
send_error(event_queue, callback, move |cx| match err {
|
|
559
535
|
PollActivityError::ShutDown => SHUTDOWN_ERROR.from_error(cx, err),
|
|
560
|
-
PollActivityError::NoWorkerForQueue(queue_name) => {
|
|
561
|
-
let args = vec![cx.string(queue_name).upcast()];
|
|
562
|
-
NO_WORKER_ERROR.construct(cx, args)
|
|
563
|
-
}
|
|
564
536
|
PollActivityError::TonicError(_) => TRANSPORT_ERROR.from_error(cx, err),
|
|
565
537
|
});
|
|
566
538
|
}
|
|
@@ -569,61 +541,63 @@ async fn handle_poll_activity_task_request(
|
|
|
569
541
|
|
|
570
542
|
// Below are functions exported to JS
|
|
571
543
|
|
|
572
|
-
///
|
|
544
|
+
/// Initialize Core global telemetry.
|
|
545
|
+
/// This should typically be called once on process startup.
|
|
546
|
+
fn init_telemetry(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
547
|
+
let telemetry_options = cx.argument::<JsObject>(0)?.as_telemetry_options(&mut cx)?;
|
|
548
|
+
telemetry_init(&telemetry_options).map_err(|err| {
|
|
549
|
+
cx.throw_type_error::<String, ()>(format!("{}", err))
|
|
550
|
+
.unwrap_err()
|
|
551
|
+
})?;
|
|
552
|
+
Ok(cx.undefined())
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/// Create the tokio runtime required to run Core.
|
|
573
556
|
/// Immediately spawns a poller thread that will block on [Request]s
|
|
574
|
-
|
|
575
|
-
fn core_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
576
|
-
let core_options = cx.argument::<JsObject>(0)?;
|
|
577
|
-
let server_options = core_options
|
|
578
|
-
.get(&mut cx, "serverOptions")?
|
|
579
|
-
.downcast_or_throw::<JsObject, _>(&mut cx)?;
|
|
580
|
-
let telem_options = core_options
|
|
581
|
-
.get(&mut cx, "telemetryOptions")?
|
|
582
|
-
.downcast_or_throw::<JsObject, _>(&mut cx)?;
|
|
583
|
-
|
|
584
|
-
let gateway_opts = server_options.as_server_gateway_options(&mut cx)?;
|
|
585
|
-
let telemetry_opts = telem_options.as_telemetry_options(&mut cx)?;
|
|
586
|
-
|
|
587
|
-
let callback = cx.argument::<JsFunction>(1)?.root(&mut cx);
|
|
557
|
+
fn runtime_new(mut cx: FunctionContext) -> JsResult<BoxedRuntime> {
|
|
588
558
|
let queue = Arc::new(cx.queue());
|
|
589
|
-
let
|
|
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));
|
|
559
|
+
let (sender, mut receiver) = unbounded_channel::<Request>();
|
|
598
560
|
|
|
599
|
-
|
|
561
|
+
std::thread::spawn(move || start_bridge_loop(queue, &mut receiver));
|
|
562
|
+
|
|
563
|
+
Ok(cx.boxed(Arc::new(RuntimeHandle { sender })))
|
|
600
564
|
}
|
|
601
565
|
|
|
602
|
-
/// Create a
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
let
|
|
606
|
-
let
|
|
607
|
-
let
|
|
608
|
-
|
|
609
|
-
|
|
566
|
+
/// Create a connected gRPC client which can be used to initialize workers.
|
|
567
|
+
/// Client will be returned in the supplied `callback`.
|
|
568
|
+
fn client_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
569
|
+
let runtime = cx.argument::<BoxedRuntime>(0)?;
|
|
570
|
+
let client_options = cx.argument::<JsObject>(1)?.as_client_options(&mut cx)?;
|
|
571
|
+
let callback = cx.argument::<JsFunction>(2)?;
|
|
572
|
+
|
|
573
|
+
let request = Request::CreateClient {
|
|
574
|
+
runtime: (**runtime).clone(),
|
|
575
|
+
options: client_options,
|
|
576
|
+
callback: callback.root(&mut cx),
|
|
577
|
+
};
|
|
578
|
+
if let Err(err) = runtime.sender.send(request) {
|
|
579
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
580
|
+
};
|
|
581
|
+
|
|
610
582
|
Ok(cx.undefined())
|
|
611
583
|
}
|
|
612
584
|
|
|
613
585
|
/// Create a new worker asynchronously.
|
|
614
|
-
/// Worker
|
|
586
|
+
/// Worker uses the provided connection and returned to JS using supplied `callback`.
|
|
615
587
|
fn worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
616
|
-
let
|
|
588
|
+
let client = cx.argument::<BoxedClient>(0)?;
|
|
617
589
|
let worker_options = cx.argument::<JsObject>(1)?;
|
|
618
590
|
let callback = cx.argument::<JsFunction>(2)?;
|
|
619
591
|
|
|
620
592
|
let config = worker_options.as_worker_config(&mut cx)?;
|
|
621
593
|
|
|
622
|
-
let request = Request::
|
|
594
|
+
let request = Request::InitWorker {
|
|
595
|
+
client: client.core_client.clone(),
|
|
596
|
+
runtime: client.runtime.clone(),
|
|
623
597
|
config,
|
|
624
598
|
callback: callback.root(&mut cx),
|
|
625
599
|
};
|
|
626
|
-
if let Err(err) =
|
|
600
|
+
if let Err(err) = client.runtime.sender.send(request) {
|
|
627
601
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
628
602
|
};
|
|
629
603
|
|
|
@@ -631,10 +605,9 @@ fn worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
|
631
605
|
}
|
|
632
606
|
|
|
633
607
|
/// Create a new replay worker asynchronously.
|
|
634
|
-
/// Worker is
|
|
635
|
-
/// The provided core instance must be a replay core.
|
|
608
|
+
/// Worker is returned to JS using supplied callback.
|
|
636
609
|
fn replay_worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
637
|
-
let
|
|
610
|
+
let runtime = cx.argument::<BoxedRuntime>(0)?;
|
|
638
611
|
let worker_options = cx.argument::<JsObject>(1)?;
|
|
639
612
|
let history_binary = cx.argument::<JsArrayBuffer>(2)?;
|
|
640
613
|
let callback = cx.argument::<JsFunction>(3)?;
|
|
@@ -645,12 +618,13 @@ fn replay_worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
|
645
618
|
History::decode_length_delimited(data.as_slice::<u8>())
|
|
646
619
|
}) {
|
|
647
620
|
Ok(history) => {
|
|
648
|
-
let request = Request::
|
|
621
|
+
let request = Request::InitReplayWorker {
|
|
622
|
+
runtime: (**runtime).clone(),
|
|
649
623
|
config,
|
|
650
624
|
history,
|
|
651
625
|
callback: callback.root(&mut cx),
|
|
652
626
|
};
|
|
653
|
-
if let Err(err) =
|
|
627
|
+
if let Err(err) = runtime.sender.send(request) {
|
|
654
628
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
655
629
|
};
|
|
656
630
|
}
|
|
@@ -663,26 +637,26 @@ fn replay_worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
|
663
637
|
}
|
|
664
638
|
|
|
665
639
|
/// Shutdown the Core instance and break out of the thread loop
|
|
666
|
-
fn
|
|
667
|
-
let
|
|
640
|
+
fn runtime_shutdown(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
641
|
+
let runtime = cx.argument::<BoxedRuntime>(0)?;
|
|
668
642
|
let callback = cx.argument::<JsFunction>(1)?;
|
|
669
643
|
let request = Request::Shutdown {
|
|
670
644
|
callback: callback.root(&mut cx),
|
|
671
645
|
};
|
|
672
|
-
if let Err(err) =
|
|
646
|
+
if let Err(err) = runtime.sender.send(request) {
|
|
673
647
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
674
648
|
};
|
|
675
649
|
Ok(cx.undefined())
|
|
676
650
|
}
|
|
677
651
|
|
|
678
652
|
/// Request to drain forwarded logs from core
|
|
679
|
-
fn
|
|
680
|
-
let
|
|
653
|
+
fn poll_logs(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
654
|
+
let runtime = cx.argument::<BoxedRuntime>(0)?;
|
|
681
655
|
let callback = cx.argument::<JsFunction>(1)?;
|
|
682
656
|
let request = Request::PollLogs {
|
|
683
657
|
callback: callback.root(&mut cx),
|
|
684
658
|
};
|
|
685
|
-
if let Err(err) =
|
|
659
|
+
if let Err(err) = runtime.sender.send(request) {
|
|
686
660
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
687
661
|
}
|
|
688
662
|
Ok(cx.undefined())
|
|
@@ -695,11 +669,11 @@ fn worker_poll_workflow_activation(mut cx: FunctionContext) -> JsResult<JsUndefi
|
|
|
695
669
|
let otel_span = cx.argument::<JsObject>(1)?;
|
|
696
670
|
let callback = cx.argument::<JsFunction>(2)?;
|
|
697
671
|
let request = Request::PollWorkflowActivation {
|
|
698
|
-
|
|
672
|
+
worker: worker.core_worker.clone(),
|
|
699
673
|
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
700
674
|
callback: callback.root(&mut cx),
|
|
701
675
|
};
|
|
702
|
-
if let Err(err) = worker.
|
|
676
|
+
if let Err(err) = worker.runtime.sender.send(request) {
|
|
703
677
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
704
678
|
}
|
|
705
679
|
Ok(cx.undefined())
|
|
@@ -712,11 +686,11 @@ fn worker_poll_activity_task(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
|
712
686
|
let otel_span = cx.argument::<JsObject>(1)?;
|
|
713
687
|
let callback = cx.argument::<JsFunction>(2)?;
|
|
714
688
|
let request = Request::PollActivityTask {
|
|
715
|
-
|
|
689
|
+
worker: worker.core_worker.clone(),
|
|
716
690
|
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
717
691
|
callback: callback.root(&mut cx),
|
|
718
692
|
};
|
|
719
|
-
if let Err(err) = worker.
|
|
693
|
+
if let Err(err) = worker.runtime.sender.send(request) {
|
|
720
694
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
721
695
|
}
|
|
722
696
|
Ok(cx.undefined())
|
|
@@ -733,17 +707,13 @@ fn worker_complete_workflow_activation(mut cx: FunctionContext) -> JsResult<JsUn
|
|
|
733
707
|
});
|
|
734
708
|
match result {
|
|
735
709
|
Ok(completion) => {
|
|
736
|
-
// Add the task queue from our Worker
|
|
737
|
-
let completion = WorkflowActivationCompletion {
|
|
738
|
-
task_queue: worker.queue.clone(),
|
|
739
|
-
..completion
|
|
740
|
-
};
|
|
741
710
|
let request = Request::CompleteWorkflowActivation {
|
|
711
|
+
worker: worker.core_worker.clone(),
|
|
742
712
|
completion,
|
|
743
713
|
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
744
714
|
callback: callback.root(&mut cx),
|
|
745
715
|
};
|
|
746
|
-
if let Err(err) = worker.
|
|
716
|
+
if let Err(err) = worker.runtime.sender.send(request) {
|
|
747
717
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
748
718
|
};
|
|
749
719
|
}
|
|
@@ -765,17 +735,13 @@ fn worker_complete_activity_task(mut cx: FunctionContext) -> JsResult<JsUndefine
|
|
|
765
735
|
});
|
|
766
736
|
match result {
|
|
767
737
|
Ok(completion) => {
|
|
768
|
-
// Add the task queue from our Worker
|
|
769
|
-
let completion = ActivityTaskCompletion {
|
|
770
|
-
task_queue: worker.queue.clone(),
|
|
771
|
-
..completion
|
|
772
|
-
};
|
|
773
738
|
let request = Request::CompleteActivityTask {
|
|
739
|
+
worker: worker.core_worker.clone(),
|
|
774
740
|
completion,
|
|
775
741
|
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
776
742
|
callback: callback.root(&mut cx),
|
|
777
743
|
};
|
|
778
|
-
if let Err(err) = worker.
|
|
744
|
+
if let Err(err) = worker.runtime.sender.send(request) {
|
|
779
745
|
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
780
746
|
};
|
|
781
747
|
}
|
|
@@ -795,13 +761,11 @@ fn worker_record_activity_heartbeat(mut cx: FunctionContext) -> JsResult<JsUndef
|
|
|
795
761
|
});
|
|
796
762
|
match heartbeat {
|
|
797
763
|
Ok(heartbeat) => {
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
..heartbeat
|
|
764
|
+
let request = Request::RecordActivityHeartbeat {
|
|
765
|
+
worker: worker.core_worker.clone(),
|
|
766
|
+
heartbeat,
|
|
802
767
|
};
|
|
803
|
-
|
|
804
|
-
match worker.core.sender.send(request) {
|
|
768
|
+
match worker.runtime.sender.send(request) {
|
|
805
769
|
Err(err) => UNEXPECTED_ERROR
|
|
806
770
|
.from_error(&mut cx, err)
|
|
807
771
|
.and_then(|err| cx.throw(err)),
|
|
@@ -819,8 +783,8 @@ fn worker_record_activity_heartbeat(mut cx: FunctionContext) -> JsResult<JsUndef
|
|
|
819
783
|
fn worker_shutdown(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
820
784
|
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
821
785
|
let callback = cx.argument::<JsFunction>(1)?;
|
|
822
|
-
match worker.
|
|
823
|
-
|
|
786
|
+
match worker.runtime.sender.send(Request::ShutdownWorker {
|
|
787
|
+
worker: worker.core_worker.clone(),
|
|
824
788
|
callback: callback.root(&mut cx),
|
|
825
789
|
}) {
|
|
826
790
|
Err(err) => cx.throw_error(format!("{}", err)),
|
|
@@ -854,13 +818,14 @@ fn get_time_of_day(mut cx: FunctionContext) -> JsResult<JsArray> {
|
|
|
854
818
|
fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
|
855
819
|
cx.export_function("getTimeOfDay", get_time_of_day)?;
|
|
856
820
|
cx.export_function("registerErrors", errors::register_errors)?;
|
|
857
|
-
cx.export_function("
|
|
858
|
-
cx.export_function("
|
|
821
|
+
cx.export_function("initTelemetry", init_telemetry)?;
|
|
822
|
+
cx.export_function("newRuntime", runtime_new)?;
|
|
823
|
+
cx.export_function("newClient", client_new)?;
|
|
859
824
|
cx.export_function("newWorker", worker_new)?;
|
|
860
825
|
cx.export_function("newReplayWorker", replay_worker_new)?;
|
|
861
826
|
cx.export_function("workerShutdown", worker_shutdown)?;
|
|
862
|
-
cx.export_function("
|
|
863
|
-
cx.export_function("
|
|
827
|
+
cx.export_function("runtimeShutdown", runtime_shutdown)?;
|
|
828
|
+
cx.export_function("pollLogs", poll_logs)?;
|
|
864
829
|
cx.export_function(
|
|
865
830
|
"workerPollWorkflowActivation",
|
|
866
831
|
worker_poll_workflow_activation,
|