@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.
Files changed (170) hide show
  1. package/Cargo.lock +339 -226
  2. package/Cargo.toml +7 -3
  3. package/common.js +50 -0
  4. package/index.d.ts +7 -0
  5. package/index.js +12 -0
  6. package/package.json +7 -4
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/{index.node → releases/index.node} +0 -0
  10. package/releases/x86_64-apple-darwin/index.node +0 -0
  11. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  12. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  13. package/scripts/build.js +10 -50
  14. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  15. package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
  16. package/sdk-core/.buildkite/pipeline.yml +2 -0
  17. package/sdk-core/Cargo.toml +1 -88
  18. package/sdk-core/README.md +30 -6
  19. package/sdk-core/bridge-ffi/Cargo.toml +24 -0
  20. package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
  21. package/sdk-core/bridge-ffi/build.rs +25 -0
  22. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
  23. package/sdk-core/bridge-ffi/src/lib.rs +829 -0
  24. package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
  25. package/sdk-core/client/Cargo.toml +32 -0
  26. package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
  27. package/sdk-core/client/src/metrics.rs +89 -0
  28. package/sdk-core/client/src/mocks.rs +167 -0
  29. package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
  30. package/sdk-core/core/Cargo.toml +96 -0
  31. package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
  32. package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
  33. package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
  34. package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
  35. package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
  36. package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
  37. package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
  38. package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
  39. package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
  40. package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
  41. package/sdk-core/core/src/lib.rs +374 -0
  42. package/sdk-core/{src → core/src}/log_export.rs +3 -27
  43. package/sdk-core/core/src/pending_activations.rs +162 -0
  44. package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
  45. package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
  46. package/sdk-core/core/src/protosext/mod.rs +396 -0
  47. package/sdk-core/core/src/replay/mod.rs +210 -0
  48. package/sdk-core/core/src/retry_logic.rs +144 -0
  49. package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
  50. package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
  51. package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
  52. package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
  53. package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
  55. package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
  56. package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
  57. package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
  58. package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
  59. package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
  60. package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
  61. package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
  62. package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
  63. package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
  64. package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
  65. package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
  66. package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
  67. package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
  68. package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
  69. package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
  70. package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
  71. package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
  72. package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
  73. package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
  74. package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
  75. package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
  76. package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
  77. package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
  78. package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
  79. package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
  80. package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
  81. package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
  82. package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
  83. package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
  84. package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
  85. package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
  86. package/sdk-core/{src → core-api/src}/errors.rs +42 -92
  87. package/sdk-core/core-api/src/lib.rs +158 -0
  88. package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
  89. package/sdk-core/etc/deps.svg +156 -0
  90. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
  92. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
  93. package/sdk-core/histories/fail_wf_task.bin +0 -0
  94. package/sdk-core/histories/timer_workflow_history.bin +0 -0
  95. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
  96. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
  97. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
  98. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
  99. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
  100. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
  101. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
  102. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
  103. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
  104. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  105. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
  106. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
  107. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
  108. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
  109. package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  110. package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
  111. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
  112. package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
  113. package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
  114. package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
  115. package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
  116. package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  117. package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
  118. package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
  119. package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
  120. package/sdk-core/sdk/Cargo.toml +32 -0
  121. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
  122. package/sdk-core/sdk/src/lib.rs +699 -0
  123. package/sdk-core/sdk/src/payload_converter.rs +11 -0
  124. package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
  125. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
  126. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
  127. package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
  128. package/sdk-core/sdk-core-protos/build.rs +28 -6
  129. package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  130. package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
  131. package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
  132. package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
  133. package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  134. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  135. package/sdk-core/test-utils/Cargo.toml +32 -0
  136. package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
  137. package/sdk-core/test-utils/src/histfetch.rs +28 -0
  138. package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
  139. package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
  140. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
  141. package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
  142. package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
  143. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
  144. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
  145. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
  146. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
  147. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
  148. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
  149. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
  150. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
  151. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
  152. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
  153. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
  154. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
  155. package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
  156. package/sdk-core/tests/load_tests.rs +6 -6
  157. package/sdk-core/tests/main.rs +2 -2
  158. package/src/conversions.rs +24 -21
  159. package/src/errors.rs +8 -0
  160. package/src/lib.rs +323 -211
  161. package/sdk-core/protos/local/activity_result.proto +0 -46
  162. package/sdk-core/protos/local/activity_task.proto +0 -66
  163. package/sdk-core/src/core_tests/retry.rs +0 -147
  164. package/sdk-core/src/lib.rs +0 -403
  165. package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
  166. package/sdk-core/src/pending_activations.rs +0 -249
  167. package/sdk-core/src/protosext/mod.rs +0 -160
  168. package/sdk-core/src/prototype_rust_sdk.rs +0 -412
  169. package/sdk-core/src/task_token.rs +0 -20
  170. 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
+ }