@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
|
@@ -0,0 +1,829 @@
|
|
|
1
|
+
#![allow(
|
|
2
|
+
// Non-camel-case types needed since this is exported as a C header and we
|
|
3
|
+
// want C-like underscores in our type names
|
|
4
|
+
non_camel_case_types,
|
|
5
|
+
|
|
6
|
+
// We choose to have narrow "unsafe" blocks instead of marking entire
|
|
7
|
+
// functions as unsafe. Even the example in clippy's docs at
|
|
8
|
+
// https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref
|
|
9
|
+
// cause a rustc warning for unnecessary inner-unsafe when marked on fn.
|
|
10
|
+
// This check only applies to "pub" functions which are all exposed via C
|
|
11
|
+
// API.
|
|
12
|
+
clippy::not_unsafe_ptr_arg_deref,
|
|
13
|
+
)]
|
|
14
|
+
|
|
15
|
+
mod wrappers;
|
|
16
|
+
|
|
17
|
+
use prost::Message;
|
|
18
|
+
use temporal_sdk_core_protos::coresdk::bridge;
|
|
19
|
+
|
|
20
|
+
/// A set of bytes owned by Core. No fields within nor any bytes references must
|
|
21
|
+
/// ever be mutated outside of Core. This must always be passed to
|
|
22
|
+
/// tmprl_bytes_free when no longer in use.
|
|
23
|
+
#[repr(C)]
|
|
24
|
+
pub struct tmprl_bytes_t {
|
|
25
|
+
bytes: *const u8,
|
|
26
|
+
len: libc::size_t,
|
|
27
|
+
/// For internal use only.
|
|
28
|
+
cap: libc::size_t,
|
|
29
|
+
/// For internal use only.
|
|
30
|
+
disable_free: bool,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
impl tmprl_bytes_t {
|
|
34
|
+
fn from_vec(vec: Vec<u8>) -> tmprl_bytes_t {
|
|
35
|
+
// Mimics Vec::into_raw_parts that's only available in nightly
|
|
36
|
+
let mut vec = std::mem::ManuallyDrop::new(vec);
|
|
37
|
+
tmprl_bytes_t {
|
|
38
|
+
bytes: vec.as_mut_ptr(),
|
|
39
|
+
len: vec.len(),
|
|
40
|
+
cap: vec.capacity(),
|
|
41
|
+
disable_free: false,
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fn from_vec_disable_free(vec: Vec<u8>) -> tmprl_bytes_t {
|
|
46
|
+
let mut b = tmprl_bytes_t::from_vec(vec);
|
|
47
|
+
b.disable_free = true;
|
|
48
|
+
b
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fn into_raw(self) -> *mut tmprl_bytes_t {
|
|
52
|
+
Box::into_raw(Box::new(self))
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// Required because these instances are used by lazy_static and raw pointers
|
|
57
|
+
/// are not usually safe for send/sync.
|
|
58
|
+
unsafe impl Send for tmprl_bytes_t {}
|
|
59
|
+
unsafe impl Sync for tmprl_bytes_t {}
|
|
60
|
+
|
|
61
|
+
impl Drop for tmprl_bytes_t {
|
|
62
|
+
fn drop(&mut self) {
|
|
63
|
+
// In cases where freeing is disabled (or technically some other
|
|
64
|
+
// drop-but-not-freed situation though we don't expect any), the bytes
|
|
65
|
+
// remain non-null so we re-own them here
|
|
66
|
+
if !self.bytes.is_null() {
|
|
67
|
+
unsafe { Vec::from_raw_parts(self.bytes as *mut u8, self.len, self.cap) };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// Free a set of bytes. The first parameter can be null in cases where a
|
|
73
|
+
/// tmprl_core_t instance isn't available. If the second parameter is null, this
|
|
74
|
+
/// is a no-op.
|
|
75
|
+
#[no_mangle]
|
|
76
|
+
pub extern "C" fn tmprl_bytes_free(core: *mut tmprl_core_t, bytes: *const tmprl_bytes_t) {
|
|
77
|
+
// Bail if freeing is disabled
|
|
78
|
+
unsafe {
|
|
79
|
+
if bytes.is_null() || (*bytes).disable_free {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let bytes = bytes as *mut tmprl_bytes_t;
|
|
84
|
+
// Return vec back to core before dropping bytes
|
|
85
|
+
let vec = unsafe { Vec::from_raw_parts((*bytes).bytes as *mut u8, (*bytes).len, (*bytes).cap) };
|
|
86
|
+
// Set to null so the byte dropper doesn't try to free it
|
|
87
|
+
unsafe { (*bytes).bytes = std::ptr::null_mut() };
|
|
88
|
+
// Return only if core is non-null
|
|
89
|
+
if !core.is_null() {
|
|
90
|
+
let core = unsafe { &mut *core };
|
|
91
|
+
core.return_buf(vec);
|
|
92
|
+
}
|
|
93
|
+
unsafe {
|
|
94
|
+
Box::from_raw(bytes);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/// Used for maintaining pointer to user data across threads. See
|
|
99
|
+
/// https://doc.rust-lang.org/nomicon/send-and-sync.html.
|
|
100
|
+
struct UserDataHandle(*mut libc::c_void);
|
|
101
|
+
unsafe impl Send for UserDataHandle {}
|
|
102
|
+
unsafe impl Sync for UserDataHandle {}
|
|
103
|
+
|
|
104
|
+
impl From<UserDataHandle> for *mut libc::c_void {
|
|
105
|
+
fn from(v: UserDataHandle) -> Self {
|
|
106
|
+
v.0
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
lazy_static::lazy_static! {
|
|
111
|
+
static ref DEFAULT_INIT_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
112
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::InitResponse::default().encode_to_vec())
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
static ref DEFAULT_SHUTDOWN_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
116
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::ShutdownResponse::default().encode_to_vec())
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
static ref DEFAULT_REGISTER_WORKER_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
120
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::RegisterWorkerResponse::default().encode_to_vec())
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
static ref DEFAULT_SHUTDOWN_WORKER_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
124
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::ShutdownWorkerResponse::default().encode_to_vec())
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
static ref DEFAULT_COMPLETE_WORKFLOW_ACTIVATION_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
128
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::CompleteWorkflowActivationResponse::default().encode_to_vec())
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
static ref DEFAULT_COMPLETE_ACTIVITY_TASK_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
132
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::CompleteActivityTaskResponse::default().encode_to_vec())
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
static ref DEFAULT_RECORD_ACTIVITY_HEARTBEAT_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
136
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::RecordActivityHeartbeatResponse::default().encode_to_vec())
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
static ref DEFAULT_REQUEST_WORKFLOW_EVICTION_RESPONSE_BYTES: tmprl_bytes_t = {
|
|
140
|
+
tmprl_bytes_t::from_vec_disable_free(bridge::RequestWorkflowEvictionResponse::default().encode_to_vec())
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/// A runtime owned by Core. This must be passed to tmprl_runtime_free when no
|
|
145
|
+
/// longer in use. This must not be freed until every call to every tmprl_core_t
|
|
146
|
+
/// instance created with this runtime has been shutdown.
|
|
147
|
+
pub struct tmprl_runtime_t {
|
|
148
|
+
// This is the same runtime shared with the core instance
|
|
149
|
+
tokio_runtime: std::sync::Arc<tokio::runtime::Runtime>,
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/// Create a new runtime. The result is never null and must be freed via
|
|
153
|
+
/// tmprl_runtime_free when no longer in use.
|
|
154
|
+
#[no_mangle]
|
|
155
|
+
pub extern "C" fn tmprl_runtime_new() -> *mut tmprl_runtime_t {
|
|
156
|
+
Box::into_raw(Box::new(tmprl_runtime_t {
|
|
157
|
+
// TODO(cretz): Options to configure thread pool?
|
|
158
|
+
tokio_runtime: std::sync::Arc::new(
|
|
159
|
+
tokio::runtime::Builder::new_multi_thread()
|
|
160
|
+
.enable_all()
|
|
161
|
+
.build()
|
|
162
|
+
.unwrap(),
|
|
163
|
+
),
|
|
164
|
+
}))
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/// Free a previously created runtime.
|
|
168
|
+
#[no_mangle]
|
|
169
|
+
pub extern "C" fn tmprl_runtime_free(runtime: *mut tmprl_runtime_t) {
|
|
170
|
+
if !runtime.is_null() {
|
|
171
|
+
unsafe {
|
|
172
|
+
Box::from_raw(runtime);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/// A core instance owned by Core. This must be passed to tmprl_core_shutdown
|
|
178
|
+
/// when no longer in use which will free the resources.
|
|
179
|
+
pub struct tmprl_core_t {
|
|
180
|
+
tokio_runtime: std::sync::Arc<tokio::runtime::Runtime>,
|
|
181
|
+
// We are not concerned with the overhead of dynamic dispatch at this time
|
|
182
|
+
core: std::sync::Arc<dyn temporal_sdk_core_api::Core>,
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/// Callback called by tmprl_core_init on completion. The first parameter of the
|
|
186
|
+
/// callback is user data passed into the original function. The second
|
|
187
|
+
/// parameter is a core instance if the call is successful or null if not. If
|
|
188
|
+
/// present, the core instance must be freed via tmprl_core_shutdown when no
|
|
189
|
+
/// longer in use. The third parameter of the callback is a byte array for a
|
|
190
|
+
/// InitResponse protobuf message which must be freed via tmprl_bytes_free.
|
|
191
|
+
type tmprl_core_init_callback = unsafe extern "C" fn(
|
|
192
|
+
user_data: *mut libc::c_void,
|
|
193
|
+
core: *mut tmprl_core_t,
|
|
194
|
+
resp: *const tmprl_bytes_t,
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
/// Callback called on function completion. The first parameter of the callback
|
|
198
|
+
/// is user data passed into the original function. The second parameter of the
|
|
199
|
+
/// callback is a never-null byte array for a response protobuf message which
|
|
200
|
+
/// must be freed via tmprl_bytes_free.
|
|
201
|
+
type tmprl_callback =
|
|
202
|
+
unsafe extern "C" fn(user_data: *mut libc::c_void, core: *const tmprl_bytes_t);
|
|
203
|
+
|
|
204
|
+
/// Create a new core instance.
|
|
205
|
+
///
|
|
206
|
+
/// The runtime is required and must outlive this instance. The req_proto and
|
|
207
|
+
/// req_proto_len represent a byte array for a InitRequest protobuf message. The
|
|
208
|
+
/// callback is invoked on completion.
|
|
209
|
+
#[no_mangle]
|
|
210
|
+
pub extern "C" fn tmprl_core_init(
|
|
211
|
+
runtime: *mut tmprl_runtime_t,
|
|
212
|
+
req_proto: *const u8,
|
|
213
|
+
req_proto_len: libc::size_t,
|
|
214
|
+
user_data: *mut libc::c_void,
|
|
215
|
+
callback: tmprl_core_init_callback,
|
|
216
|
+
) {
|
|
217
|
+
let runtime = unsafe { &*runtime };
|
|
218
|
+
let req = match tmprl_core_t::decode_proto::<bridge::InitRequest>(req_proto, req_proto_len) {
|
|
219
|
+
Ok(req) => req,
|
|
220
|
+
Err(message) => {
|
|
221
|
+
let resp = bridge::InitResponse {
|
|
222
|
+
error: Some(bridge::init_response::Error { message }),
|
|
223
|
+
};
|
|
224
|
+
unsafe {
|
|
225
|
+
callback(
|
|
226
|
+
user_data,
|
|
227
|
+
std::ptr::null_mut(),
|
|
228
|
+
tmprl_bytes_t::from_vec(resp.encode_to_vec()).into_raw(),
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
let user_data = UserDataHandle(user_data);
|
|
235
|
+
runtime.tokio_runtime.spawn(async move {
|
|
236
|
+
match tmprl_core_t::new(
|
|
237
|
+
runtime.tokio_runtime.clone(),
|
|
238
|
+
wrappers::CoreInitOptions(req),
|
|
239
|
+
)
|
|
240
|
+
.await
|
|
241
|
+
{
|
|
242
|
+
Ok(core) => unsafe {
|
|
243
|
+
callback(
|
|
244
|
+
user_data.into(),
|
|
245
|
+
Box::into_raw(Box::new(core)),
|
|
246
|
+
&*DEFAULT_INIT_RESPONSE_BYTES,
|
|
247
|
+
);
|
|
248
|
+
},
|
|
249
|
+
Err(message) => {
|
|
250
|
+
let resp = bridge::InitResponse {
|
|
251
|
+
error: Some(bridge::init_response::Error { message }),
|
|
252
|
+
};
|
|
253
|
+
unsafe {
|
|
254
|
+
callback(
|
|
255
|
+
user_data.into(),
|
|
256
|
+
std::ptr::null_mut(),
|
|
257
|
+
tmprl_bytes_t::from_vec(resp.encode_to_vec()).into_raw(),
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/// Shutdown and free a core instance.
|
|
266
|
+
///
|
|
267
|
+
/// The req_proto and req_proto_len represent a byte array for a ShutdownRequest
|
|
268
|
+
/// protobuf message. The callback is invoked on completion with a
|
|
269
|
+
/// ShutdownResponse protobuf message.
|
|
270
|
+
#[no_mangle]
|
|
271
|
+
pub extern "C" fn tmprl_core_shutdown(
|
|
272
|
+
core: *mut tmprl_core_t,
|
|
273
|
+
#[allow(unused_variables)] // We intentionally ignore the request
|
|
274
|
+
req_proto: *const u8,
|
|
275
|
+
#[allow(unused_variables)] req_proto_len: libc::size_t,
|
|
276
|
+
user_data: *mut libc::c_void,
|
|
277
|
+
callback: tmprl_callback,
|
|
278
|
+
) {
|
|
279
|
+
// Re-own the object so it can be dropped
|
|
280
|
+
let core = unsafe { Box::from_raw(core) };
|
|
281
|
+
let user_data = UserDataHandle(user_data);
|
|
282
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
283
|
+
core.shutdown().await;
|
|
284
|
+
unsafe {
|
|
285
|
+
callback(user_data.into(), &*DEFAULT_SHUTDOWN_RESPONSE_BYTES);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/// Register a worker.
|
|
291
|
+
///
|
|
292
|
+
/// The req_proto and req_proto_len represent a byte array for a RegisterWorker
|
|
293
|
+
/// protobuf message. The callback is invoked on completion with a
|
|
294
|
+
/// RegisterWorkerResponse protobuf message.
|
|
295
|
+
#[no_mangle]
|
|
296
|
+
pub extern "C" fn tmprl_register_worker(
|
|
297
|
+
core: *mut tmprl_core_t,
|
|
298
|
+
req_proto: *const u8,
|
|
299
|
+
req_proto_len: libc::size_t,
|
|
300
|
+
user_data: *mut libc::c_void,
|
|
301
|
+
callback: tmprl_callback,
|
|
302
|
+
) {
|
|
303
|
+
let core = unsafe { &mut *core };
|
|
304
|
+
let req =
|
|
305
|
+
match tmprl_core_t::decode_proto::<bridge::RegisterWorkerRequest>(req_proto, req_proto_len)
|
|
306
|
+
{
|
|
307
|
+
Ok(req) => req,
|
|
308
|
+
Err(message) => {
|
|
309
|
+
let resp = bridge::RegisterWorkerResponse {
|
|
310
|
+
error: Some(bridge::register_worker_response::Error {
|
|
311
|
+
message,
|
|
312
|
+
worker_already_registered: false,
|
|
313
|
+
}),
|
|
314
|
+
};
|
|
315
|
+
unsafe {
|
|
316
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
317
|
+
}
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
let user_data = UserDataHandle(user_data);
|
|
322
|
+
match core.register_worker(wrappers::WorkerConfig(req)) {
|
|
323
|
+
Ok(()) => unsafe {
|
|
324
|
+
callback(user_data.into(), &*DEFAULT_REGISTER_WORKER_RESPONSE_BYTES);
|
|
325
|
+
},
|
|
326
|
+
Err(err) => {
|
|
327
|
+
let resp = bridge::RegisterWorkerResponse { error: Some(err) };
|
|
328
|
+
unsafe { callback(user_data.into(), core.encode_proto(&resp).into_raw()) };
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/// Shutdown registered worker.
|
|
334
|
+
///
|
|
335
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
336
|
+
/// ShutdownWorkerRequest protobuf message. The callback is invoked on
|
|
337
|
+
/// completion with a ShutdownWorkerResponse protobuf message.
|
|
338
|
+
#[no_mangle]
|
|
339
|
+
pub extern "C" fn tmprl_shutdown_worker(
|
|
340
|
+
core: *mut tmprl_core_t,
|
|
341
|
+
#[allow(unused_variables)] // We intentionally ignore the request
|
|
342
|
+
req_proto: *const u8,
|
|
343
|
+
#[allow(unused_variables)] req_proto_len: libc::size_t,
|
|
344
|
+
user_data: *mut libc::c_void,
|
|
345
|
+
callback: tmprl_callback,
|
|
346
|
+
) {
|
|
347
|
+
let core = unsafe { &mut *core };
|
|
348
|
+
let req =
|
|
349
|
+
match tmprl_core_t::decode_proto::<bridge::ShutdownWorkerRequest>(req_proto, req_proto_len)
|
|
350
|
+
{
|
|
351
|
+
Ok(req) => req,
|
|
352
|
+
Err(message) => {
|
|
353
|
+
let resp = bridge::ShutdownWorkerResponse {
|
|
354
|
+
error: Some(bridge::shutdown_worker_response::Error { message }),
|
|
355
|
+
};
|
|
356
|
+
unsafe {
|
|
357
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
358
|
+
}
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
let user_data = UserDataHandle(user_data);
|
|
363
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
364
|
+
core.shutdown_worker(req).await;
|
|
365
|
+
unsafe {
|
|
366
|
+
callback(user_data.into(), &*DEFAULT_SHUTDOWN_WORKER_RESPONSE_BYTES);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/// Poll workflow activation.
|
|
372
|
+
///
|
|
373
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
374
|
+
/// PollWorkflowActivationRequest protobuf message. The callback is invoked on
|
|
375
|
+
/// completion with a PollWorkflowActivationResponse protobuf message.
|
|
376
|
+
#[no_mangle]
|
|
377
|
+
pub extern "C" fn tmprl_poll_workflow_activation(
|
|
378
|
+
core: *mut tmprl_core_t,
|
|
379
|
+
req_proto: *const u8,
|
|
380
|
+
req_proto_len: libc::size_t,
|
|
381
|
+
user_data: *mut libc::c_void,
|
|
382
|
+
callback: tmprl_callback,
|
|
383
|
+
) {
|
|
384
|
+
let core = unsafe { &mut *core };
|
|
385
|
+
let req = match tmprl_core_t::decode_proto::<bridge::PollWorkflowActivationRequest>(
|
|
386
|
+
req_proto,
|
|
387
|
+
req_proto_len,
|
|
388
|
+
) {
|
|
389
|
+
Ok(req) => req,
|
|
390
|
+
Err(message) => {
|
|
391
|
+
let resp = bridge::PollWorkflowActivationResponse {
|
|
392
|
+
response: Some(bridge::poll_workflow_activation_response::Response::Error(
|
|
393
|
+
bridge::poll_workflow_activation_response::Error {
|
|
394
|
+
message,
|
|
395
|
+
shutdown: false,
|
|
396
|
+
},
|
|
397
|
+
)),
|
|
398
|
+
};
|
|
399
|
+
unsafe {
|
|
400
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
401
|
+
}
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
let user_data = UserDataHandle(user_data);
|
|
406
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
407
|
+
let resp = bridge::PollWorkflowActivationResponse {
|
|
408
|
+
response: Some(match core.poll_workflow_activation(req).await {
|
|
409
|
+
Ok(act) => bridge::poll_workflow_activation_response::Response::Activation(act),
|
|
410
|
+
Err(err) => bridge::poll_workflow_activation_response::Response::Error(err),
|
|
411
|
+
}),
|
|
412
|
+
};
|
|
413
|
+
unsafe { callback(user_data.into(), core.encode_proto(&resp).into_raw()) };
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/// Poll activity task.
|
|
418
|
+
///
|
|
419
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
420
|
+
/// PollActivityTaskRequest protobuf message. The callback is invoked on
|
|
421
|
+
/// completion with a PollActivityTaskResponse protobuf message.
|
|
422
|
+
#[no_mangle]
|
|
423
|
+
pub extern "C" fn tmprl_poll_activity_task(
|
|
424
|
+
core: *mut tmprl_core_t,
|
|
425
|
+
req_proto: *const u8,
|
|
426
|
+
req_proto_len: libc::size_t,
|
|
427
|
+
user_data: *mut libc::c_void,
|
|
428
|
+
callback: tmprl_callback,
|
|
429
|
+
) {
|
|
430
|
+
let core = unsafe { &mut *core };
|
|
431
|
+
let req = match tmprl_core_t::decode_proto::<bridge::PollActivityTaskRequest>(
|
|
432
|
+
req_proto,
|
|
433
|
+
req_proto_len,
|
|
434
|
+
) {
|
|
435
|
+
Ok(req) => req,
|
|
436
|
+
Err(message) => {
|
|
437
|
+
let resp = bridge::PollActivityTaskResponse {
|
|
438
|
+
response: Some(bridge::poll_activity_task_response::Response::Error(
|
|
439
|
+
bridge::poll_activity_task_response::Error {
|
|
440
|
+
message,
|
|
441
|
+
shutdown: false,
|
|
442
|
+
},
|
|
443
|
+
)),
|
|
444
|
+
};
|
|
445
|
+
unsafe {
|
|
446
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
447
|
+
}
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
let user_data = UserDataHandle(user_data);
|
|
452
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
453
|
+
let resp = bridge::PollActivityTaskResponse {
|
|
454
|
+
response: Some(match core.poll_activity_task(req).await {
|
|
455
|
+
Ok(task) => bridge::poll_activity_task_response::Response::Task(task),
|
|
456
|
+
Err(err) => bridge::poll_activity_task_response::Response::Error(err),
|
|
457
|
+
}),
|
|
458
|
+
};
|
|
459
|
+
unsafe { callback(user_data.into(), core.encode_proto(&resp).into_raw()) };
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/// Complete workflow activation.
|
|
464
|
+
///
|
|
465
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
466
|
+
/// CompleteWorkflowActivationRequest protobuf message. The callback is invoked
|
|
467
|
+
/// on completion with a CompleteWorkflowActivationResponse protobuf message.
|
|
468
|
+
#[no_mangle]
|
|
469
|
+
pub extern "C" fn tmprl_complete_workflow_activation(
|
|
470
|
+
core: *mut tmprl_core_t,
|
|
471
|
+
req_proto: *const u8,
|
|
472
|
+
req_proto_len: libc::size_t,
|
|
473
|
+
user_data: *mut libc::c_void,
|
|
474
|
+
callback: tmprl_callback,
|
|
475
|
+
) {
|
|
476
|
+
let core = unsafe { &mut *core };
|
|
477
|
+
let req = match tmprl_core_t::decode_proto::<bridge::CompleteWorkflowActivationRequest>(
|
|
478
|
+
req_proto,
|
|
479
|
+
req_proto_len,
|
|
480
|
+
) {
|
|
481
|
+
Ok(req) => req,
|
|
482
|
+
Err(message) => {
|
|
483
|
+
let resp = bridge::CompleteWorkflowActivationResponse {
|
|
484
|
+
error: Some(bridge::complete_workflow_activation_response::Error { message }),
|
|
485
|
+
};
|
|
486
|
+
unsafe {
|
|
487
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
488
|
+
}
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
let user_data = UserDataHandle(user_data);
|
|
493
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
494
|
+
match core.complete_workflow_activation(req).await {
|
|
495
|
+
Ok(()) => unsafe {
|
|
496
|
+
callback(
|
|
497
|
+
user_data.into(),
|
|
498
|
+
&*DEFAULT_COMPLETE_WORKFLOW_ACTIVATION_RESPONSE_BYTES,
|
|
499
|
+
);
|
|
500
|
+
},
|
|
501
|
+
Err(err) => {
|
|
502
|
+
let resp = bridge::CompleteWorkflowActivationResponse { error: Some(err) };
|
|
503
|
+
unsafe { callback(user_data.into(), core.encode_proto(&resp).into_raw()) };
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/// Complete activity task.
|
|
510
|
+
///
|
|
511
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
512
|
+
/// CompleteActivityTaskRequest protobuf message. The callback is invoked
|
|
513
|
+
/// on completion with a CompleteActivityTaskResponse protobuf message.
|
|
514
|
+
#[no_mangle]
|
|
515
|
+
pub extern "C" fn tmprl_complete_activity_task(
|
|
516
|
+
core: *mut tmprl_core_t,
|
|
517
|
+
req_proto: *const u8,
|
|
518
|
+
req_proto_len: libc::size_t,
|
|
519
|
+
user_data: *mut libc::c_void,
|
|
520
|
+
callback: tmprl_callback,
|
|
521
|
+
) {
|
|
522
|
+
let core = unsafe { &mut *core };
|
|
523
|
+
let req = match tmprl_core_t::decode_proto::<bridge::CompleteActivityTaskRequest>(
|
|
524
|
+
req_proto,
|
|
525
|
+
req_proto_len,
|
|
526
|
+
) {
|
|
527
|
+
Ok(req) => req,
|
|
528
|
+
Err(message) => {
|
|
529
|
+
let resp = bridge::CompleteActivityTaskResponse {
|
|
530
|
+
error: Some(bridge::complete_activity_task_response::Error { message }),
|
|
531
|
+
};
|
|
532
|
+
unsafe {
|
|
533
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
534
|
+
}
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
let user_data = UserDataHandle(user_data);
|
|
539
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
540
|
+
match core.complete_activity_task(req).await {
|
|
541
|
+
Ok(()) => unsafe {
|
|
542
|
+
callback(
|
|
543
|
+
user_data.into(),
|
|
544
|
+
&*DEFAULT_COMPLETE_ACTIVITY_TASK_RESPONSE_BYTES,
|
|
545
|
+
);
|
|
546
|
+
},
|
|
547
|
+
Err(err) => {
|
|
548
|
+
let resp = bridge::CompleteActivityTaskResponse { error: Some(err) };
|
|
549
|
+
unsafe { callback(user_data.into(), core.encode_proto(&resp).into_raw()) };
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/// Record activity heartbeat.
|
|
556
|
+
///
|
|
557
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
558
|
+
/// RecordActivityHeartbeatRequest protobuf message. The callback is invoked
|
|
559
|
+
/// on completion with a RecordActivityHeartbeatResponse protobuf message.
|
|
560
|
+
#[no_mangle]
|
|
561
|
+
pub extern "C" fn tmprl_record_activity_heartbeat(
|
|
562
|
+
core: *mut tmprl_core_t,
|
|
563
|
+
req_proto: *const u8,
|
|
564
|
+
req_proto_len: libc::size_t,
|
|
565
|
+
user_data: *mut libc::c_void,
|
|
566
|
+
callback: tmprl_callback,
|
|
567
|
+
) {
|
|
568
|
+
let core = unsafe { &mut *core };
|
|
569
|
+
let req = match tmprl_core_t::decode_proto::<bridge::RecordActivityHeartbeatRequest>(
|
|
570
|
+
req_proto,
|
|
571
|
+
req_proto_len,
|
|
572
|
+
) {
|
|
573
|
+
Ok(req) => req,
|
|
574
|
+
Err(message) => {
|
|
575
|
+
let resp = bridge::RecordActivityHeartbeatResponse {
|
|
576
|
+
error: Some(bridge::record_activity_heartbeat_response::Error { message }),
|
|
577
|
+
};
|
|
578
|
+
unsafe {
|
|
579
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
580
|
+
}
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
let user_data = UserDataHandle(user_data);
|
|
585
|
+
// We intentionally spawn even though the core call is not async so the
|
|
586
|
+
// callback can be made in the tokio runtime
|
|
587
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
588
|
+
core.record_activity_heartbeat(req);
|
|
589
|
+
unsafe {
|
|
590
|
+
callback(
|
|
591
|
+
user_data.into(),
|
|
592
|
+
&*DEFAULT_RECORD_ACTIVITY_HEARTBEAT_RESPONSE_BYTES,
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/// Request workflow eviction.
|
|
599
|
+
///
|
|
600
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
601
|
+
/// RequestWorkflowEvictionRequest protobuf message. The callback is invoked
|
|
602
|
+
/// on completion with a RequestWorkflowEvictionResponse protobuf message.
|
|
603
|
+
#[no_mangle]
|
|
604
|
+
pub extern "C" fn tmprl_request_workflow_eviction(
|
|
605
|
+
core: *mut tmprl_core_t,
|
|
606
|
+
req_proto: *const u8,
|
|
607
|
+
req_proto_len: libc::size_t,
|
|
608
|
+
user_data: *mut libc::c_void,
|
|
609
|
+
callback: tmprl_callback,
|
|
610
|
+
) {
|
|
611
|
+
let core = unsafe { &mut *core };
|
|
612
|
+
let req = match tmprl_core_t::decode_proto::<bridge::RequestWorkflowEvictionRequest>(
|
|
613
|
+
req_proto,
|
|
614
|
+
req_proto_len,
|
|
615
|
+
) {
|
|
616
|
+
Ok(req) => req,
|
|
617
|
+
Err(message) => {
|
|
618
|
+
let resp = bridge::RequestWorkflowEvictionResponse {
|
|
619
|
+
error: Some(bridge::request_workflow_eviction_response::Error { message }),
|
|
620
|
+
};
|
|
621
|
+
unsafe {
|
|
622
|
+
callback(user_data, core.encode_proto(&resp).into_raw());
|
|
623
|
+
}
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
let user_data = UserDataHandle(user_data);
|
|
628
|
+
// We intentionally spawn even though the core call is not async so the
|
|
629
|
+
// callback can be made in the tokio runtime
|
|
630
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
631
|
+
core.request_workflow_eviction(req);
|
|
632
|
+
unsafe {
|
|
633
|
+
callback(
|
|
634
|
+
user_data.into(),
|
|
635
|
+
&*DEFAULT_REQUEST_WORKFLOW_EVICTION_RESPONSE_BYTES,
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/// Fetch buffered logs.
|
|
642
|
+
///
|
|
643
|
+
/// The req_proto and req_proto_len represent a byte array for a
|
|
644
|
+
/// FetchBufferedLogsRequest protobuf message. The callback is invoked
|
|
645
|
+
/// on completion with a FetchBufferedLogsResponse protobuf message.
|
|
646
|
+
#[no_mangle]
|
|
647
|
+
pub extern "C" fn tmprl_fetch_buffered_logs(
|
|
648
|
+
core: *mut tmprl_core_t,
|
|
649
|
+
#[allow(unused_variables)] // We intentionally ignore the request
|
|
650
|
+
req_proto: *const u8,
|
|
651
|
+
#[allow(unused_variables)] req_proto_len: libc::size_t,
|
|
652
|
+
user_data: *mut libc::c_void,
|
|
653
|
+
callback: tmprl_callback,
|
|
654
|
+
) {
|
|
655
|
+
let core = unsafe { &mut *core };
|
|
656
|
+
let user_data = UserDataHandle(user_data);
|
|
657
|
+
// We intentionally spawn even though the core call is not async so the
|
|
658
|
+
// callback can be made in the tokio runtime
|
|
659
|
+
core.tokio_runtime.clone().spawn(async move {
|
|
660
|
+
let resp = core.fetch_buffered_logs();
|
|
661
|
+
unsafe { callback(user_data.into(), core.encode_proto(&resp).into_raw()) };
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
impl tmprl_core_t {
|
|
666
|
+
async fn new(
|
|
667
|
+
tokio_runtime: std::sync::Arc<tokio::runtime::Runtime>,
|
|
668
|
+
opts: wrappers::CoreInitOptions,
|
|
669
|
+
) -> Result<tmprl_core_t, String> {
|
|
670
|
+
Ok(tmprl_core_t {
|
|
671
|
+
tokio_runtime,
|
|
672
|
+
core: std::sync::Arc::new(
|
|
673
|
+
temporal_sdk_core::init(opts.try_into()?)
|
|
674
|
+
.await
|
|
675
|
+
.map_err(|err| format!("failed initializing: {}", err))?,
|
|
676
|
+
),
|
|
677
|
+
})
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
async fn shutdown(&self) {
|
|
681
|
+
self.core.shutdown().await;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
fn register_worker(
|
|
685
|
+
&self,
|
|
686
|
+
config: wrappers::WorkerConfig,
|
|
687
|
+
) -> Result<(), bridge::register_worker_response::Error> {
|
|
688
|
+
let config =
|
|
689
|
+
config
|
|
690
|
+
.try_into()
|
|
691
|
+
.map_err(|message| bridge::register_worker_response::Error {
|
|
692
|
+
message,
|
|
693
|
+
worker_already_registered: false,
|
|
694
|
+
})?;
|
|
695
|
+
self.core.register_worker(config).map_err(|err| {
|
|
696
|
+
bridge::register_worker_response::Error {
|
|
697
|
+
message: format!("{}", err),
|
|
698
|
+
worker_already_registered: matches!(
|
|
699
|
+
err,
|
|
700
|
+
temporal_sdk_core_api::errors::WorkerRegistrationError::WorkerAlreadyRegisteredForQueue(_),
|
|
701
|
+
),
|
|
702
|
+
}
|
|
703
|
+
})
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
async fn shutdown_worker(&self, req: bridge::ShutdownWorkerRequest) {
|
|
707
|
+
self.core.shutdown_worker(&req.task_queue).await;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
async fn poll_workflow_activation(
|
|
711
|
+
&self,
|
|
712
|
+
req: bridge::PollWorkflowActivationRequest,
|
|
713
|
+
) -> Result<
|
|
714
|
+
temporal_sdk_core_protos::coresdk::workflow_activation::WorkflowActivation,
|
|
715
|
+
bridge::poll_workflow_activation_response::Error,
|
|
716
|
+
> {
|
|
717
|
+
self.core
|
|
718
|
+
.poll_workflow_activation(&req.task_queue)
|
|
719
|
+
.await
|
|
720
|
+
.map_err(|err| bridge::poll_workflow_activation_response::Error {
|
|
721
|
+
message: format!("{}", err),
|
|
722
|
+
shutdown: matches!(err, temporal_sdk_core_api::errors::PollWfError::ShutDown),
|
|
723
|
+
})
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
async fn poll_activity_task(
|
|
727
|
+
&self,
|
|
728
|
+
req: bridge::PollActivityTaskRequest,
|
|
729
|
+
) -> Result<
|
|
730
|
+
temporal_sdk_core_protos::coresdk::activity_task::ActivityTask,
|
|
731
|
+
bridge::poll_activity_task_response::Error,
|
|
732
|
+
> {
|
|
733
|
+
self.core
|
|
734
|
+
.poll_activity_task(&req.task_queue)
|
|
735
|
+
.await
|
|
736
|
+
.map_err(|err| bridge::poll_activity_task_response::Error {
|
|
737
|
+
message: format!("{}", err),
|
|
738
|
+
shutdown: matches!(
|
|
739
|
+
err,
|
|
740
|
+
temporal_sdk_core_api::errors::PollActivityError::ShutDown
|
|
741
|
+
),
|
|
742
|
+
})
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
async fn complete_workflow_activation(
|
|
746
|
+
&self,
|
|
747
|
+
req: bridge::CompleteWorkflowActivationRequest,
|
|
748
|
+
) -> Result<(), bridge::complete_workflow_activation_response::Error> {
|
|
749
|
+
self.core
|
|
750
|
+
.complete_workflow_activation(req.completion.unwrap_or_default())
|
|
751
|
+
.await
|
|
752
|
+
.map_err(|err| bridge::complete_workflow_activation_response::Error {
|
|
753
|
+
message: format!("{}", err),
|
|
754
|
+
})
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
async fn complete_activity_task(
|
|
758
|
+
&self,
|
|
759
|
+
req: bridge::CompleteActivityTaskRequest,
|
|
760
|
+
) -> Result<(), bridge::complete_activity_task_response::Error> {
|
|
761
|
+
self.core
|
|
762
|
+
.complete_activity_task(req.completion.unwrap_or_default())
|
|
763
|
+
.await
|
|
764
|
+
.map_err(|err| bridge::complete_activity_task_response::Error {
|
|
765
|
+
message: format!("{}", err),
|
|
766
|
+
})
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
fn record_activity_heartbeat(&self, req: bridge::RecordActivityHeartbeatRequest) {
|
|
770
|
+
self.core
|
|
771
|
+
.record_activity_heartbeat(req.heartbeat.unwrap_or_default());
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
fn request_workflow_eviction(&self, req: bridge::RequestWorkflowEvictionRequest) {
|
|
775
|
+
self.core
|
|
776
|
+
.request_workflow_eviction(&req.task_queue, &req.run_id);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
fn fetch_buffered_logs(&self) -> bridge::FetchBufferedLogsResponse {
|
|
780
|
+
bridge::FetchBufferedLogsResponse {
|
|
781
|
+
entries: self
|
|
782
|
+
.core
|
|
783
|
+
.fetch_buffered_logs()
|
|
784
|
+
.into_iter()
|
|
785
|
+
.map(|log| bridge::fetch_buffered_logs_response::LogEntry {
|
|
786
|
+
message: log.message,
|
|
787
|
+
timestamp: Some(log.timestamp.into()),
|
|
788
|
+
level: match log.level {
|
|
789
|
+
log::Level::Error => bridge::LogLevel::Error.into(),
|
|
790
|
+
log::Level::Warn => bridge::LogLevel::Warn.into(),
|
|
791
|
+
log::Level::Info => bridge::LogLevel::Info.into(),
|
|
792
|
+
log::Level::Debug => bridge::LogLevel::Debug.into(),
|
|
793
|
+
log::Level::Trace => bridge::LogLevel::Trace.into(),
|
|
794
|
+
},
|
|
795
|
+
})
|
|
796
|
+
.collect(),
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
fn borrow_buf(&mut self) -> Vec<u8> {
|
|
801
|
+
// We currently do not use a thread-safe byte pool, but if wanted, it
|
|
802
|
+
// can be added here
|
|
803
|
+
Vec::new()
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
fn return_buf(&mut self, _vec: Vec<u8>) {
|
|
807
|
+
// We currently do not use a thread-safe byte pool, but if wanted, it
|
|
808
|
+
// can be added here
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
fn encode_proto(&mut self, proto: &impl prost::Message) -> tmprl_bytes_t {
|
|
812
|
+
let mut buf = self.borrow_buf();
|
|
813
|
+
buf.clear();
|
|
814
|
+
// Increase buf capacity if needed
|
|
815
|
+
buf.reserve(proto.encoded_len());
|
|
816
|
+
// Only fails if size not big enough which can't happen in our case
|
|
817
|
+
proto.encode(&mut buf).unwrap();
|
|
818
|
+
tmprl_bytes_t::from_vec(buf)
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
fn decode_proto<P>(bytes: *const u8, bytes_len: libc::size_t) -> Result<P, String>
|
|
822
|
+
where
|
|
823
|
+
P: prost::Message,
|
|
824
|
+
P: Default,
|
|
825
|
+
{
|
|
826
|
+
P::decode(unsafe { std::slice::from_raw_parts(bytes, bytes_len) })
|
|
827
|
+
.map_err(|err| format!("failed decoding proto: {}", err))
|
|
828
|
+
}
|
|
829
|
+
}
|