@temporalio/core-bridge 1.12.0 → 1.12.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 +64 -119
- package/Cargo.toml +1 -1
- package/index.js +3 -2
- 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 +1 -2
- package/sdk-core/.github/workflows/per-pr.yml +2 -0
- package/sdk-core/AGENTS.md +7 -0
- package/sdk-core/Cargo.toml +9 -5
- package/sdk-core/README.md +6 -5
- package/sdk-core/client/Cargo.toml +3 -2
- package/sdk-core/client/src/lib.rs +17 -8
- package/sdk-core/client/src/metrics.rs +57 -23
- package/sdk-core/client/src/raw.rs +33 -15
- package/sdk-core/core/Cargo.toml +11 -9
- package/sdk-core/core/benches/workflow_replay.rs +114 -15
- package/sdk-core/core/src/core_tests/activity_tasks.rs +18 -18
- package/sdk-core/core/src/core_tests/child_workflows.rs +4 -4
- package/sdk-core/core/src/core_tests/determinism.rs +6 -6
- package/sdk-core/core/src/core_tests/local_activities.rs +20 -20
- package/sdk-core/core/src/core_tests/mod.rs +40 -5
- package/sdk-core/core/src/core_tests/queries.rs +25 -16
- package/sdk-core/core/src/core_tests/replay_flag.rs +3 -3
- package/sdk-core/core/src/core_tests/updates.rs +3 -3
- package/sdk-core/core/src/core_tests/workers.rs +9 -7
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +40 -42
- package/sdk-core/core/src/ephemeral_server/mod.rs +1 -19
- package/sdk-core/core/src/lib.rs +10 -1
- package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
- package/sdk-core/core/src/replay/mod.rs +3 -3
- package/sdk-core/core/src/telemetry/metrics.rs +306 -152
- package/sdk-core/core/src/telemetry/mod.rs +11 -4
- package/sdk-core/core/src/telemetry/otel.rs +134 -131
- package/sdk-core/core/src/telemetry/prometheus_meter.rs +885 -0
- package/sdk-core/core/src/telemetry/prometheus_server.rs +48 -28
- package/sdk-core/core/src/test_help/mod.rs +27 -12
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +7 -7
- package/sdk-core/core/src/worker/activities.rs +4 -4
- package/sdk-core/core/src/worker/client/mocks.rs +10 -3
- package/sdk-core/core/src/worker/client.rs +68 -5
- package/sdk-core/core/src/worker/heartbeat.rs +229 -0
- package/sdk-core/core/src/worker/mod.rs +35 -14
- package/sdk-core/core/src/worker/tuner/resource_based.rs +4 -4
- package/sdk-core/core/src/worker/workflow/history_update.rs +71 -19
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +31 -48
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +3 -3
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +4 -1
- package/sdk-core/core/src/worker/workflow/managed_run.rs +1 -1
- package/sdk-core/core/src/worker/workflow/mod.rs +15 -15
- package/sdk-core/core-api/Cargo.toml +2 -2
- package/sdk-core/core-api/src/envconfig.rs +204 -99
- package/sdk-core/core-api/src/lib.rs +9 -0
- package/sdk-core/core-api/src/telemetry/metrics.rs +548 -100
- package/sdk-core/core-api/src/worker.rs +11 -5
- package/sdk-core/core-c-bridge/Cargo.toml +49 -0
- package/sdk-core/core-c-bridge/build.rs +26 -0
- package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +817 -0
- package/sdk-core/core-c-bridge/src/client.rs +679 -0
- package/sdk-core/core-c-bridge/src/lib.rs +245 -0
- package/sdk-core/core-c-bridge/src/metric.rs +682 -0
- package/sdk-core/core-c-bridge/src/random.rs +61 -0
- package/sdk-core/core-c-bridge/src/runtime.rs +445 -0
- package/sdk-core/core-c-bridge/src/testing.rs +282 -0
- package/sdk-core/core-c-bridge/src/tests/context.rs +644 -0
- package/sdk-core/core-c-bridge/src/tests/mod.rs +178 -0
- package/sdk-core/core-c-bridge/src/tests/utils.rs +108 -0
- package/sdk-core/core-c-bridge/src/worker.rs +1069 -0
- package/sdk-core/etc/deps.svg +64 -64
- package/sdk-core/sdk/src/activity_context.rs +6 -4
- package/sdk-core/sdk/src/lib.rs +49 -27
- package/sdk-core/sdk/src/workflow_future.rs +18 -25
- package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +4 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.yaml +0 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +630 -83
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +632 -78
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto +4 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +6 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +32 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +10 -1
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/deployment.proto +26 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/reset.proto +4 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +47 -31
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +4 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +7 -1
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/worker/v1/message.proto +134 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +14 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +148 -37
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +21 -0
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -4
- package/sdk-core/sdk-core-protos/src/history_builder.rs +9 -5
- package/sdk-core/sdk-core-protos/src/lib.rs +96 -6
- package/sdk-core/test-utils/src/lib.rs +11 -3
- package/sdk-core/tests/cloud_tests.rs +3 -3
- package/sdk-core/tests/heavy_tests.rs +11 -3
- package/sdk-core/tests/integ_tests/client_tests.rs +12 -13
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/metrics_tests.rs +188 -83
- package/sdk-core/tests/integ_tests/polling_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/queries_tests.rs +56 -40
- package/sdk-core/tests/integ_tests/update_tests.rs +2 -7
- package/sdk-core/tests/integ_tests/worker_tests.rs +3 -4
- package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +3 -7
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +3 -5
- package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +24 -17
- package/src/client.rs +6 -0
- package/src/metrics.rs +6 -6
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
use crate::client::RpcService;
|
|
2
|
+
use crate::tests::utils::{
|
|
3
|
+
OwnedRpcCallOptions, RpcCallError, default_client_options, default_server_config,
|
|
4
|
+
};
|
|
5
|
+
use context::Context;
|
|
6
|
+
use prost::Message;
|
|
7
|
+
use std::sync::Arc;
|
|
8
|
+
use temporal_sdk_core_protos::temporal::api::workflowservice::v1::{
|
|
9
|
+
GetSystemInfoRequest, GetSystemInfoResponse,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
mod context;
|
|
13
|
+
mod utils;
|
|
14
|
+
|
|
15
|
+
#[test]
|
|
16
|
+
fn test_get_system_info() {
|
|
17
|
+
Context::with(|context| {
|
|
18
|
+
context.runtime_new().unwrap();
|
|
19
|
+
context
|
|
20
|
+
.start_dev_server(Box::new(default_server_config()))
|
|
21
|
+
.unwrap();
|
|
22
|
+
context
|
|
23
|
+
.client_connect(Box::new(default_client_options(
|
|
24
|
+
&context.ephemeral_server_target().unwrap().unwrap(),
|
|
25
|
+
)))
|
|
26
|
+
.unwrap();
|
|
27
|
+
let result = GetSystemInfoResponse::decode(
|
|
28
|
+
&*context
|
|
29
|
+
.rpc_call(Box::new(OwnedRpcCallOptions {
|
|
30
|
+
service: RpcService::Workflow,
|
|
31
|
+
rpc: "GetSystemInfo".into(),
|
|
32
|
+
req: GetSystemInfoRequest {}.encode_to_vec(),
|
|
33
|
+
retry: false,
|
|
34
|
+
metadata: None,
|
|
35
|
+
timeout_millis: 0,
|
|
36
|
+
cancellation_token: None,
|
|
37
|
+
}))
|
|
38
|
+
.unwrap(),
|
|
39
|
+
);
|
|
40
|
+
assert!(result.is_ok());
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn rpc_call_exists(context: &Arc<Context>, service: RpcService, rpc: &str) -> bool {
|
|
45
|
+
let result = context.rpc_call(Box::new(OwnedRpcCallOptions {
|
|
46
|
+
service,
|
|
47
|
+
rpc: rpc.into(),
|
|
48
|
+
req: Vec::new(),
|
|
49
|
+
retry: false,
|
|
50
|
+
metadata: None,
|
|
51
|
+
timeout_millis: 0,
|
|
52
|
+
cancellation_token: None,
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
if let Err(e) = result {
|
|
56
|
+
// will panic on other types of errors
|
|
57
|
+
e.downcast::<RpcCallError>().unwrap().message != format!("Unknown RPC call {rpc}")
|
|
58
|
+
} else {
|
|
59
|
+
true
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#[test]
|
|
64
|
+
fn test_missing_rpc_call_has_expected_error_message() {
|
|
65
|
+
Context::with(|context| {
|
|
66
|
+
context.runtime_new().unwrap();
|
|
67
|
+
context
|
|
68
|
+
.start_dev_server(Box::new(default_server_config()))
|
|
69
|
+
.unwrap();
|
|
70
|
+
context
|
|
71
|
+
.client_connect(Box::new(default_client_options(
|
|
72
|
+
&context.ephemeral_server_target().unwrap().unwrap(),
|
|
73
|
+
)))
|
|
74
|
+
.unwrap();
|
|
75
|
+
|
|
76
|
+
assert!(!rpc_call_exists(
|
|
77
|
+
context,
|
|
78
|
+
RpcService::Workflow,
|
|
79
|
+
"NonExistentMethod"
|
|
80
|
+
));
|
|
81
|
+
assert!(!rpc_call_exists(
|
|
82
|
+
context,
|
|
83
|
+
RpcService::Operator,
|
|
84
|
+
"NonExistentMethod"
|
|
85
|
+
));
|
|
86
|
+
assert!(!rpc_call_exists(
|
|
87
|
+
context,
|
|
88
|
+
RpcService::Cloud,
|
|
89
|
+
"NonExistentMethod"
|
|
90
|
+
));
|
|
91
|
+
assert!(!rpc_call_exists(
|
|
92
|
+
context,
|
|
93
|
+
RpcService::Test,
|
|
94
|
+
"NonExistentMethod"
|
|
95
|
+
));
|
|
96
|
+
assert!(!rpc_call_exists(
|
|
97
|
+
context,
|
|
98
|
+
RpcService::Health,
|
|
99
|
+
"NonExistentMethod"
|
|
100
|
+
));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
fn list_proto_methods(proto_def_str: &str) -> Vec<&str> {
|
|
105
|
+
proto_def_str
|
|
106
|
+
.lines()
|
|
107
|
+
.map(|l| l.trim())
|
|
108
|
+
.filter(|l| l.starts_with("rpc"))
|
|
109
|
+
.map(|l| {
|
|
110
|
+
let stripped = l.strip_prefix("rpc ").unwrap();
|
|
111
|
+
stripped[..stripped.find('(').unwrap()].trim()
|
|
112
|
+
})
|
|
113
|
+
.collect()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
fn all_rpc_calls_exist(context: &Arc<Context>, service: RpcService, proto: &str) -> bool {
|
|
117
|
+
let mut ret = true;
|
|
118
|
+
for rpc in list_proto_methods(proto) {
|
|
119
|
+
if !rpc_call_exists(context, service, rpc) {
|
|
120
|
+
eprintln!("RPC method {rpc} does not exist in service {service:?}");
|
|
121
|
+
ret = false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
ret
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
#[test]
|
|
128
|
+
fn test_all_rpc_calls_exist() {
|
|
129
|
+
Context::with(|context| {
|
|
130
|
+
context.runtime_new().unwrap();
|
|
131
|
+
context
|
|
132
|
+
.start_dev_server(Box::new(default_server_config()))
|
|
133
|
+
.unwrap();
|
|
134
|
+
context
|
|
135
|
+
.client_connect(Box::new(default_client_options(
|
|
136
|
+
&context.ephemeral_server_target().unwrap().unwrap(),
|
|
137
|
+
)))
|
|
138
|
+
.unwrap();
|
|
139
|
+
|
|
140
|
+
assert!(all_rpc_calls_exist(
|
|
141
|
+
context,
|
|
142
|
+
RpcService::Workflow,
|
|
143
|
+
include_str!(
|
|
144
|
+
"../../../sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto"
|
|
145
|
+
),
|
|
146
|
+
));
|
|
147
|
+
|
|
148
|
+
assert!(all_rpc_calls_exist(
|
|
149
|
+
context,
|
|
150
|
+
RpcService::Operator,
|
|
151
|
+
include_str!(
|
|
152
|
+
"../../../sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto"
|
|
153
|
+
),
|
|
154
|
+
));
|
|
155
|
+
|
|
156
|
+
assert!(all_rpc_calls_exist(
|
|
157
|
+
context,
|
|
158
|
+
RpcService::Cloud,
|
|
159
|
+
include_str!(
|
|
160
|
+
"../../../sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/service.proto"
|
|
161
|
+
),
|
|
162
|
+
));
|
|
163
|
+
|
|
164
|
+
assert!(all_rpc_calls_exist(
|
|
165
|
+
context,
|
|
166
|
+
RpcService::Test,
|
|
167
|
+
include_str!(
|
|
168
|
+
"../../../sdk-core-protos/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto"
|
|
169
|
+
),
|
|
170
|
+
));
|
|
171
|
+
|
|
172
|
+
assert!(all_rpc_calls_exist(
|
|
173
|
+
context,
|
|
174
|
+
RpcService::Health,
|
|
175
|
+
include_str!("../../../sdk-core-protos/protos/grpc/health/v1/health.proto"),
|
|
176
|
+
));
|
|
177
|
+
});
|
|
178
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
use crate::client::RpcService;
|
|
2
|
+
use crate::runtime::{Runtime, temporal_core_byte_array_free};
|
|
3
|
+
use crate::{ByteArray, CancellationToken};
|
|
4
|
+
use std::collections::HashMap;
|
|
5
|
+
use std::ops::Deref;
|
|
6
|
+
use temporal_client::{ClientOptions, ClientOptionsBuilder};
|
|
7
|
+
use temporal_sdk_core::ephemeral_server::{
|
|
8
|
+
TemporalDevServerConfig, TemporalDevServerConfigBuilder,
|
|
9
|
+
};
|
|
10
|
+
use temporal_sdk_core_test_utils::default_cached_download;
|
|
11
|
+
use url::Url;
|
|
12
|
+
|
|
13
|
+
pub fn byte_array_to_vec(runtime: *mut Runtime, byte_array: *const ByteArray) -> Option<Vec<u8>> {
|
|
14
|
+
(!byte_array.is_null()).then(|| {
|
|
15
|
+
let ret = unsafe { &*byte_array }.as_ref().to_vec();
|
|
16
|
+
temporal_core_byte_array_free(runtime, byte_array);
|
|
17
|
+
ret
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
pub fn byte_array_to_string(runtime: *mut Runtime, byte_array: *const ByteArray) -> Option<String> {
|
|
22
|
+
(!byte_array.is_null()).then(|| {
|
|
23
|
+
let ret = unsafe { &*byte_array }.as_ref().to_string();
|
|
24
|
+
temporal_core_byte_array_free(runtime, byte_array);
|
|
25
|
+
ret
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
pub fn pointer_or_null<T>(x: Option<impl Deref<Target = T>>) -> *const T {
|
|
30
|
+
x.map(|x| &*x as *const T).unwrap_or(std::ptr::null())
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
pub fn default_server_config() -> TemporalDevServerConfig {
|
|
34
|
+
TemporalDevServerConfigBuilder::default()
|
|
35
|
+
.exe(default_cached_download())
|
|
36
|
+
.build()
|
|
37
|
+
.unwrap()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
pub fn default_client_options(target: &str) -> ClientOptions {
|
|
41
|
+
ClientOptionsBuilder::default()
|
|
42
|
+
.target_url(Url::parse(&format!("http://{target}")).unwrap())
|
|
43
|
+
.client_name("core-c-bridge-tests".to_owned())
|
|
44
|
+
.client_version("0.1.0".to_owned())
|
|
45
|
+
.build()
|
|
46
|
+
.unwrap()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pub struct OwnedRpcCallOptions {
|
|
50
|
+
pub service: RpcService,
|
|
51
|
+
pub rpc: String,
|
|
52
|
+
pub req: Vec<u8>,
|
|
53
|
+
pub retry: bool,
|
|
54
|
+
pub metadata: Option<MetadataMap>,
|
|
55
|
+
pub timeout_millis: u32,
|
|
56
|
+
pub cancellation_token: Option<*mut CancellationToken>,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
unsafe impl Send for OwnedRpcCallOptions {}
|
|
60
|
+
unsafe impl Sync for OwnedRpcCallOptions {}
|
|
61
|
+
|
|
62
|
+
#[derive(Clone, Debug)]
|
|
63
|
+
pub enum MetadataMap {
|
|
64
|
+
Deserialized(HashMap<String, String>),
|
|
65
|
+
Serialized(String),
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
impl From<HashMap<String, String>> for MetadataMap {
|
|
69
|
+
fn from(value: HashMap<String, String>) -> Self {
|
|
70
|
+
Self::Deserialized(value)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#[allow(dead_code)]
|
|
75
|
+
impl MetadataMap {
|
|
76
|
+
pub fn serialize_from_map(map: &HashMap<String, String>) -> String {
|
|
77
|
+
map.iter().map(|(k, v)| format!("{k}\n{v}\n")).collect()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
pub fn serialize(&self) -> String {
|
|
81
|
+
match self {
|
|
82
|
+
Self::Deserialized(map) => Self::serialize_from_map(map),
|
|
83
|
+
Self::Serialized(s) => s.clone(),
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
pub fn serialize_in_place(&mut self) {
|
|
88
|
+
if let Self::Deserialized(map) = self {
|
|
89
|
+
*self = Self::Serialized(Self::serialize_from_map(map));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
pub fn as_str(&mut self) -> &str {
|
|
94
|
+
self.serialize_in_place();
|
|
95
|
+
let Self::Serialized(s) = self else {
|
|
96
|
+
unreachable!();
|
|
97
|
+
};
|
|
98
|
+
s
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#[derive(thiserror::Error, Debug)]
|
|
103
|
+
#[error("{message} (status code {status_code})")]
|
|
104
|
+
pub struct RpcCallError {
|
|
105
|
+
pub status_code: u32,
|
|
106
|
+
pub message: String,
|
|
107
|
+
pub details: Option<Vec<u8>>,
|
|
108
|
+
}
|