@temporalio/core-bridge 1.9.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +754 -473
- package/Cargo.toml +3 -3
- package/lib/index.d.ts +33 -2
- package/lib/index.js.map +1 -1
- package/package.json +4 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/scripts/build.js +4 -3
- package/sdk-core/.cargo/config.toml +2 -4
- package/sdk-core/.github/workflows/heavy.yml +1 -1
- package/sdk-core/.github/workflows/per-pr.yml +6 -4
- package/sdk-core/Cargo.toml +10 -3
- package/sdk-core/README.md +4 -6
- package/sdk-core/client/Cargo.toml +13 -5
- package/sdk-core/client/src/lib.rs +123 -34
- package/sdk-core/client/src/metrics.rs +70 -18
- package/sdk-core/client/src/proxy.rs +85 -0
- package/sdk-core/client/src/raw.rs +67 -5
- package/sdk-core/client/src/worker_registry/mod.rs +5 -3
- package/sdk-core/client/src/workflow_handle/mod.rs +3 -1
- package/sdk-core/core/Cargo.toml +31 -37
- package/sdk-core/core/src/abstractions/take_cell.rs +3 -3
- package/sdk-core/core/src/abstractions.rs +176 -108
- package/sdk-core/core/src/core_tests/activity_tasks.rs +4 -13
- package/sdk-core/core/src/core_tests/determinism.rs +2 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +3 -3
- package/sdk-core/core/src/core_tests/mod.rs +3 -3
- package/sdk-core/core/src/core_tests/queries.rs +42 -5
- package/sdk-core/core/src/core_tests/workers.rs +2 -3
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +115 -15
- package/sdk-core/core/src/ephemeral_server/mod.rs +109 -136
- package/sdk-core/core/src/internal_flags.rs +8 -8
- package/sdk-core/core/src/lib.rs +16 -11
- package/sdk-core/core/src/pollers/mod.rs +11 -5
- package/sdk-core/core/src/pollers/poll_buffer.rs +48 -29
- package/sdk-core/core/src/protosext/mod.rs +32 -32
- package/sdk-core/core/src/protosext/protocol_messages.rs +14 -24
- package/sdk-core/core/src/retry_logic.rs +2 -2
- package/sdk-core/core/src/telemetry/log_export.rs +10 -9
- package/sdk-core/core/src/telemetry/metrics.rs +233 -330
- package/sdk-core/core/src/telemetry/mod.rs +11 -38
- package/sdk-core/core/src/telemetry/otel.rs +355 -0
- package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -23
- package/sdk-core/core/src/test_help/mod.rs +80 -59
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +6 -6
- package/sdk-core/core/src/worker/activities/local_activities.rs +46 -43
- package/sdk-core/core/src/worker/activities.rs +45 -46
- package/sdk-core/core/src/worker/client/mocks.rs +8 -7
- package/sdk-core/core/src/worker/client.rs +40 -39
- package/sdk-core/core/src/worker/mod.rs +72 -42
- package/sdk-core/core/src/worker/slot_provider.rs +28 -28
- package/sdk-core/core/src/worker/slot_supplier.rs +1 -0
- package/sdk-core/core/src/worker/tuner/fixed_size.rs +52 -0
- package/sdk-core/core/src/worker/tuner/resource_based.rs +561 -0
- package/sdk-core/core/src/worker/tuner.rs +122 -0
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +6 -6
- package/sdk-core/core/src/worker/workflow/history_update.rs +27 -53
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +4 -17
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -10
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +4 -11
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +17 -35
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -8
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -14
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -10
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +3 -10
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +12 -8
- package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +0 -10
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -13
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +27 -37
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +3 -14
- package/sdk-core/core/src/worker/workflow/managed_run.rs +84 -54
- package/sdk-core/core/src/worker/workflow/mod.rs +63 -160
- package/sdk-core/core/src/worker/workflow/run_cache.rs +22 -13
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +16 -3
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +15 -12
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +39 -78
- package/sdk-core/core-api/Cargo.toml +6 -5
- package/sdk-core/core-api/src/errors.rs +8 -0
- package/sdk-core/core-api/src/telemetry/metrics.rs +75 -4
- package/sdk-core/core-api/src/telemetry.rs +7 -1
- package/sdk-core/core-api/src/worker.rs +212 -56
- package/sdk-core/fsm/Cargo.toml +3 -0
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
- package/sdk-core/sdk/Cargo.toml +5 -7
- package/sdk-core/sdk/src/app_data.rs +3 -3
- package/sdk-core/sdk/src/lib.rs +5 -3
- package/sdk-core/sdk/src/workflow_context/options.rs +1 -1
- package/sdk-core/sdk/src/workflow_context.rs +10 -9
- package/sdk-core/sdk/src/workflow_future.rs +1 -1
- package/sdk-core/sdk-core-protos/Cargo.toml +8 -6
- package/sdk-core/sdk-core-protos/build.rs +1 -10
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +3 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/ci.yml +26 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +42 -20
- package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +36 -26
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/struct.proto +95 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +9632 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +7337 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/payload_description.txt +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +45 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +22 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/command_type.proto +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +44 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +18 -3
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +30 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/update.proto +7 -8
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +23 -5
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/errordetails/v1/message.proto +20 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +25 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +141 -15
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +12 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +193 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +73 -6
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +46 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +4 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +2 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +116 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +134 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +274 -29
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +57 -1
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +10 -12
- package/sdk-core/sdk-core-protos/src/history_builder.rs +1 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +54 -51
- package/sdk-core/sdk-core-protos/src/task_token.rs +11 -2
- package/sdk-core/test-utils/Cargo.toml +7 -4
- package/sdk-core/test-utils/src/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +44 -62
- package/sdk-core/tests/fuzzy_workflow.rs +5 -2
- package/sdk-core/tests/heavy_tests.rs +114 -17
- package/sdk-core/tests/integ_tests/activity_functions.rs +1 -1
- package/sdk-core/tests/integ_tests/client_tests.rs +2 -2
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +38 -26
- package/sdk-core/tests/integ_tests/metrics_tests.rs +126 -17
- package/sdk-core/tests/integ_tests/polling_tests.rs +118 -2
- package/sdk-core/tests/integ_tests/update_tests.rs +3 -5
- package/sdk-core/tests/integ_tests/visibility_tests.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -4
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -2
- package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +6 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +9 -7
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +14 -9
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +6 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +9 -6
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +5 -5
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests.rs +115 -11
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +57 -0
- package/src/lib.rs +1 -0
- package/src/runtime.rs +51 -35
- package/ts/index.ts +67 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
- package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
- package/sdk-core/sdk/src/payload_converter.rs +0 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +0 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/docker-compose.yml +0 -15
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/pipeline.yml +0 -10
- package/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
- package/sdk-core/tests/wf_input_replay.rs +0 -32
package/Cargo.toml
CHANGED
|
@@ -20,10 +20,10 @@ incremental = false
|
|
|
20
20
|
futures = { version = "0.3", features = ["executor"] }
|
|
21
21
|
log = "0.4"
|
|
22
22
|
neon = { version = "0.10", default-features = false, features = ["napi-6", "event-queue-api"] }
|
|
23
|
-
opentelemetry = "0.
|
|
23
|
+
opentelemetry = "0.22"
|
|
24
24
|
parking_lot = "0.12"
|
|
25
|
-
prost = "0.
|
|
26
|
-
prost-types = "0.
|
|
25
|
+
prost = "0.12"
|
|
26
|
+
prost-types = "0.12"
|
|
27
27
|
serde_json = "1.0"
|
|
28
28
|
tokio = "1.13"
|
|
29
29
|
once_cell = "1.19"
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LogLevel, Duration } from '@temporalio/common';
|
|
2
|
-
import type { TLSConfig } from '@temporalio/common/lib/internal-non-workflow';
|
|
3
|
-
export { TLSConfig };
|
|
2
|
+
import type { TLSConfig, ProxyConfig, HttpConnectProxyConfig } from '@temporalio/common/lib/internal-non-workflow';
|
|
3
|
+
export type { TLSConfig, ProxyConfig, HttpConnectProxyConfig };
|
|
4
4
|
/** @deprecated Import from @temporalio/common instead */
|
|
5
5
|
export { LogLevel };
|
|
6
6
|
type Shadow<Base, New> = Base extends object ? New extends object ? {
|
|
@@ -37,6 +37,12 @@ export interface ClientOptions {
|
|
|
37
37
|
* connect with TLS without any customization.
|
|
38
38
|
*/
|
|
39
39
|
tls?: TLSConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Proxying configuration.
|
|
42
|
+
*
|
|
43
|
+
* @experimental
|
|
44
|
+
*/
|
|
45
|
+
proxy?: ProxyConfig;
|
|
40
46
|
/**
|
|
41
47
|
* Optional retry options for server requests.
|
|
42
48
|
*/
|
|
@@ -47,6 +53,13 @@ export interface ClientOptions {
|
|
|
47
53
|
* Set statically at connection time, can be replaced later using {@link clientUpdateHeaders}.
|
|
48
54
|
*/
|
|
49
55
|
metadata?: Record<string, string>;
|
|
56
|
+
/**
|
|
57
|
+
* API key for Temporal. This becomes the "Authorization" HTTP header with "Bearer " prepended.
|
|
58
|
+
* This is only set if RPC metadata doesn't already have an "authorization" key.
|
|
59
|
+
*
|
|
60
|
+
* Set statically at connection time, can be replaced later using {@link clientUpdateApiKey}.
|
|
61
|
+
*/
|
|
62
|
+
apiKey?: string;
|
|
50
63
|
}
|
|
51
64
|
/**
|
|
52
65
|
* Log directly to console
|
|
@@ -99,6 +112,10 @@ export interface OtelCollectorExporter {
|
|
|
99
112
|
* @defaults 1 second
|
|
100
113
|
*/
|
|
101
114
|
metricsExportInterval?: Duration;
|
|
115
|
+
/**
|
|
116
|
+
* If set to true, the exporter will use seconds for durations instead of milliseconds.
|
|
117
|
+
*/
|
|
118
|
+
useSecondsForDurations?: boolean;
|
|
102
119
|
};
|
|
103
120
|
}
|
|
104
121
|
/** @experimental */
|
|
@@ -121,6 +138,19 @@ export interface PrometheusMetricsExporter {
|
|
|
121
138
|
* Metrics will be available for scraping under the standard `/metrics` route.
|
|
122
139
|
*/
|
|
123
140
|
bindAddress: string;
|
|
141
|
+
/**
|
|
142
|
+
* If set to true, all counter names will include a "_total" suffix.
|
|
143
|
+
*/
|
|
144
|
+
countersTotalSuffix?: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* If set to true, all histograms will include the unit in their name as a suffix.
|
|
147
|
+
* EX: "_milliseconds"
|
|
148
|
+
*/
|
|
149
|
+
unitSuffix?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* If set to true, the exporter will use seconds for durations instead of milliseconds.
|
|
152
|
+
*/
|
|
153
|
+
useSecondsForDurations?: boolean;
|
|
124
154
|
};
|
|
125
155
|
}
|
|
126
156
|
/**
|
|
@@ -416,6 +446,7 @@ export declare function closeHistoryStream(pusher: HistoryPusher): void;
|
|
|
416
446
|
export declare function workerInitiateShutdown(worker: Worker, callback: VoidCallback): void;
|
|
417
447
|
export declare function workerFinalizeShutdown(worker: Worker): void;
|
|
418
448
|
export declare function clientUpdateHeaders(client: Client, headers: Record<string, string>, callback: VoidCallback): void;
|
|
449
|
+
export declare function clientUpdateApiKey(client: Client, apiKey: string, callback: VoidCallback): void;
|
|
419
450
|
export declare function clientClose(client: Client): void;
|
|
420
451
|
export declare function runtimeShutdown(runtime: Runtime, callback: VoidCallback): void;
|
|
421
452
|
export declare function pollLogs(runtime: Runtime, callback: LogsCallback): void;
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":";;;AAsjBA,mCAA0E;AAAjE,uGAAA,aAAa,OAAA;AAAE,wGAAA,cAAc,OAAA;AAAE,yGAAA,eAAe,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporalio/core-bridge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Temporal.io SDK Core<>Node bridge",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"build-rust-release": "npm run build-rust -- --release",
|
|
11
11
|
"install": "node ./scripts/build.js",
|
|
12
12
|
"format": "cargo fmt",
|
|
13
|
-
"lint": "cargo clippy --fix",
|
|
13
|
+
"lint": "cargo clippy --fix --allow-staged",
|
|
14
14
|
"lint.check": "cargo clippy"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"author": "Temporal Technologies Inc. <sdk@temporal.io>",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@temporalio/common": "
|
|
25
|
+
"@temporalio/common": "1.10.0",
|
|
26
26
|
"arg": "^5.0.2",
|
|
27
27
|
"cargo-cp-artifact": "^0.1.8",
|
|
28
28
|
"which": "^4.0.0"
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "39d702af7ae5d7e33ee90651292aa77fa07d33ca"
|
|
56
56
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/scripts/build.js
CHANGED
|
@@ -82,11 +82,12 @@ function compile(requestedTarget) {
|
|
|
82
82
|
const cmd = which.sync('cargo-cp-artifact');
|
|
83
83
|
|
|
84
84
|
console.log('Running', cmd, argv);
|
|
85
|
-
const { status } = spawnSync(cmd, argv, {
|
|
85
|
+
const { status, error } = spawnSync(cmd, argv, {
|
|
86
86
|
stdio: 'inherit',
|
|
87
|
+
shell: process.platform === 'win32',
|
|
87
88
|
});
|
|
88
|
-
if (status !== 0) {
|
|
89
|
-
throw new Error(`Failed to build${target ? ' for ' + target : ''}
|
|
89
|
+
if (status !== 0 || error) {
|
|
90
|
+
throw new Error(`Failed to build${target ? ' for ' + target : ''}: status code ${status}`, error);
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
93
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
[alias]
|
|
2
2
|
integ-test = ["run", "--package", "temporal-sdk-core", "--example", "integ_runner", "--"]
|
|
3
|
-
wf-input-replay = ["run", "--package", "temporal-sdk-core", "--features", "save_wf_inputs",
|
|
4
|
-
"--example", "wf_input_replay", "--"]
|
|
5
3
|
lint = ["clippy", "--workspace", "--examples", "--all-features",
|
|
6
|
-
|
|
4
|
+
"--test", "integ_tests", "--test", "heavy_tests", "--", "--D", "warnings"]
|
|
7
5
|
test-lint = ["clippy", "--all", "--all-features", "--examples", "--workspace",
|
|
8
|
-
|
|
6
|
+
"--tests", "--", "--D", "warnings"]
|
|
@@ -13,7 +13,7 @@ concurrency:
|
|
|
13
13
|
jobs:
|
|
14
14
|
build-and-test:
|
|
15
15
|
name: "Format, docs, and lint"
|
|
16
|
-
timeout-minutes:
|
|
16
|
+
timeout-minutes: 10
|
|
17
17
|
runs-on: ubuntu-latest
|
|
18
18
|
steps:
|
|
19
19
|
- uses: actions/checkout@v2
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
- uses: actions-rs/toolchain@v1
|
|
23
23
|
with:
|
|
24
24
|
profile: minimal
|
|
25
|
-
toolchain: 1.
|
|
25
|
+
toolchain: 1.77.0
|
|
26
26
|
override: true
|
|
27
27
|
- name: Install protoc
|
|
28
28
|
uses: arduino/setup-protoc@v1
|
|
@@ -48,13 +48,14 @@ jobs:
|
|
|
48
48
|
|
|
49
49
|
test:
|
|
50
50
|
name: Unit Tests
|
|
51
|
+
timeout-minutes: 10
|
|
51
52
|
runs-on: ubuntu-latest
|
|
52
53
|
steps:
|
|
53
54
|
- uses: actions/checkout@v2
|
|
54
55
|
- uses: actions-rs/toolchain@v1
|
|
55
56
|
with:
|
|
56
57
|
profile: minimal
|
|
57
|
-
toolchain: 1.
|
|
58
|
+
toolchain: 1.77.0
|
|
58
59
|
override: true
|
|
59
60
|
- name: Install protoc
|
|
60
61
|
uses: arduino/setup-protoc@v1
|
|
@@ -77,13 +78,14 @@ jobs:
|
|
|
77
78
|
|
|
78
79
|
fmt:
|
|
79
80
|
name: Integ tests
|
|
81
|
+
timeout-minutes: 20
|
|
80
82
|
runs-on: ubuntu-latest
|
|
81
83
|
steps:
|
|
82
84
|
- uses: actions/checkout@v2
|
|
83
85
|
- uses: actions-rs/toolchain@v1
|
|
84
86
|
with:
|
|
85
87
|
profile: minimal
|
|
86
|
-
toolchain: 1.
|
|
88
|
+
toolchain: 1.77.0
|
|
87
89
|
override: true
|
|
88
90
|
- name: Install protoc
|
|
89
91
|
uses: arduino/setup-protoc@v1
|
package/sdk-core/Cargo.toml
CHANGED
|
@@ -7,7 +7,14 @@ license = "MIT"
|
|
|
7
7
|
license-file = "LICENSE.txt"
|
|
8
8
|
|
|
9
9
|
[workspace.dependencies]
|
|
10
|
+
derive_builder = "0.20"
|
|
10
11
|
derive_more = { version = "0.99", default-features = false, features = ["constructor", "display", "from", "into"] }
|
|
11
|
-
|
|
12
|
-
tonic
|
|
13
|
-
|
|
12
|
+
once_cell = "1.16"
|
|
13
|
+
tonic = "0.11"
|
|
14
|
+
tonic-build = "0.11"
|
|
15
|
+
opentelemetry = "0.22"
|
|
16
|
+
prost = "0.12"
|
|
17
|
+
prost-types = "0.12"
|
|
18
|
+
|
|
19
|
+
[workspace.lints.rust]
|
|
20
|
+
unreachable_pub = "warn"
|
package/sdk-core/README.md
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
[](https://buildkite.com/temporal/core-sdk?branch=master)
|
|
2
|
-
|
|
3
1
|
# Temporal Core SDK
|
|
4
2
|
|
|
5
3
|
Core SDK that can be used as a base for other Temporal SDKs. It is currently used as the base of:
|
|
@@ -34,7 +32,7 @@ This repo is composed of multiple crates:
|
|
|
34
32
|
- temporal-sdk-core `./core` - The Core implementation
|
|
35
33
|
- temporal-sdk `./sdk` - A (currently prototype) Rust SDK built on top of Core. Used for testing.
|
|
36
34
|
- rustfsm `./fsm` - Implements a procedural macro used by core for defining state machines
|
|
37
|
-
|
|
35
|
+
(contains subcrates). It is temporal agnostic.
|
|
38
36
|
|
|
39
37
|
Visualized (dev dependencies are in blue):
|
|
40
38
|
|
|
@@ -51,7 +49,7 @@ You can build and test the project using cargo:
|
|
|
51
49
|
Run integ tests with `cargo integ-test`. By default it will start an ephemeral server. You can also
|
|
52
50
|
use an already-running server by passing `-s external`.
|
|
53
51
|
|
|
54
|
-
Run load tests with `cargo test --
|
|
52
|
+
Run load tests with `cargo test --test heavy_tests`.
|
|
55
53
|
|
|
56
54
|
## Formatting
|
|
57
55
|
|
|
@@ -86,8 +84,8 @@ equivalent.
|
|
|
86
84
|
|
|
87
85
|
## Proto files
|
|
88
86
|
|
|
89
|
-
This repo uses a subtree for upstream protobuf files. The path `sdk-core-protos/protos/api_upstream`
|
|
90
|
-
subtree. To update it, use:
|
|
87
|
+
This repo uses a subtree for upstream protobuf files. The path `sdk-core-protos/protos/api_upstream`
|
|
88
|
+
is a subtree. To update it, use:
|
|
91
89
|
|
|
92
90
|
`git pull --squash --rebase=false -s subtree ssh://git@github.com/temporalio/api.git master --allow-unrelated-histories`
|
|
93
91
|
|
|
@@ -10,19 +10,24 @@ repository = "https://github.com/temporalio/sdk-core"
|
|
|
10
10
|
keywords = ["temporal", "workflow"]
|
|
11
11
|
categories = ["development-tools"]
|
|
12
12
|
|
|
13
|
+
[features]
|
|
14
|
+
telemetry = ["dep:opentelemetry"]
|
|
15
|
+
|
|
13
16
|
[dependencies]
|
|
14
17
|
anyhow = "1.0"
|
|
15
18
|
async-trait = "0.1"
|
|
16
19
|
backoff = "0.4"
|
|
17
|
-
|
|
20
|
+
base64 = "0.22"
|
|
21
|
+
derive_builder = { workspace = true }
|
|
18
22
|
derive_more = "0.99"
|
|
19
23
|
futures = "0.3"
|
|
20
24
|
futures-retry = "0.6.0"
|
|
21
25
|
http = "0.2"
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
hyper = { version = "0.14" }
|
|
27
|
+
once_cell = { workspace = true }
|
|
28
|
+
opentelemetry = { workspace = true, features = ["metrics"], optional = true }
|
|
24
29
|
parking_lot = "0.12"
|
|
25
|
-
prost-types =
|
|
30
|
+
prost-types = { workspace = true }
|
|
26
31
|
slotmap = "1.0"
|
|
27
32
|
thiserror = "1.0"
|
|
28
33
|
tokio = "1.1"
|
|
@@ -40,4 +45,7 @@ path = "../core-api"
|
|
|
40
45
|
|
|
41
46
|
[dev-dependencies]
|
|
42
47
|
assert_matches = "1"
|
|
43
|
-
mockall = "0.
|
|
48
|
+
mockall = "0.12"
|
|
49
|
+
|
|
50
|
+
[lints]
|
|
51
|
+
workspace = true
|
|
@@ -8,12 +8,16 @@
|
|
|
8
8
|
extern crate tracing;
|
|
9
9
|
|
|
10
10
|
mod metrics;
|
|
11
|
+
mod proxy;
|
|
11
12
|
mod raw;
|
|
12
13
|
mod retry;
|
|
13
14
|
mod worker_registry;
|
|
14
15
|
mod workflow_handle;
|
|
15
16
|
|
|
16
|
-
pub use crate::
|
|
17
|
+
pub use crate::{
|
|
18
|
+
proxy::HttpConnectProxyOptions,
|
|
19
|
+
retry::{CallType, RetryClient, RETRYABLE_ERROR_CODES},
|
|
20
|
+
};
|
|
17
21
|
pub use raw::{HealthService, OperatorService, TestService, WorkflowService};
|
|
18
22
|
pub use temporal_sdk_core_protos::temporal::api::{
|
|
19
23
|
enums::v1::ArchivalState,
|
|
@@ -25,7 +29,9 @@ pub use temporal_sdk_core_protos::temporal::api::{
|
|
|
25
29
|
};
|
|
26
30
|
pub use tonic;
|
|
27
31
|
pub use worker_registry::{Slot, SlotManager, SlotProvider, WorkerKey};
|
|
28
|
-
pub use workflow_handle::{
|
|
32
|
+
pub use workflow_handle::{
|
|
33
|
+
GetWorkflowResultOpts, WorkflowExecutionInfo, WorkflowExecutionResult, WorkflowHandle,
|
|
34
|
+
};
|
|
29
35
|
|
|
30
36
|
use crate::{
|
|
31
37
|
metrics::{GrpcMetricSvc, MetricsContext},
|
|
@@ -67,7 +73,7 @@ use tonic::{
|
|
|
67
73
|
body::BoxBody,
|
|
68
74
|
client::GrpcService,
|
|
69
75
|
codegen::InterceptedService,
|
|
70
|
-
metadata::{MetadataKey, MetadataValue},
|
|
76
|
+
metadata::{MetadataKey, MetadataMap, MetadataValue},
|
|
71
77
|
service::Interceptor,
|
|
72
78
|
transport::{Certificate, Channel, Endpoint, Identity},
|
|
73
79
|
Code, Status,
|
|
@@ -133,6 +139,23 @@ pub struct ClientOptions {
|
|
|
133
139
|
/// If set (which it is by default), HTTP2 gRPC keep alive will be enabled.
|
|
134
140
|
#[builder(default = "Some(ClientKeepAliveConfig::default())")]
|
|
135
141
|
pub keep_alive: Option<ClientKeepAliveConfig>,
|
|
142
|
+
|
|
143
|
+
/// HTTP headers to include on every RPC call.
|
|
144
|
+
#[builder(default)]
|
|
145
|
+
pub headers: Option<HashMap<String, String>>,
|
|
146
|
+
|
|
147
|
+
/// API key which is set as the "Authorization" header with "Bearer " prepended. This will only
|
|
148
|
+
/// be applied if the headers don't already have an "Authorization" header.
|
|
149
|
+
#[builder(default)]
|
|
150
|
+
pub api_key: Option<String>,
|
|
151
|
+
|
|
152
|
+
/// HTTP CONNECT proxy to use for this client.
|
|
153
|
+
#[builder(default)]
|
|
154
|
+
pub http_connect_proxy: Option<HttpConnectProxyOptions>,
|
|
155
|
+
|
|
156
|
+
/// If set true, error code labels will not be included on request failure metrics.
|
|
157
|
+
#[builder(default)]
|
|
158
|
+
pub disable_error_code_metric_tags: bool,
|
|
136
159
|
}
|
|
137
160
|
|
|
138
161
|
/// Configuration options for TLS
|
|
@@ -200,7 +223,7 @@ impl Default for RetryConfig {
|
|
|
200
223
|
Self {
|
|
201
224
|
initial_interval: Duration::from_millis(100), // 100 ms wait by default.
|
|
202
225
|
randomization_factor: 0.2, // +-20% jitter.
|
|
203
|
-
multiplier: 1.
|
|
226
|
+
multiplier: 1.7, // each next retry delay will increase by 70%
|
|
204
227
|
max_interval: Duration::from_secs(5), // until it reaches 5 seconds.
|
|
205
228
|
max_elapsed_time: Some(Duration::from_secs(10)), // 10 seconds total allocated time for all retries.
|
|
206
229
|
max_retries: 10,
|
|
@@ -279,7 +302,7 @@ pub enum ClientInitError {
|
|
|
279
302
|
pub struct ConfiguredClient<C> {
|
|
280
303
|
client: C,
|
|
281
304
|
options: Arc<ClientOptions>,
|
|
282
|
-
headers: Arc<RwLock<
|
|
305
|
+
headers: Arc<RwLock<ClientHeaders>>,
|
|
283
306
|
/// Capabilities as read from the `get_system_info` RPC call made on client connection
|
|
284
307
|
capabilities: Option<get_system_info_response::Capabilities>,
|
|
285
308
|
workers: Arc<SlotManager>,
|
|
@@ -288,8 +311,12 @@ pub struct ConfiguredClient<C> {
|
|
|
288
311
|
impl<C> ConfiguredClient<C> {
|
|
289
312
|
/// Set HTTP request headers overwriting previous headers
|
|
290
313
|
pub fn set_headers(&self, headers: HashMap<String, String>) {
|
|
291
|
-
|
|
292
|
-
|
|
314
|
+
self.headers.write().user_headers = headers;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/// Set API key, overwriting previous
|
|
318
|
+
pub fn set_api_key(&self, api_key: Option<String>) {
|
|
319
|
+
self.headers.write().api_key = api_key;
|
|
293
320
|
}
|
|
294
321
|
|
|
295
322
|
/// Returns the options the client is configured with
|
|
@@ -309,6 +336,34 @@ impl<C> ConfiguredClient<C> {
|
|
|
309
336
|
}
|
|
310
337
|
}
|
|
311
338
|
|
|
339
|
+
#[derive(Debug)]
|
|
340
|
+
struct ClientHeaders {
|
|
341
|
+
user_headers: HashMap<String, String>,
|
|
342
|
+
api_key: Option<String>,
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
impl ClientHeaders {
|
|
346
|
+
fn apply_to_metadata(&self, metadata: &mut MetadataMap) {
|
|
347
|
+
for (key, val) in self.user_headers.iter() {
|
|
348
|
+
// Only if not already present
|
|
349
|
+
if !metadata.contains_key(key) {
|
|
350
|
+
// Ignore invalid keys/values
|
|
351
|
+
if let (Ok(key), Ok(val)) = (MetadataKey::from_str(key), val.parse()) {
|
|
352
|
+
metadata.insert(key, val);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if let Some(api_key) = &self.api_key {
|
|
357
|
+
// Only if not already present
|
|
358
|
+
if !metadata.contains_key("authorization") {
|
|
359
|
+
if let Ok(val) = format!("Bearer {}", api_key).parse() {
|
|
360
|
+
metadata.insert("authorization", val);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
312
367
|
// The configured client is effectively a "smart" (dumb) pointer
|
|
313
368
|
impl<C> Deref for ConfiguredClient<C> {
|
|
314
369
|
type Target = C;
|
|
@@ -331,12 +386,8 @@ impl ClientOptions {
|
|
|
331
386
|
&self,
|
|
332
387
|
namespace: impl Into<String>,
|
|
333
388
|
metrics_meter: Option<TemporalMeter>,
|
|
334
|
-
headers: Option<Arc<RwLock<HashMap<String, String>>>>,
|
|
335
389
|
) -> Result<RetryClient<Client>, ClientInitError> {
|
|
336
|
-
let client = self
|
|
337
|
-
.connect_no_namespace(metrics_meter, headers)
|
|
338
|
-
.await?
|
|
339
|
-
.into_inner();
|
|
390
|
+
let client = self.connect_no_namespace(metrics_meter).await?.into_inner();
|
|
340
391
|
let client = Client::new(client, namespace.into());
|
|
341
392
|
let retry_client = RetryClient::new(client, self.retry_config.clone());
|
|
342
393
|
Ok(retry_client)
|
|
@@ -349,7 +400,6 @@ impl ClientOptions {
|
|
|
349
400
|
pub async fn connect_no_namespace(
|
|
350
401
|
&self,
|
|
351
402
|
metrics_meter: Option<TemporalMeter>,
|
|
352
|
-
headers: Option<Arc<RwLock<HashMap<String, String>>>>,
|
|
353
403
|
) -> Result<RetryClient<ConfiguredClient<TemporalServiceClientWithMetrics>>, ClientInitError>
|
|
354
404
|
{
|
|
355
405
|
let channel = Channel::from_shared(self.target_url.to_string())?;
|
|
@@ -367,14 +417,23 @@ impl ClientOptions {
|
|
|
367
417
|
} else {
|
|
368
418
|
channel
|
|
369
419
|
};
|
|
370
|
-
|
|
420
|
+
// If there is a proxy, we have to connect that way
|
|
421
|
+
let channel = if let Some(proxy) = self.http_connect_proxy.as_ref() {
|
|
422
|
+
proxy.connect_endpoint(&channel).await?
|
|
423
|
+
} else {
|
|
424
|
+
channel.connect().await?
|
|
425
|
+
};
|
|
371
426
|
let service = ServiceBuilder::new()
|
|
372
427
|
.layer_fn(move |channel| GrpcMetricSvc {
|
|
373
428
|
inner: channel,
|
|
374
429
|
metrics: metrics_meter.clone().map(MetricsContext::new),
|
|
430
|
+
disable_errcode_label: self.disable_error_code_metric_tags,
|
|
375
431
|
})
|
|
376
432
|
.service(channel);
|
|
377
|
-
let headers =
|
|
433
|
+
let headers = Arc::new(RwLock::new(ClientHeaders {
|
|
434
|
+
user_headers: self.headers.clone().unwrap_or_default(),
|
|
435
|
+
api_key: self.api_key.clone(),
|
|
436
|
+
}));
|
|
378
437
|
let interceptor = ServiceCallInterceptor {
|
|
379
438
|
opts: self.clone(),
|
|
380
439
|
headers: headers.clone(),
|
|
@@ -442,7 +501,7 @@ impl ClientOptions {
|
|
|
442
501
|
pub struct ServiceCallInterceptor {
|
|
443
502
|
opts: ClientOptions,
|
|
444
503
|
/// Only accessed as a reader
|
|
445
|
-
headers: Arc<RwLock<
|
|
504
|
+
headers: Arc<RwLock<ClientHeaders>>,
|
|
446
505
|
}
|
|
447
506
|
|
|
448
507
|
impl Interceptor for ServiceCallInterceptor {
|
|
@@ -468,16 +527,7 @@ impl Interceptor for ServiceCallInterceptor {
|
|
|
468
527
|
.unwrap_or_else(|_| MetadataValue::from_static("")),
|
|
469
528
|
);
|
|
470
529
|
}
|
|
471
|
-
|
|
472
|
-
for (k, v) in headers {
|
|
473
|
-
if metadata.contains_key(k) {
|
|
474
|
-
// Don't overwrite per-request specified headers
|
|
475
|
-
continue;
|
|
476
|
-
}
|
|
477
|
-
if let (Ok(k), Ok(v)) = (MetadataKey::from_str(k), v.parse()) {
|
|
478
|
-
metadata.insert(k, v);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
530
|
+
self.headers.read().apply_to_metadata(metadata);
|
|
481
531
|
if !metadata.contains_key("grpc-timeout") {
|
|
482
532
|
request.set_timeout(OTHER_CALL_TIMEOUT);
|
|
483
533
|
}
|
|
@@ -1559,7 +1609,7 @@ mod tests {
|
|
|
1559
1609
|
use super::*;
|
|
1560
1610
|
|
|
1561
1611
|
#[test]
|
|
1562
|
-
fn
|
|
1612
|
+
fn applies_headers() {
|
|
1563
1613
|
let opts = ClientOptionsBuilder::default()
|
|
1564
1614
|
.identity("enchicat".to_string())
|
|
1565
1615
|
.target_url(Url::parse("https://smolkitty").unwrap())
|
|
@@ -1568,16 +1618,55 @@ mod tests {
|
|
|
1568
1618
|
.build()
|
|
1569
1619
|
.unwrap();
|
|
1570
1620
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1621
|
+
// Initial header set
|
|
1622
|
+
let headers = Arc::new(RwLock::new(ClientHeaders {
|
|
1623
|
+
user_headers: HashMap::new(),
|
|
1624
|
+
api_key: Some("my-api-key".to_owned()),
|
|
1625
|
+
}));
|
|
1626
|
+
headers
|
|
1627
|
+
.clone()
|
|
1628
|
+
.write()
|
|
1629
|
+
.user_headers
|
|
1630
|
+
.insert("my-meta-key".to_owned(), "my-meta-val".to_owned());
|
|
1631
|
+
let mut interceptor = ServiceCallInterceptor {
|
|
1574
1632
|
opts,
|
|
1575
|
-
headers:
|
|
1633
|
+
headers: headers.clone(),
|
|
1576
1634
|
};
|
|
1635
|
+
|
|
1636
|
+
// Confirm on metadata
|
|
1637
|
+
let req = interceptor.call(tonic::Request::new(())).unwrap();
|
|
1638
|
+
assert_eq!(req.metadata().get("my-meta-key").unwrap(), "my-meta-val");
|
|
1639
|
+
assert_eq!(
|
|
1640
|
+
req.metadata().get("authorization").unwrap(),
|
|
1641
|
+
"Bearer my-api-key"
|
|
1642
|
+
);
|
|
1643
|
+
|
|
1644
|
+
// Overwrite at request time
|
|
1577
1645
|
let mut req = tonic::Request::new(());
|
|
1578
|
-
req.metadata_mut()
|
|
1579
|
-
|
|
1580
|
-
|
|
1646
|
+
req.metadata_mut()
|
|
1647
|
+
.insert("my-meta-key", "my-meta-val2".parse().unwrap());
|
|
1648
|
+
req.metadata_mut()
|
|
1649
|
+
.insert("authorization", "my-api-key2".parse().unwrap());
|
|
1650
|
+
let req = interceptor.call(req).unwrap();
|
|
1651
|
+
assert_eq!(req.metadata().get("my-meta-key").unwrap(), "my-meta-val2");
|
|
1652
|
+
assert_eq!(req.metadata().get("authorization").unwrap(), "my-api-key2");
|
|
1653
|
+
|
|
1654
|
+
// Overwrite auth on header
|
|
1655
|
+
headers
|
|
1656
|
+
.clone()
|
|
1657
|
+
.write()
|
|
1658
|
+
.user_headers
|
|
1659
|
+
.insert("authorization".to_owned(), "my-api-key3".to_owned());
|
|
1660
|
+
let req = interceptor.call(tonic::Request::new(())).unwrap();
|
|
1661
|
+
assert_eq!(req.metadata().get("my-meta-key").unwrap(), "my-meta-val");
|
|
1662
|
+
assert_eq!(req.metadata().get("authorization").unwrap(), "my-api-key3");
|
|
1663
|
+
|
|
1664
|
+
// Remove headers and auth and confirm gone
|
|
1665
|
+
headers.clone().write().user_headers.clear();
|
|
1666
|
+
headers.clone().write().api_key.take();
|
|
1667
|
+
let req = interceptor.call(tonic::Request::new(())).unwrap();
|
|
1668
|
+
assert!(!req.metadata().contains_key("my-meta-key"));
|
|
1669
|
+
assert!(!req.metadata().contains_key("authorization"));
|
|
1581
1670
|
}
|
|
1582
1671
|
|
|
1583
1672
|
#[test]
|