@temporalio/core-bridge 1.1.0 → 1.4.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 +765 -128
- package/Cargo.toml +2 -2
- package/common.js +7 -3
- package/index.d.ts +118 -5
- package/index.js +2 -6
- package/package.json +2 -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/scripts/build.js +4 -3
- package/sdk-core/.buildkite/docker/Dockerfile +2 -1
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/.cargo/config.toml +1 -1
- package/sdk-core/ARCHITECTURE.md +2 -2
- package/sdk-core/README.md +12 -0
- package/sdk-core/bridge-ffi/Cargo.toml +2 -2
- package/sdk-core/bridge-ffi/src/lib.rs +2 -2
- package/sdk-core/client/Cargo.toml +7 -5
- package/sdk-core/client/src/lib.rs +354 -226
- package/sdk-core/client/src/metrics.rs +13 -11
- package/sdk-core/client/src/raw.rs +352 -107
- package/sdk-core/client/src/retry.rs +188 -147
- package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
- package/sdk-core/core/Cargo.toml +28 -15
- package/sdk-core/core/src/core_tests/activity_tasks.rs +98 -33
- package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
- package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
- package/sdk-core/core/src/core_tests/workers.rs +3 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
- package/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
- package/sdk-core/core/src/lib.rs +62 -28
- package/sdk-core/core/src/pollers/mod.rs +2 -0
- package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
- package/sdk-core/core/src/replay/mod.rs +3 -3
- package/sdk-core/core/src/retry_logic.rs +10 -9
- package/sdk-core/core/src/telemetry/metrics.rs +48 -39
- package/sdk-core/core/src/telemetry/mod.rs +46 -12
- package/sdk-core/core/src/telemetry/prometheus_server.rs +17 -13
- package/sdk-core/core/src/test_help/mod.rs +18 -8
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
- package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
- package/sdk-core/core/src/worker/activities.rs +6 -12
- package/sdk-core/core/src/worker/client/mocks.rs +1 -0
- package/sdk-core/core/src/worker/client.rs +193 -64
- package/sdk-core/core/src/worker/mod.rs +14 -19
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
- package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
- package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
- package/sdk-core/core/src/worker/workflow/mod.rs +62 -58
- package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
- package/sdk-core/core-api/Cargo.toml +3 -3
- package/sdk-core/core-api/src/errors.rs +3 -11
- package/sdk-core/core-api/src/worker.rs +7 -0
- package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
- package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
- package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
- package/sdk-core/protos/api_upstream/Makefile +2 -2
- package/sdk-core/protos/api_upstream/buf.yaml +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
- package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
- package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
- package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
- package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
- package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
- package/sdk-core/sdk/Cargo.toml +2 -2
- package/sdk-core/sdk/src/lib.rs +2 -2
- package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
- package/sdk-core/sdk/src/workflow_context.rs +30 -6
- package/sdk-core/sdk/src/workflow_future.rs +4 -4
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
- package/sdk-core/sdk-core-protos/build.rs +9 -1
- package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
- package/sdk-core/test-utils/Cargo.toml +3 -3
- package/sdk-core/test-utils/src/canned_histories.rs +58 -0
- package/sdk-core/test-utils/src/lib.rs +35 -12
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
- package/sdk-core/tests/integ_tests/polling_tests.rs +2 -1
- package/sdk-core/tests/integ_tests/queries_tests.rs +5 -5
- package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +2 -6
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +8 -2
- package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
- package/sdk-core/tests/load_tests.rs +2 -1
- package/sdk-core/tests/main.rs +17 -0
- package/sdk-core/tests/runner.rs +93 -0
- package/src/conversions.rs +157 -94
- package/src/helpers.rs +190 -0
- package/src/lib.rs +10 -912
- package/src/runtime.rs +436 -0
- package/src/testing.rs +67 -0
- package/src/worker.rs +465 -0
package/src/worker.rs
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
use crate::conversions::ObjectHandleConversionsExt;
|
|
2
|
+
use crate::errors::*;
|
|
3
|
+
use crate::helpers::*;
|
|
4
|
+
use crate::runtime::*;
|
|
5
|
+
use futures::stream::StreamExt;
|
|
6
|
+
use neon::prelude::*;
|
|
7
|
+
use neon::types::buffer::TypedArray;
|
|
8
|
+
use opentelemetry::trace::{FutureExt, SpanContext, TraceContextExt};
|
|
9
|
+
use prost::Message;
|
|
10
|
+
use std::{cell::RefCell, sync::Arc};
|
|
11
|
+
use temporal_sdk_core::{
|
|
12
|
+
api::{
|
|
13
|
+
errors::{CompleteActivityError, CompleteWfError, PollActivityError, PollWfError},
|
|
14
|
+
Worker as CoreWorkerTrait,
|
|
15
|
+
},
|
|
16
|
+
protos::{
|
|
17
|
+
coresdk::{
|
|
18
|
+
workflow_completion::WorkflowActivationCompletion, ActivityHeartbeat,
|
|
19
|
+
ActivityTaskCompletion,
|
|
20
|
+
},
|
|
21
|
+
temporal::api::history::v1::History,
|
|
22
|
+
},
|
|
23
|
+
Worker as CoreWorker,
|
|
24
|
+
};
|
|
25
|
+
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
|
|
26
|
+
use tokio_stream::wrappers::UnboundedReceiverStream;
|
|
27
|
+
|
|
28
|
+
/// Worker struct, hold a reference for the channel sender responsible for sending requests from
|
|
29
|
+
/// JS to a bridge thread which forwards them to core
|
|
30
|
+
pub struct WorkerHandle {
|
|
31
|
+
pub(crate) sender: UnboundedSender<WorkerRequest>,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// Box it so we can use Worker from JS
|
|
35
|
+
pub type BoxedWorker = JsBox<RefCell<Option<WorkerHandle>>>;
|
|
36
|
+
impl Finalize for WorkerHandle {}
|
|
37
|
+
|
|
38
|
+
#[derive(Debug)]
|
|
39
|
+
pub enum WorkerRequest {
|
|
40
|
+
/// A request to shutdown a worker, the worker instance will remain active to
|
|
41
|
+
/// allow draining of pending tasks
|
|
42
|
+
InitiateShutdown {
|
|
43
|
+
/// Used to send the result back into JS
|
|
44
|
+
callback: Root<JsFunction>,
|
|
45
|
+
},
|
|
46
|
+
/// A request to poll for workflow activations
|
|
47
|
+
PollWorkflowActivation {
|
|
48
|
+
otel_span: SpanContext,
|
|
49
|
+
/// Used to send the result back into JS
|
|
50
|
+
callback: Root<JsFunction>,
|
|
51
|
+
},
|
|
52
|
+
/// A request to complete a single workflow activation
|
|
53
|
+
CompleteWorkflowActivation {
|
|
54
|
+
completion: WorkflowActivationCompletion,
|
|
55
|
+
otel_span: SpanContext,
|
|
56
|
+
/// Used to send the result back into JS
|
|
57
|
+
callback: Root<JsFunction>,
|
|
58
|
+
},
|
|
59
|
+
/// A request to poll for activity tasks
|
|
60
|
+
PollActivityTask {
|
|
61
|
+
otel_span: SpanContext,
|
|
62
|
+
/// Used to report completion or error back into JS
|
|
63
|
+
callback: Root<JsFunction>,
|
|
64
|
+
},
|
|
65
|
+
/// A request to complete a single activity task
|
|
66
|
+
CompleteActivityTask {
|
|
67
|
+
completion: ActivityTaskCompletion,
|
|
68
|
+
otel_span: SpanContext,
|
|
69
|
+
/// Used to send the result back into JS
|
|
70
|
+
callback: Root<JsFunction>,
|
|
71
|
+
},
|
|
72
|
+
/// A request to send a heartbeat from a running activity
|
|
73
|
+
RecordActivityHeartbeat { heartbeat: ActivityHeartbeat },
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Polls on [WorkerRequest]s via given channel.
|
|
77
|
+
/// Bridges requests from JS to core and sends responses back to JS using a neon::Channel.
|
|
78
|
+
/// Returns when the given channel is dropped.
|
|
79
|
+
pub async fn start_worker_loop(
|
|
80
|
+
worker: CoreWorker,
|
|
81
|
+
rx: UnboundedReceiver<WorkerRequest>,
|
|
82
|
+
channel: Arc<Channel>,
|
|
83
|
+
) {
|
|
84
|
+
UnboundedReceiverStream::new(rx)
|
|
85
|
+
.for_each_concurrent(None, |request| {
|
|
86
|
+
let worker = &worker;
|
|
87
|
+
let channel = channel.clone();
|
|
88
|
+
async move {
|
|
89
|
+
match request {
|
|
90
|
+
WorkerRequest::InitiateShutdown { callback } => {
|
|
91
|
+
worker.initiate_shutdown();
|
|
92
|
+
send_result(channel, callback, |cx| Ok(cx.undefined()));
|
|
93
|
+
}
|
|
94
|
+
WorkerRequest::PollWorkflowActivation {
|
|
95
|
+
otel_span,
|
|
96
|
+
callback,
|
|
97
|
+
} => {
|
|
98
|
+
handle_poll_workflow_activation_request(
|
|
99
|
+
&worker, otel_span, channel, callback,
|
|
100
|
+
)
|
|
101
|
+
.await
|
|
102
|
+
}
|
|
103
|
+
WorkerRequest::PollActivityTask {
|
|
104
|
+
otel_span,
|
|
105
|
+
callback,
|
|
106
|
+
} => {
|
|
107
|
+
handle_poll_activity_task_request(&worker, otel_span, channel, callback)
|
|
108
|
+
.await
|
|
109
|
+
}
|
|
110
|
+
WorkerRequest::CompleteWorkflowActivation {
|
|
111
|
+
completion,
|
|
112
|
+
otel_span,
|
|
113
|
+
callback,
|
|
114
|
+
} => {
|
|
115
|
+
let otel_ctx =
|
|
116
|
+
opentelemetry::Context::new().with_remote_span_context(otel_span);
|
|
117
|
+
void_future_to_js(
|
|
118
|
+
channel,
|
|
119
|
+
callback,
|
|
120
|
+
async move {
|
|
121
|
+
worker
|
|
122
|
+
.complete_workflow_activation(completion)
|
|
123
|
+
.with_context(otel_ctx)
|
|
124
|
+
.await
|
|
125
|
+
},
|
|
126
|
+
|cx, err| -> JsResult<JsObject> {
|
|
127
|
+
match err {
|
|
128
|
+
CompleteWfError::MalformedWorkflowCompletion {
|
|
129
|
+
reason, ..
|
|
130
|
+
} => Ok(JsError::type_error(cx, reason)?.upcast()),
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
)
|
|
134
|
+
.await;
|
|
135
|
+
}
|
|
136
|
+
WorkerRequest::CompleteActivityTask {
|
|
137
|
+
completion,
|
|
138
|
+
otel_span,
|
|
139
|
+
callback,
|
|
140
|
+
} => {
|
|
141
|
+
let otel_ctx =
|
|
142
|
+
opentelemetry::Context::new().with_remote_span_context(otel_span);
|
|
143
|
+
void_future_to_js(
|
|
144
|
+
channel,
|
|
145
|
+
callback,
|
|
146
|
+
async move {
|
|
147
|
+
worker
|
|
148
|
+
.complete_activity_task(completion)
|
|
149
|
+
.with_context(otel_ctx)
|
|
150
|
+
.await
|
|
151
|
+
},
|
|
152
|
+
|cx, err| -> JsResult<JsObject> {
|
|
153
|
+
match err {
|
|
154
|
+
CompleteActivityError::MalformedActivityCompletion {
|
|
155
|
+
reason,
|
|
156
|
+
..
|
|
157
|
+
} => Ok(JsError::type_error(cx, reason)?.upcast()),
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
)
|
|
161
|
+
.await;
|
|
162
|
+
}
|
|
163
|
+
WorkerRequest::RecordActivityHeartbeat { heartbeat } => {
|
|
164
|
+
worker.record_activity_heartbeat(heartbeat)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
.await;
|
|
170
|
+
worker.finalize_shutdown().await;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/// Called within the poll loop thread, calls core and triggers JS callback with result
|
|
174
|
+
async fn handle_poll_workflow_activation_request(
|
|
175
|
+
worker: &CoreWorker,
|
|
176
|
+
span_context: SpanContext,
|
|
177
|
+
channel: Arc<Channel>,
|
|
178
|
+
callback: Root<JsFunction>,
|
|
179
|
+
) {
|
|
180
|
+
let otel_ctx = opentelemetry::Context::new().with_remote_span_context(span_context);
|
|
181
|
+
match worker
|
|
182
|
+
.poll_workflow_activation()
|
|
183
|
+
.with_context(otel_ctx)
|
|
184
|
+
.await
|
|
185
|
+
{
|
|
186
|
+
Ok(task) => {
|
|
187
|
+
send_result(channel, callback, move |cx| {
|
|
188
|
+
let len = task.encoded_len();
|
|
189
|
+
let mut result = JsArrayBuffer::new(cx, len)?;
|
|
190
|
+
let mut slice = result.as_mut_slice(cx);
|
|
191
|
+
if task.encode(&mut slice).is_err() {
|
|
192
|
+
panic!("Failed to encode task")
|
|
193
|
+
};
|
|
194
|
+
Ok(result)
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
Err(err) => {
|
|
198
|
+
send_error(channel, callback, move |cx| match err {
|
|
199
|
+
PollWfError::ShutDown => SHUTDOWN_ERROR.from_error(cx, err),
|
|
200
|
+
PollWfError::TonicError(_) => TRANSPORT_ERROR.from_error(cx, err),
|
|
201
|
+
PollWfError::AutocompleteError(CompleteWfError::MalformedWorkflowCompletion {
|
|
202
|
+
reason,
|
|
203
|
+
..
|
|
204
|
+
}) => Ok(JsError::type_error(cx, reason)?.upcast()),
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/// Called within the poll loop thread, calls core and triggers JS callback with result
|
|
211
|
+
pub async fn handle_poll_activity_task_request(
|
|
212
|
+
worker: &CoreWorker,
|
|
213
|
+
span_context: SpanContext,
|
|
214
|
+
channel: Arc<Channel>,
|
|
215
|
+
callback: Root<JsFunction>,
|
|
216
|
+
) {
|
|
217
|
+
let otel_ctx = opentelemetry::Context::new().with_remote_span_context(span_context);
|
|
218
|
+
match worker.poll_activity_task().with_context(otel_ctx).await {
|
|
219
|
+
Ok(task) => {
|
|
220
|
+
send_result(channel, callback, move |cx| {
|
|
221
|
+
let len = task.encoded_len();
|
|
222
|
+
let mut result = JsArrayBuffer::new(cx, len)?;
|
|
223
|
+
let mut slice = result.as_mut_slice(cx);
|
|
224
|
+
if task.encode(&mut slice).is_err() {
|
|
225
|
+
panic!("Failed to encode task")
|
|
226
|
+
};
|
|
227
|
+
Ok(result)
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
Err(err) => {
|
|
231
|
+
send_error(channel, callback, move |cx| match err {
|
|
232
|
+
PollActivityError::ShutDown => SHUTDOWN_ERROR.from_error(cx, err),
|
|
233
|
+
PollActivityError::TonicError(_) => TRANSPORT_ERROR.from_error(cx, err),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Below are functions exported to JS
|
|
240
|
+
|
|
241
|
+
/// Create a new worker asynchronously.
|
|
242
|
+
/// Worker uses the provided connection and returned to JS using supplied `callback`.
|
|
243
|
+
pub fn worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
244
|
+
let client = cx.argument::<BoxedClient>(0)?;
|
|
245
|
+
let worker_options = cx.argument::<JsObject>(1)?;
|
|
246
|
+
let callback = cx.argument::<JsFunction>(2)?;
|
|
247
|
+
|
|
248
|
+
let config = worker_options.as_worker_config(&mut cx)?;
|
|
249
|
+
match client.borrow().as_ref() {
|
|
250
|
+
None => {
|
|
251
|
+
callback_with_unexpected_error(&mut cx, callback, "Tried to use closed Client")?;
|
|
252
|
+
}
|
|
253
|
+
Some(client) => {
|
|
254
|
+
let request = RuntimeRequest::InitWorker {
|
|
255
|
+
client: client.core_client.clone(),
|
|
256
|
+
config,
|
|
257
|
+
callback: callback.root(&mut cx),
|
|
258
|
+
};
|
|
259
|
+
if let Err(err) = client.runtime.sender.send(request) {
|
|
260
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
Ok(cx.undefined())
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// Create a new replay worker asynchronously.
|
|
269
|
+
/// Worker is returned to JS using supplied callback.
|
|
270
|
+
pub fn replay_worker_new(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
271
|
+
let runtime = cx.argument::<BoxedRuntime>(0)?;
|
|
272
|
+
let worker_options = cx.argument::<JsObject>(1)?;
|
|
273
|
+
let history_binary = cx.argument::<JsArrayBuffer>(2)?;
|
|
274
|
+
let callback = cx.argument::<JsFunction>(3)?;
|
|
275
|
+
|
|
276
|
+
let config = worker_options.as_worker_config(&mut cx)?;
|
|
277
|
+
let data = history_binary.as_slice(&mut cx);
|
|
278
|
+
match History::decode_length_delimited(data) {
|
|
279
|
+
Ok(history) => {
|
|
280
|
+
let request = RuntimeRequest::InitReplayWorker {
|
|
281
|
+
config,
|
|
282
|
+
history,
|
|
283
|
+
callback: callback.root(&mut cx),
|
|
284
|
+
};
|
|
285
|
+
if let Err(err) = runtime.sender.send(request) {
|
|
286
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
Err(_) => callback_with_error(&mut cx, callback, |cx| {
|
|
290
|
+
JsError::type_error(cx, "Cannot decode History from buffer")
|
|
291
|
+
})?,
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
Ok(cx.undefined())
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/// Initiate a single workflow activation poll request.
|
|
298
|
+
/// There should be only one concurrent poll request for this type.
|
|
299
|
+
pub fn worker_poll_workflow_activation(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
300
|
+
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
301
|
+
let otel_span = cx.argument::<JsObject>(1)?;
|
|
302
|
+
let callback = cx.argument::<JsFunction>(2)?;
|
|
303
|
+
match worker.borrow().as_ref() {
|
|
304
|
+
None => {
|
|
305
|
+
callback_with_unexpected_error(&mut cx, callback, "Tried to use closed Worker")?;
|
|
306
|
+
}
|
|
307
|
+
Some(worker) => {
|
|
308
|
+
let request = WorkerRequest::PollWorkflowActivation {
|
|
309
|
+
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
310
|
+
callback: callback.root(&mut cx),
|
|
311
|
+
};
|
|
312
|
+
if let Err(err) = worker.sender.send(request) {
|
|
313
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
Ok(cx.undefined())
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/// Initiate a single activity task poll request.
|
|
321
|
+
/// There should be only one concurrent poll request for this type.
|
|
322
|
+
pub fn worker_poll_activity_task(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
323
|
+
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
324
|
+
let otel_span = cx.argument::<JsObject>(1)?;
|
|
325
|
+
let callback = cx.argument::<JsFunction>(2)?;
|
|
326
|
+
match worker.borrow().as_ref() {
|
|
327
|
+
None => {
|
|
328
|
+
callback_with_unexpected_error(&mut cx, callback, "Tried to use closed Worker")?;
|
|
329
|
+
}
|
|
330
|
+
Some(worker) => {
|
|
331
|
+
let request = WorkerRequest::PollActivityTask {
|
|
332
|
+
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
333
|
+
callback: callback.root(&mut cx),
|
|
334
|
+
};
|
|
335
|
+
if let Err(err) = worker.sender.send(request) {
|
|
336
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
Ok(cx.undefined())
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/// Submit a workflow activation completion to core.
|
|
344
|
+
pub fn worker_complete_workflow_activation(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
345
|
+
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
346
|
+
let otel_span = cx.argument::<JsObject>(1)?;
|
|
347
|
+
let completion = cx.argument::<JsArrayBuffer>(2)?;
|
|
348
|
+
let callback = cx.argument::<JsFunction>(3)?;
|
|
349
|
+
match worker.borrow().as_ref() {
|
|
350
|
+
None => {
|
|
351
|
+
callback_with_unexpected_error(&mut cx, callback, "Tried to use closed Worker")?;
|
|
352
|
+
}
|
|
353
|
+
Some(worker) => {
|
|
354
|
+
match WorkflowActivationCompletion::decode_length_delimited(
|
|
355
|
+
completion.as_slice(&mut cx),
|
|
356
|
+
) {
|
|
357
|
+
Ok(completion) => {
|
|
358
|
+
let request = WorkerRequest::CompleteWorkflowActivation {
|
|
359
|
+
completion,
|
|
360
|
+
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
361
|
+
callback: callback.root(&mut cx),
|
|
362
|
+
};
|
|
363
|
+
if let Err(err) = worker.sender.send(request) {
|
|
364
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
Err(_) => callback_with_error(&mut cx, callback, |cx| {
|
|
368
|
+
JsError::type_error(cx, "Cannot decode Completion from buffer")
|
|
369
|
+
})?,
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
Ok(cx.undefined())
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/// Submit an activity task completion to core.
|
|
377
|
+
pub fn worker_complete_activity_task(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
378
|
+
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
379
|
+
let otel_span = cx.argument::<JsObject>(1)?;
|
|
380
|
+
let result = cx.argument::<JsArrayBuffer>(2)?;
|
|
381
|
+
let callback = cx.argument::<JsFunction>(3)?;
|
|
382
|
+
match worker.borrow().as_ref() {
|
|
383
|
+
None => {
|
|
384
|
+
callback_with_unexpected_error(&mut cx, callback, "Tried to use closed Worker")?;
|
|
385
|
+
}
|
|
386
|
+
Some(worker) => {
|
|
387
|
+
match ActivityTaskCompletion::decode_length_delimited(result.as_slice(&mut cx)) {
|
|
388
|
+
Ok(completion) => {
|
|
389
|
+
let request = WorkerRequest::CompleteActivityTask {
|
|
390
|
+
completion,
|
|
391
|
+
otel_span: otel_span.as_otel_span_context(&mut cx)?,
|
|
392
|
+
callback: callback.root(&mut cx),
|
|
393
|
+
};
|
|
394
|
+
if let Err(err) = worker.sender.send(request) {
|
|
395
|
+
callback_with_unexpected_error(&mut cx, callback, err)?;
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
Err(_) => callback_with_error(&mut cx, callback, |cx| {
|
|
399
|
+
JsError::type_error(cx, "Cannot decode Completion from buffer")
|
|
400
|
+
})?,
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
Ok(cx.undefined())
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/// Submit an activity heartbeat to core.
|
|
408
|
+
pub fn worker_record_activity_heartbeat(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
409
|
+
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
410
|
+
let heartbeat = cx.argument::<JsArrayBuffer>(1)?;
|
|
411
|
+
match worker.borrow().as_ref() {
|
|
412
|
+
None => UNEXPECTED_ERROR
|
|
413
|
+
.from_string(&mut cx, "Tried to use closed Worker")
|
|
414
|
+
.and_then(|err| cx.throw(err))?,
|
|
415
|
+
Some(worker) => {
|
|
416
|
+
match ActivityHeartbeat::decode_length_delimited(heartbeat.as_slice(&mut cx)) {
|
|
417
|
+
Ok(heartbeat) => {
|
|
418
|
+
let request = WorkerRequest::RecordActivityHeartbeat { heartbeat };
|
|
419
|
+
if let Err(err) = worker.sender.send(request) {
|
|
420
|
+
UNEXPECTED_ERROR
|
|
421
|
+
.from_error(&mut cx, err)
|
|
422
|
+
.and_then(|err| cx.throw(err))?;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
Err(_) => cx.throw_type_error("Cannot decode ActivityHeartbeat from buffer")?,
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
Ok(cx.undefined())
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/// Request shutdown of the worker.
|
|
433
|
+
/// Once complete Core will stop polling on new tasks and activations on worker's task queue.
|
|
434
|
+
/// Caller should drain any pending tasks and activations and call worker_finalize_shutdown before breaking from
|
|
435
|
+
/// the loop to ensure graceful shutdown.
|
|
436
|
+
pub fn worker_initiate_shutdown(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
437
|
+
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
438
|
+
let callback = cx.argument::<JsFunction>(1)?;
|
|
439
|
+
match worker.borrow().as_ref() {
|
|
440
|
+
None => {
|
|
441
|
+
callback_with_unexpected_error(&mut cx, callback, "Tried to use closed Worker")?;
|
|
442
|
+
}
|
|
443
|
+
Some(worker) => {
|
|
444
|
+
if let Err(err) = worker.sender.send(WorkerRequest::InitiateShutdown {
|
|
445
|
+
callback: callback.root(&mut cx),
|
|
446
|
+
}) {
|
|
447
|
+
UNEXPECTED_ERROR
|
|
448
|
+
.from_error(&mut cx, err)
|
|
449
|
+
.and_then(|err| cx.throw(err))?;
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
Ok(cx.undefined())
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
pub fn worker_finalize_shutdown(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
|
457
|
+
let worker = cx.argument::<BoxedWorker>(0)?;
|
|
458
|
+
if worker.replace(None).is_none() {
|
|
459
|
+
ILLEGAL_STATE_ERROR
|
|
460
|
+
.from_string(&mut cx, "Worker already closed")
|
|
461
|
+
.and_then(|err| cx.throw(err))?;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
Ok(cx.undefined())
|
|
465
|
+
}
|