@temporalio/core-bridge 1.13.0 → 1.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +239 -382
- package/Cargo.toml +11 -11
- package/lib/native.d.ts +10 -3
- package/package.json +3 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.cargo/config.toml +71 -11
- package/sdk-core/.clippy.toml +1 -0
- package/sdk-core/.github/workflows/heavy.yml +2 -0
- package/sdk-core/.github/workflows/per-pr.yml +50 -18
- package/sdk-core/ARCHITECTURE.md +44 -48
- package/sdk-core/Cargo.toml +26 -7
- package/sdk-core/README.md +4 -0
- package/sdk-core/arch_docs/diagrams/TimerMachine_Coverage.puml +14 -0
- package/sdk-core/arch_docs/diagrams/initial_event_history.png +0 -0
- package/sdk-core/arch_docs/sdks_intro.md +299 -0
- package/sdk-core/client/Cargo.toml +8 -7
- package/sdk-core/client/src/callback_based.rs +1 -2
- package/sdk-core/client/src/lib.rs +485 -299
- package/sdk-core/client/src/metrics.rs +32 -8
- package/sdk-core/client/src/proxy.rs +124 -5
- package/sdk-core/client/src/raw.rs +598 -307
- package/sdk-core/client/src/replaceable.rs +253 -0
- package/sdk-core/client/src/retry.rs +9 -6
- package/sdk-core/client/src/worker_registry/mod.rs +19 -3
- package/sdk-core/client/src/workflow_handle/mod.rs +20 -17
- package/sdk-core/core/Cargo.toml +100 -31
- package/sdk-core/core/src/core_tests/activity_tasks.rs +55 -225
- package/sdk-core/core/src/core_tests/mod.rs +2 -8
- package/sdk-core/core/src/core_tests/queries.rs +3 -5
- package/sdk-core/core/src/core_tests/replay_flag.rs +3 -62
- package/sdk-core/core/src/core_tests/updates.rs +4 -5
- package/sdk-core/core/src/core_tests/workers.rs +4 -3
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +10 -7
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +28 -291
- package/sdk-core/core/src/ephemeral_server/mod.rs +15 -3
- package/sdk-core/core/src/internal_flags.rs +11 -1
- package/sdk-core/core/src/lib.rs +50 -36
- package/sdk-core/core/src/pollers/mod.rs +5 -5
- package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
- package/sdk-core/core/src/protosext/mod.rs +13 -5
- package/sdk-core/core/src/protosext/protocol_messages.rs +4 -11
- package/sdk-core/core/src/retry_logic.rs +256 -108
- package/sdk-core/core/src/telemetry/metrics.rs +1 -0
- package/sdk-core/core/src/telemetry/mod.rs +8 -2
- package/sdk-core/core/src/telemetry/prometheus_meter.rs +2 -2
- package/sdk-core/core/src/test_help/integ_helpers.rs +971 -0
- package/sdk-core/core/src/test_help/mod.rs +10 -1100
- package/sdk-core/core/src/test_help/unit_helpers.rs +218 -0
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +42 -6
- package/sdk-core/core/src/worker/activities/local_activities.rs +19 -19
- package/sdk-core/core/src/worker/activities.rs +10 -3
- package/sdk-core/core/src/worker/client/mocks.rs +3 -3
- package/sdk-core/core/src/worker/client.rs +130 -93
- package/sdk-core/core/src/worker/heartbeat.rs +12 -13
- package/sdk-core/core/src/worker/mod.rs +31 -21
- package/sdk-core/core/src/worker/nexus.rs +14 -3
- package/sdk-core/core/src/worker/slot_provider.rs +9 -0
- package/sdk-core/core/src/worker/tuner.rs +159 -0
- package/sdk-core/core/src/worker/workflow/history_update.rs +3 -265
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -54
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -82
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -67
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -192
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -43
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +6 -554
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -71
- package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +102 -3
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +10 -539
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -139
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -119
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -63
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +9 -4
- package/sdk-core/core/src/worker/workflow/mod.rs +5 -1
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +8 -3
- package/sdk-core/core-api/Cargo.toml +4 -4
- package/sdk-core/core-api/src/envconfig.rs +153 -54
- package/sdk-core/core-api/src/lib.rs +68 -0
- package/sdk-core/core-api/src/telemetry/metrics.rs +2 -1
- package/sdk-core/core-api/src/telemetry.rs +13 -0
- package/sdk-core/core-c-bridge/Cargo.toml +13 -8
- package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +184 -22
- package/sdk-core/core-c-bridge/src/client.rs +462 -184
- package/sdk-core/core-c-bridge/src/envconfig.rs +314 -0
- package/sdk-core/core-c-bridge/src/lib.rs +1 -0
- package/sdk-core/core-c-bridge/src/random.rs +4 -4
- package/sdk-core/core-c-bridge/src/runtime.rs +22 -23
- package/sdk-core/core-c-bridge/src/testing.rs +1 -4
- package/sdk-core/core-c-bridge/src/tests/context.rs +31 -31
- package/sdk-core/core-c-bridge/src/tests/mod.rs +32 -28
- package/sdk-core/core-c-bridge/src/tests/utils.rs +7 -7
- package/sdk-core/core-c-bridge/src/worker.rs +319 -66
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -1
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +5 -5
- package/sdk-core/sdk/Cargo.toml +8 -2
- package/sdk-core/sdk/src/activity_context.rs +1 -1
- package/sdk-core/sdk/src/app_data.rs +1 -1
- package/sdk-core/sdk/src/interceptors.rs +1 -4
- package/sdk-core/sdk/src/lib.rs +1 -5
- package/sdk-core/sdk/src/workflow_context/options.rs +10 -1
- package/sdk-core/sdk/src/workflow_future.rs +1 -1
- package/sdk-core/sdk-core-protos/Cargo.toml +6 -6
- package/sdk-core/sdk-core-protos/build.rs +10 -23
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/create-release.yml +9 -1
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +254 -5
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +234 -5
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +1 -1
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +6 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +60 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -6
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
- package/sdk-core/{test-utils → sdk-core-protos}/src/canned_histories.rs +5 -5
- package/sdk-core/sdk-core-protos/src/history_builder.rs +2 -2
- package/sdk-core/sdk-core-protos/src/lib.rs +25 -9
- package/sdk-core/sdk-core-protos/src/test_utils.rs +89 -0
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -5
- package/sdk-core/tests/c_bridge_smoke_test.c +10 -0
- package/sdk-core/tests/cloud_tests.rs +10 -8
- package/sdk-core/tests/common/http_proxy.rs +134 -0
- package/sdk-core/{test-utils/src/lib.rs → tests/common/mod.rs} +214 -281
- package/sdk-core/{test-utils/src → tests/common}/workflows.rs +4 -3
- package/sdk-core/tests/fuzzy_workflow.rs +1 -1
- package/sdk-core/tests/global_metric_tests.rs +8 -7
- package/sdk-core/tests/heavy_tests.rs +7 -3
- package/sdk-core/tests/integ_tests/client_tests.rs +111 -24
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +14 -9
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +4 -4
- package/sdk-core/tests/integ_tests/metrics_tests.rs +114 -14
- package/sdk-core/tests/integ_tests/pagination_tests.rs +273 -0
- package/sdk-core/tests/integ_tests/polling_tests.rs +311 -93
- package/sdk-core/tests/integ_tests/queries_tests.rs +4 -4
- package/sdk-core/tests/integ_tests/update_tests.rs +13 -7
- package/sdk-core/tests/integ_tests/visibility_tests.rs +26 -9
- package/sdk-core/tests/integ_tests/worker_tests.rs +668 -13
- package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +40 -24
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +244 -11
- package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +78 -2
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +61 -2
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +465 -7
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +41 -2
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +315 -3
- package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1990 -14
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +65 -2
- package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +123 -23
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +525 -3
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +65 -16
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +32 -23
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +126 -5
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +1 -2
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +124 -8
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +62 -2
- package/sdk-core/tests/integ_tests/workflow_tests.rs +67 -8
- package/sdk-core/tests/main.rs +26 -17
- package/sdk-core/tests/manual_tests.rs +5 -1
- package/sdk-core/tests/runner.rs +22 -40
- package/sdk-core/tests/shared_tests/mod.rs +1 -1
- package/sdk-core/tests/shared_tests/priority.rs +1 -1
- package/sdk-core/{core/benches/workflow_replay.rs → tests/workflow_replay_bench.rs} +10 -5
- package/src/client.rs +97 -20
- package/src/helpers/callbacks.rs +4 -4
- package/src/helpers/errors.rs +7 -1
- package/src/helpers/handles.rs +1 -0
- package/src/helpers/try_from_js.rs +4 -3
- package/src/lib.rs +3 -2
- package/src/metrics.rs +3 -0
- package/src/runtime.rs +5 -2
- package/src/worker.rs +9 -12
- package/ts/native.ts +13 -3
- package/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
- package/sdk-core/core/src/core_tests/child_workflows.rs +0 -281
- package/sdk-core/core/src/core_tests/determinism.rs +0 -318
- package/sdk-core/core/src/core_tests/local_activities.rs +0 -1442
- package/sdk-core/test-utils/Cargo.toml +0 -38
- package/sdk-core/test-utils/src/histfetch.rs +0 -28
- package/sdk-core/test-utils/src/interceptors.rs +0 -46
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
use crate::{ByteArray, ByteArrayRef};
|
|
2
|
+
use serde::Serialize;
|
|
3
|
+
use std::collections::HashMap;
|
|
4
|
+
use temporal_sdk_core_api::envconfig::{
|
|
5
|
+
self, ClientConfig as CoreClientConfig, ClientConfigCodec as CoreClientConfigCodec,
|
|
6
|
+
ClientConfigProfile as CoreClientConfigProfile, ClientConfigTLS as CoreClientConfigTLS,
|
|
7
|
+
DataSource as CoreDataSource, LoadClientConfigOptions, LoadClientConfigProfileOptions,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/// OrFail result for client config loading operations.
|
|
11
|
+
/// Either success or fail will be null, but never both.
|
|
12
|
+
/// If success is not null, it contains JSON-serialized client configuration data.
|
|
13
|
+
/// If fail is not null, it contains UTF-8 encoded error message.
|
|
14
|
+
/// The returned ByteArrays must be freed by the caller.
|
|
15
|
+
#[repr(C)]
|
|
16
|
+
pub struct ClientEnvConfigOrFail {
|
|
17
|
+
pub success: *const ByteArray,
|
|
18
|
+
pub fail: *const ByteArray,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// OrFail result for client config profile loading operations.
|
|
22
|
+
/// Either success or fail will be null, but never both.
|
|
23
|
+
/// If success is not null, it contains JSON-serialized client configuration profile data.
|
|
24
|
+
/// If fail is not null, it contains UTF-8 encoded error message.
|
|
25
|
+
/// The returned ByteArrays must be freed by the caller.
|
|
26
|
+
#[repr(C)]
|
|
27
|
+
pub struct ClientEnvConfigProfileOrFail {
|
|
28
|
+
pub success: *const ByteArray,
|
|
29
|
+
pub fail: *const ByteArray,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Options for loading client configuration.
|
|
33
|
+
#[repr(C)]
|
|
34
|
+
pub struct ClientEnvConfigLoadOptions {
|
|
35
|
+
pub path: ByteArrayRef,
|
|
36
|
+
pub data: ByteArrayRef,
|
|
37
|
+
pub config_file_strict: bool,
|
|
38
|
+
pub env_vars: ByteArrayRef,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// Options for loading a specific client configuration profile.
|
|
42
|
+
#[repr(C)]
|
|
43
|
+
pub struct ClientEnvConfigProfileLoadOptions {
|
|
44
|
+
pub profile: ByteArrayRef,
|
|
45
|
+
pub path: ByteArrayRef,
|
|
46
|
+
pub data: ByteArrayRef,
|
|
47
|
+
pub disable_file: bool,
|
|
48
|
+
pub disable_env: bool,
|
|
49
|
+
pub config_file_strict: bool,
|
|
50
|
+
pub env_vars: ByteArrayRef,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Wrapper types for JSON serialization
|
|
54
|
+
#[derive(Serialize)]
|
|
55
|
+
struct ClientEnvConfig {
|
|
56
|
+
profiles: HashMap<String, ClientEnvConfigProfile>,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
impl From<CoreClientConfig> for ClientEnvConfig {
|
|
60
|
+
fn from(c: CoreClientConfig) -> Self {
|
|
61
|
+
Self {
|
|
62
|
+
profiles: c.profiles.into_iter().map(|(k, v)| (k, v.into())).collect(),
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#[derive(Serialize)]
|
|
68
|
+
struct ClientEnvConfigProfile {
|
|
69
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
70
|
+
address: Option<String>,
|
|
71
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
72
|
+
namespace: Option<String>,
|
|
73
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
74
|
+
api_key: Option<String>,
|
|
75
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
76
|
+
tls: Option<ClientEnvConfigTLS>,
|
|
77
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
78
|
+
codec: Option<ClientEnvConfigCodec>,
|
|
79
|
+
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
|
80
|
+
grpc_meta: HashMap<String, String>,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
impl From<CoreClientConfigProfile> for ClientEnvConfigProfile {
|
|
84
|
+
fn from(c: CoreClientConfigProfile) -> Self {
|
|
85
|
+
Self {
|
|
86
|
+
address: c.address,
|
|
87
|
+
namespace: c.namespace,
|
|
88
|
+
api_key: c.api_key,
|
|
89
|
+
tls: c.tls.map(Into::into),
|
|
90
|
+
codec: c.codec.map(Into::into),
|
|
91
|
+
grpc_meta: c.grpc_meta,
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
#[derive(Serialize)]
|
|
97
|
+
struct ClientEnvConfigTLS {
|
|
98
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
99
|
+
disabled: Option<bool>,
|
|
100
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
101
|
+
server_name: Option<String>,
|
|
102
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
103
|
+
server_ca_cert: Option<DataSource>,
|
|
104
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
105
|
+
client_cert: Option<DataSource>,
|
|
106
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
107
|
+
client_key: Option<DataSource>,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
impl From<CoreClientConfigTLS> for ClientEnvConfigTLS {
|
|
111
|
+
fn from(c: CoreClientConfigTLS) -> Self {
|
|
112
|
+
Self {
|
|
113
|
+
disabled: c.disabled,
|
|
114
|
+
server_name: c.server_name,
|
|
115
|
+
server_ca_cert: c.server_ca_cert.map(Into::into),
|
|
116
|
+
client_cert: c.client_cert.map(Into::into),
|
|
117
|
+
client_key: c.client_key.map(Into::into),
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#[derive(Serialize)]
|
|
123
|
+
struct ClientEnvConfigCodec {
|
|
124
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
125
|
+
endpoint: Option<String>,
|
|
126
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
127
|
+
auth: Option<String>,
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
impl From<CoreClientConfigCodec> for ClientEnvConfigCodec {
|
|
131
|
+
fn from(c: CoreClientConfigCodec) -> Self {
|
|
132
|
+
Self {
|
|
133
|
+
endpoint: c.endpoint,
|
|
134
|
+
auth: c.auth,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#[derive(Serialize)]
|
|
140
|
+
struct DataSource {
|
|
141
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
142
|
+
path: Option<String>,
|
|
143
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
144
|
+
data: Option<Vec<u8>>,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
impl From<CoreDataSource> for DataSource {
|
|
148
|
+
fn from(c: CoreDataSource) -> Self {
|
|
149
|
+
match c {
|
|
150
|
+
CoreDataSource::Path(p) => Self {
|
|
151
|
+
path: Some(p),
|
|
152
|
+
data: None,
|
|
153
|
+
},
|
|
154
|
+
CoreDataSource::Data(d) => Self {
|
|
155
|
+
path: None,
|
|
156
|
+
data: Some(d),
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Helper functions
|
|
163
|
+
fn parse_config_source(
|
|
164
|
+
path: &ByteArrayRef,
|
|
165
|
+
data: &ByteArrayRef,
|
|
166
|
+
) -> Result<Option<CoreDataSource>, String> {
|
|
167
|
+
if !path.data.is_null() && path.size > 0 {
|
|
168
|
+
Ok(Some(CoreDataSource::Path(path.to_string())))
|
|
169
|
+
} else if !data.data.is_null() && data.size > 0 {
|
|
170
|
+
Ok(Some(CoreDataSource::Data(data.to_vec())))
|
|
171
|
+
} else {
|
|
172
|
+
Ok(None)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
fn parse_env_vars(env_vars: &ByteArrayRef) -> Result<Option<HashMap<String, String>>, String> {
|
|
177
|
+
if env_vars.data.is_null() || env_vars.size == 0 {
|
|
178
|
+
return Ok(None);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
let env_json = std::str::from_utf8(env_vars.to_slice())
|
|
182
|
+
.map_err(|e| format!("Invalid env vars UTF-8: {e}"))?;
|
|
183
|
+
|
|
184
|
+
serde_json::from_str(env_json)
|
|
185
|
+
.map(Some)
|
|
186
|
+
.map_err(|e| format!("Invalid env vars JSON: {e}"))
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Simple helper to handle serialization errors consistently
|
|
190
|
+
fn serialize_or_error<T: Serialize>(data: T) -> Result<*const ByteArray, *const ByteArray> {
|
|
191
|
+
match serde_json::to_vec(&data) {
|
|
192
|
+
Ok(json_bytes) => {
|
|
193
|
+
let result = ByteArray::from_vec(json_bytes);
|
|
194
|
+
Ok(result.into_raw())
|
|
195
|
+
}
|
|
196
|
+
Err(e) => {
|
|
197
|
+
let err = ByteArray::from_utf8(format!("Failed to serialize: {e}"));
|
|
198
|
+
Err(err.into_raw())
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/// Load all client profiles from given sources.
|
|
204
|
+
/// Returns ClientConfigOrFail with either success JSON or error message.
|
|
205
|
+
/// The returned ByteArrays must be freed by the caller.
|
|
206
|
+
#[unsafe(no_mangle)]
|
|
207
|
+
pub extern "C" fn temporal_core_client_env_config_load(
|
|
208
|
+
options: *const ClientEnvConfigLoadOptions,
|
|
209
|
+
) -> ClientEnvConfigOrFail {
|
|
210
|
+
if options.is_null() {
|
|
211
|
+
let err = ByteArray::from_utf8("Options cannot be null".to_string());
|
|
212
|
+
return ClientEnvConfigOrFail {
|
|
213
|
+
success: std::ptr::null(),
|
|
214
|
+
fail: err.into_raw(),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
let result = || -> Result<ClientEnvConfig, String> {
|
|
219
|
+
let opts = unsafe { &*options };
|
|
220
|
+
let env_vars_map = parse_env_vars(&opts.env_vars)?;
|
|
221
|
+
|
|
222
|
+
let load_options = LoadClientConfigOptions {
|
|
223
|
+
config_source: parse_config_source(&opts.path, &opts.data)?,
|
|
224
|
+
config_file_strict: opts.config_file_strict,
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
let core_config = envconfig::load_client_config(load_options, env_vars_map.as_ref())
|
|
228
|
+
.map_err(|e| e.to_string())?;
|
|
229
|
+
|
|
230
|
+
Ok(core_config.into())
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
match result() {
|
|
234
|
+
Ok(data) => match serialize_or_error(data) {
|
|
235
|
+
Ok(success) => ClientEnvConfigOrFail {
|
|
236
|
+
success,
|
|
237
|
+
fail: std::ptr::null(),
|
|
238
|
+
},
|
|
239
|
+
Err(fail) => ClientEnvConfigOrFail {
|
|
240
|
+
success: std::ptr::null(),
|
|
241
|
+
fail,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
Err(e) => {
|
|
245
|
+
let err = ByteArray::from_utf8(e);
|
|
246
|
+
ClientEnvConfigOrFail {
|
|
247
|
+
success: std::ptr::null(),
|
|
248
|
+
fail: err.into_raw(),
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/// Load a single client profile from given sources with env overrides.
|
|
255
|
+
/// Returns ClientConfigProfileOrFail with either success JSON or error message.
|
|
256
|
+
/// The returned ByteArrays must be freed by the caller.
|
|
257
|
+
#[unsafe(no_mangle)]
|
|
258
|
+
pub extern "C" fn temporal_core_client_env_config_profile_load(
|
|
259
|
+
options: *const ClientEnvConfigProfileLoadOptions,
|
|
260
|
+
) -> ClientEnvConfigProfileOrFail {
|
|
261
|
+
if options.is_null() {
|
|
262
|
+
let err = ByteArray::from_utf8("Options cannot be null".to_string());
|
|
263
|
+
return ClientEnvConfigProfileOrFail {
|
|
264
|
+
success: std::ptr::null(),
|
|
265
|
+
fail: err.into_raw(),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
let result = || -> Result<ClientEnvConfigProfile, String> {
|
|
270
|
+
let opts = unsafe { &*options };
|
|
271
|
+
|
|
272
|
+
let profile_name = if !opts.profile.data.is_null() && opts.profile.size > 0 {
|
|
273
|
+
Some(opts.profile.to_string())
|
|
274
|
+
} else {
|
|
275
|
+
None
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
let config_source = parse_config_source(&opts.path, &opts.data)?;
|
|
279
|
+
let env_vars_map = parse_env_vars(&opts.env_vars)?;
|
|
280
|
+
|
|
281
|
+
let load_options = LoadClientConfigProfileOptions {
|
|
282
|
+
config_source,
|
|
283
|
+
config_file_profile: profile_name,
|
|
284
|
+
config_file_strict: opts.config_file_strict,
|
|
285
|
+
disable_file: opts.disable_file,
|
|
286
|
+
disable_env: opts.disable_env,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
let profile = envconfig::load_client_config_profile(load_options, env_vars_map.as_ref())
|
|
290
|
+
.map_err(|e| e.to_string())?;
|
|
291
|
+
|
|
292
|
+
Ok(profile.into())
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
match result() {
|
|
296
|
+
Ok(data) => match serialize_or_error(data) {
|
|
297
|
+
Ok(success) => ClientEnvConfigProfileOrFail {
|
|
298
|
+
success,
|
|
299
|
+
fail: std::ptr::null(),
|
|
300
|
+
},
|
|
301
|
+
Err(fail) => ClientEnvConfigProfileOrFail {
|
|
302
|
+
success: std::ptr::null(),
|
|
303
|
+
fail,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
Err(e) => {
|
|
307
|
+
let err = ByteArray::from_utf8(e);
|
|
308
|
+
ClientEnvConfigProfileOrFail {
|
|
309
|
+
success: std::ptr::null(),
|
|
310
|
+
fail: err.into_raw(),
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -32,9 +32,9 @@ pub extern "C" fn temporal_core_random_int32_range(
|
|
|
32
32
|
) -> i32 {
|
|
33
33
|
let random = unsafe { &mut *random };
|
|
34
34
|
if max_inclusive {
|
|
35
|
-
random.rand.
|
|
35
|
+
random.rand.random_range(min..=max)
|
|
36
36
|
} else {
|
|
37
|
-
random.rand.
|
|
37
|
+
random.rand.random_range(min..max)
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -47,9 +47,9 @@ pub extern "C" fn temporal_core_random_double_range(
|
|
|
47
47
|
) -> f64 {
|
|
48
48
|
let random = unsafe { &mut *random };
|
|
49
49
|
if max_inclusive {
|
|
50
|
-
random.rand.
|
|
50
|
+
random.rand.random_range(min..=max)
|
|
51
51
|
} else {
|
|
52
|
-
random.rand.
|
|
52
|
+
random.rand.random_range(min..max)
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -1,29 +1,28 @@
|
|
|
1
|
-
use crate::
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
use crate::metric::CustomMetricMeterRef;
|
|
1
|
+
use crate::{
|
|
2
|
+
ByteArray, ByteArrayRef, MetadataRef,
|
|
3
|
+
metric::{CustomMetricMeter, CustomMetricMeterRef},
|
|
4
|
+
};
|
|
6
5
|
|
|
7
6
|
use serde_json::json;
|
|
8
|
-
use std::
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
use temporal_sdk_core::
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
use temporal_sdk_core_api::telemetry::{CoreLog, CoreLogConsumer};
|
|
7
|
+
use std::{
|
|
8
|
+
collections::HashMap,
|
|
9
|
+
fmt,
|
|
10
|
+
net::SocketAddr,
|
|
11
|
+
str::FromStr,
|
|
12
|
+
sync::{
|
|
13
|
+
Arc, Mutex,
|
|
14
|
+
atomic::{AtomicBool, Ordering},
|
|
15
|
+
},
|
|
16
|
+
time::{Duration, UNIX_EPOCH},
|
|
17
|
+
};
|
|
18
|
+
use temporal_sdk_core::{
|
|
19
|
+
CoreRuntime, TokioRuntimeBuilder,
|
|
20
|
+
telemetry::{build_otlp_metric_exporter, start_prometheus_metric_exporter},
|
|
21
|
+
};
|
|
24
22
|
use temporal_sdk_core_api::telemetry::{
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
CoreLog, CoreLogConsumer, HistogramBucketOverrides, Logger, MetricTemporality,
|
|
24
|
+
OtelCollectorOptionsBuilder, PrometheusExporterOptionsBuilder,
|
|
25
|
+
TelemetryOptions as CoreTelemetryOptions, TelemetryOptionsBuilder, metrics::CoreMeter,
|
|
27
26
|
};
|
|
28
27
|
use tracing::Level;
|
|
29
28
|
use url::Url;
|
|
@@ -1,28 +1,34 @@
|
|
|
1
|
-
use crate::
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
use crate::{
|
|
2
|
+
client::{
|
|
3
|
+
Client, ClientHttpConnectProxyOptions, ClientKeepAliveOptions, ClientRetryOptions,
|
|
4
|
+
ClientTlsOptions, RpcCallOptions, temporal_core_client_connect, temporal_core_client_free,
|
|
5
|
+
temporal_core_client_rpc_call,
|
|
6
|
+
},
|
|
7
|
+
runtime::{
|
|
8
|
+
Runtime, RuntimeOptions, RuntimeOrFail, temporal_core_byte_array_free,
|
|
9
|
+
temporal_core_runtime_free, temporal_core_runtime_new,
|
|
10
|
+
},
|
|
11
|
+
testing::{
|
|
12
|
+
DevServerOptions, EphemeralServer, TestServerOptions, temporal_core_ephemeral_server_free,
|
|
13
|
+
temporal_core_ephemeral_server_shutdown, temporal_core_ephemeral_server_start_dev_server,
|
|
14
|
+
},
|
|
13
15
|
};
|
|
14
16
|
|
|
15
|
-
use crate::
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
use crate::{
|
|
18
|
+
ByteArray, ByteArrayRef,
|
|
19
|
+
tests::utils::{
|
|
20
|
+
MetadataMap, OwnedRpcCallOptions, RpcCallError, byte_array_to_string, byte_array_to_vec,
|
|
21
|
+
pointer_or_null,
|
|
22
|
+
},
|
|
18
23
|
};
|
|
19
|
-
use crate::{ByteArray, ByteArrayRef};
|
|
20
24
|
use anyhow::anyhow;
|
|
21
|
-
use std::
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
use std::{
|
|
26
|
+
any::Any,
|
|
27
|
+
panic::{AssertUnwindSafe, UnwindSafe},
|
|
28
|
+
ptr::NonNull,
|
|
29
|
+
sync::{Arc, Condvar, Mutex, MutexGuard, PoisonError, Weak},
|
|
30
|
+
time::Duration,
|
|
31
|
+
};
|
|
26
32
|
use temporal_client::ClientOptions;
|
|
27
33
|
use temporal_sdk_core::ephemeral_server::{
|
|
28
34
|
EphemeralExe, EphemeralExeVersion, TemporalDevServerConfig,
|
|
@@ -156,11 +162,7 @@ impl Context {
|
|
|
156
162
|
temporal_core_runtime_free(runtime);
|
|
157
163
|
""
|
|
158
164
|
};
|
|
159
|
-
Err(anyhow!(
|
|
160
|
-
"Runtime creation failed: {}{}",
|
|
161
|
-
runtime_is_null,
|
|
162
|
-
fail
|
|
163
|
-
))
|
|
165
|
+
Err(anyhow!("Runtime creation failed: {runtime_is_null}{fail}"))
|
|
164
166
|
} else if runtime.is_null() {
|
|
165
167
|
Err(anyhow!("Runtime creation failed: runtime is null"))
|
|
166
168
|
} else {
|
|
@@ -516,8 +518,7 @@ extern "C" fn ephemeral_server_start_callback(
|
|
|
516
518
|
|
|
517
519
|
if let Some(fail) = fail {
|
|
518
520
|
ContextOperationState::CallbackError(anyhow!(
|
|
519
|
-
"Ephemeral server start failed: {}"
|
|
520
|
-
fail
|
|
521
|
+
"Ephemeral server start failed: {fail}"
|
|
521
522
|
))
|
|
522
523
|
} else if server.is_null() {
|
|
523
524
|
ContextOperationState::CallbackError(anyhow!(
|
|
@@ -562,8 +563,7 @@ extern "C" fn ephemeral_server_shutdown_callback(
|
|
|
562
563
|
let _ = context.complete_operation_catch_unwind(|guard| {
|
|
563
564
|
if let Some(fail) = byte_array_to_string(guard.runtime, std::mem::take(&mut fail)) {
|
|
564
565
|
ContextOperationState::CallbackError(anyhow!(
|
|
565
|
-
"Ephemeral server shutdown failed: {}"
|
|
566
|
-
fail
|
|
566
|
+
"Ephemeral server shutdown failed: {fail}"
|
|
567
567
|
))
|
|
568
568
|
} else {
|
|
569
569
|
ContextOperationState::CallbackOk(None)
|
|
@@ -585,7 +585,7 @@ extern "C" fn client_connect_callback(
|
|
|
585
585
|
if let Some(context) = user_data.context.upgrade() {
|
|
586
586
|
let _ = context.complete_operation_catch_unwind(|guard| {
|
|
587
587
|
if let Some(fail) = byte_array_to_string(guard.runtime, std::mem::take(&mut fail)) {
|
|
588
|
-
ContextOperationState::CallbackError(anyhow!("Client connect failed: {}"
|
|
588
|
+
ContextOperationState::CallbackError(anyhow!("Client connect failed: {fail}"))
|
|
589
589
|
} else {
|
|
590
590
|
guard.client = std::mem::take(&mut client);
|
|
591
591
|
ContextOperationState::CallbackOk(None)
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
use crate::
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
use crate::{
|
|
2
|
+
ByteArrayRef,
|
|
3
|
+
client::{
|
|
4
|
+
ClientGrpcOverrideRequest, ClientGrpcOverrideResponse, RpcService,
|
|
5
|
+
temporal_core_client_grpc_override_request_headers,
|
|
6
|
+
temporal_core_client_grpc_override_request_proto,
|
|
7
|
+
temporal_core_client_grpc_override_request_respond,
|
|
8
|
+
temporal_core_client_grpc_override_request_rpc,
|
|
9
|
+
temporal_core_client_grpc_override_request_service,
|
|
10
|
+
},
|
|
11
|
+
tests::utils::{
|
|
12
|
+
OwnedRpcCallOptions, RpcCallError, default_client_options, default_server_config,
|
|
13
|
+
},
|
|
12
14
|
};
|
|
13
15
|
use context::Context;
|
|
14
16
|
use prost::Message;
|
|
15
17
|
use std::sync::{Arc, LazyLock, Mutex};
|
|
16
|
-
use temporal_sdk_core_protos::temporal::api::
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
use temporal_sdk_core_protos::temporal::api::{
|
|
19
|
+
failure::v1::Failure,
|
|
20
|
+
workflowservice::v1::{
|
|
21
|
+
GetSystemInfoRequest, GetSystemInfoResponse, QueryWorkflowRequest,
|
|
22
|
+
StartWorkflowExecutionRequest, StartWorkflowExecutionResponse,
|
|
23
|
+
},
|
|
20
24
|
};
|
|
21
25
|
|
|
22
26
|
mod context;
|
|
@@ -313,7 +317,7 @@ fn test_simple_callback_override() {
|
|
|
313
317
|
}))
|
|
314
318
|
.unwrap();
|
|
315
319
|
let start_resp = StartWorkflowExecutionResponse::decode(&*start_resp_raw).unwrap();
|
|
316
|
-
|
|
320
|
+
assert_eq!(start_resp.run_id, "run-id for my-workflow-id");
|
|
317
321
|
|
|
318
322
|
// Try a query where a query failure will actually be delivered as failure details.
|
|
319
323
|
// However, we don't currently have temporal_sdk_core_protos::google::rpc::Status in
|
|
@@ -332,23 +336,23 @@ fn test_simple_callback_override() {
|
|
|
332
336
|
.unwrap_err()
|
|
333
337
|
.downcast::<RpcCallError>()
|
|
334
338
|
.unwrap();
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
339
|
+
assert_eq!(query_err.status_code, tonic::Code::Internal as u32);
|
|
340
|
+
assert_eq!(query_err.message, "query-fail");
|
|
341
|
+
assert_eq!(
|
|
338
342
|
Failure::decode(query_err.details.as_ref().unwrap().as_slice())
|
|
339
343
|
.unwrap()
|
|
340
|
-
.message
|
|
341
|
-
|
|
344
|
+
.message,
|
|
345
|
+
"intentional failure"
|
|
342
346
|
);
|
|
343
347
|
|
|
344
348
|
// Confirm we got the expected calls
|
|
345
|
-
|
|
346
|
-
*CALLBACK_OVERRIDE_CALLS.lock().unwrap()
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
349
|
+
assert_eq!(
|
|
350
|
+
*CALLBACK_OVERRIDE_CALLS.lock().unwrap(),
|
|
351
|
+
vec![
|
|
352
|
+
"service: temporal.api.workflowservice.v1.WorkflowService, rpc: GetSystemInfo",
|
|
353
|
+
"service: temporal.api.workflowservice.v1.WorkflowService, rpc: StartWorkflowExecution",
|
|
354
|
+
"service: temporal.api.workflowservice.v1.WorkflowService, rpc: QueryWorkflow"
|
|
355
|
+
]
|
|
352
356
|
);
|
|
353
357
|
});
|
|
354
358
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
use crate::
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
use crate::{
|
|
2
|
+
ByteArray, CancellationToken,
|
|
3
|
+
client::RpcService,
|
|
4
|
+
runtime::{Runtime, temporal_core_byte_array_free},
|
|
5
|
+
};
|
|
6
|
+
use std::{collections::HashMap, ops::Deref};
|
|
6
7
|
use temporal_client::{ClientOptions, ClientOptionsBuilder};
|
|
7
8
|
use temporal_sdk_core::ephemeral_server::{
|
|
8
|
-
TemporalDevServerConfig, TemporalDevServerConfigBuilder,
|
|
9
|
+
TemporalDevServerConfig, TemporalDevServerConfigBuilder, default_cached_download,
|
|
9
10
|
};
|
|
10
|
-
use temporal_sdk_core_test_utils::default_cached_download;
|
|
11
11
|
use url::Url;
|
|
12
12
|
|
|
13
13
|
pub fn byte_array_to_vec(runtime: *mut Runtime, byte_array: *const ByteArray) -> Option<Vec<u8>> {
|