@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.
Files changed (177) hide show
  1. package/Cargo.lock +754 -473
  2. package/Cargo.toml +3 -3
  3. package/lib/index.d.ts +33 -2
  4. package/lib/index.js.map +1 -1
  5. package/package.json +4 -4
  6. package/releases/aarch64-apple-darwin/index.node +0 -0
  7. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  8. package/releases/x86_64-apple-darwin/index.node +0 -0
  9. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  10. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  11. package/scripts/build.js +4 -3
  12. package/sdk-core/.cargo/config.toml +2 -4
  13. package/sdk-core/.github/workflows/heavy.yml +1 -1
  14. package/sdk-core/.github/workflows/per-pr.yml +6 -4
  15. package/sdk-core/Cargo.toml +10 -3
  16. package/sdk-core/README.md +4 -6
  17. package/sdk-core/client/Cargo.toml +13 -5
  18. package/sdk-core/client/src/lib.rs +123 -34
  19. package/sdk-core/client/src/metrics.rs +70 -18
  20. package/sdk-core/client/src/proxy.rs +85 -0
  21. package/sdk-core/client/src/raw.rs +67 -5
  22. package/sdk-core/client/src/worker_registry/mod.rs +5 -3
  23. package/sdk-core/client/src/workflow_handle/mod.rs +3 -1
  24. package/sdk-core/core/Cargo.toml +31 -37
  25. package/sdk-core/core/src/abstractions/take_cell.rs +3 -3
  26. package/sdk-core/core/src/abstractions.rs +176 -108
  27. package/sdk-core/core/src/core_tests/activity_tasks.rs +4 -13
  28. package/sdk-core/core/src/core_tests/determinism.rs +2 -1
  29. package/sdk-core/core/src/core_tests/local_activities.rs +3 -3
  30. package/sdk-core/core/src/core_tests/mod.rs +3 -3
  31. package/sdk-core/core/src/core_tests/queries.rs +42 -5
  32. package/sdk-core/core/src/core_tests/workers.rs +2 -3
  33. package/sdk-core/core/src/core_tests/workflow_tasks.rs +115 -15
  34. package/sdk-core/core/src/ephemeral_server/mod.rs +109 -136
  35. package/sdk-core/core/src/internal_flags.rs +8 -8
  36. package/sdk-core/core/src/lib.rs +16 -11
  37. package/sdk-core/core/src/pollers/mod.rs +11 -5
  38. package/sdk-core/core/src/pollers/poll_buffer.rs +48 -29
  39. package/sdk-core/core/src/protosext/mod.rs +32 -32
  40. package/sdk-core/core/src/protosext/protocol_messages.rs +14 -24
  41. package/sdk-core/core/src/retry_logic.rs +2 -2
  42. package/sdk-core/core/src/telemetry/log_export.rs +10 -9
  43. package/sdk-core/core/src/telemetry/metrics.rs +233 -330
  44. package/sdk-core/core/src/telemetry/mod.rs +11 -38
  45. package/sdk-core/core/src/telemetry/otel.rs +355 -0
  46. package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -23
  47. package/sdk-core/core/src/test_help/mod.rs +80 -59
  48. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +6 -6
  49. package/sdk-core/core/src/worker/activities/local_activities.rs +46 -43
  50. package/sdk-core/core/src/worker/activities.rs +45 -46
  51. package/sdk-core/core/src/worker/client/mocks.rs +8 -7
  52. package/sdk-core/core/src/worker/client.rs +40 -39
  53. package/sdk-core/core/src/worker/mod.rs +72 -42
  54. package/sdk-core/core/src/worker/slot_provider.rs +28 -28
  55. package/sdk-core/core/src/worker/slot_supplier.rs +1 -0
  56. package/sdk-core/core/src/worker/tuner/fixed_size.rs +52 -0
  57. package/sdk-core/core/src/worker/tuner/resource_based.rs +561 -0
  58. package/sdk-core/core/src/worker/tuner.rs +122 -0
  59. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +6 -6
  60. package/sdk-core/core/src/worker/workflow/history_update.rs +27 -53
  61. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +4 -17
  62. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -10
  63. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +4 -11
  64. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +17 -35
  65. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -8
  66. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -5
  67. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -5
  68. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -5
  69. package/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -14
  70. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -5
  71. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -5
  72. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -10
  73. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +3 -10
  74. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +12 -8
  75. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +0 -10
  76. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -13
  77. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +27 -37
  78. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +3 -14
  79. package/sdk-core/core/src/worker/workflow/managed_run.rs +84 -54
  80. package/sdk-core/core/src/worker/workflow/mod.rs +63 -160
  81. package/sdk-core/core/src/worker/workflow/run_cache.rs +22 -13
  82. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +16 -3
  83. package/sdk-core/core/src/worker/workflow/wft_poller.rs +15 -12
  84. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +39 -78
  85. package/sdk-core/core-api/Cargo.toml +6 -5
  86. package/sdk-core/core-api/src/errors.rs +8 -0
  87. package/sdk-core/core-api/src/telemetry/metrics.rs +75 -4
  88. package/sdk-core/core-api/src/telemetry.rs +7 -1
  89. package/sdk-core/core-api/src/worker.rs +212 -56
  90. package/sdk-core/fsm/Cargo.toml +3 -0
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  92. package/sdk-core/sdk/Cargo.toml +5 -7
  93. package/sdk-core/sdk/src/app_data.rs +3 -3
  94. package/sdk-core/sdk/src/lib.rs +5 -3
  95. package/sdk-core/sdk/src/workflow_context/options.rs +1 -1
  96. package/sdk-core/sdk/src/workflow_context.rs +10 -9
  97. package/sdk-core/sdk/src/workflow_future.rs +1 -1
  98. package/sdk-core/sdk-core-protos/Cargo.toml +8 -6
  99. package/sdk-core/sdk-core-protos/build.rs +1 -10
  100. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +3 -0
  101. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/ci.yml +26 -0
  102. package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +42 -20
  103. package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +2 -0
  104. package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +36 -26
  105. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +2 -0
  106. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/struct.proto +95 -0
  107. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +9632 -0
  108. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +7337 -0
  109. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/payload_description.txt +2 -0
  110. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +45 -11
  111. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +22 -4
  112. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/command_type.proto +2 -0
  113. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +44 -0
  114. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +18 -3
  115. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -0
  116. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +30 -0
  117. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/update.proto +7 -8
  118. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +23 -5
  119. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/errordetails/v1/message.proto +20 -0
  120. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +25 -0
  121. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +141 -15
  122. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +12 -0
  123. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +193 -0
  124. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +73 -6
  125. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +46 -4
  126. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +4 -0
  127. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +2 -2
  128. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +116 -0
  129. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +134 -0
  130. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +274 -29
  131. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +57 -1
  132. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +10 -12
  133. package/sdk-core/sdk-core-protos/src/history_builder.rs +1 -1
  134. package/sdk-core/sdk-core-protos/src/lib.rs +54 -51
  135. package/sdk-core/sdk-core-protos/src/task_token.rs +11 -2
  136. package/sdk-core/test-utils/Cargo.toml +7 -4
  137. package/sdk-core/test-utils/src/histfetch.rs +1 -1
  138. package/sdk-core/test-utils/src/lib.rs +44 -62
  139. package/sdk-core/tests/fuzzy_workflow.rs +5 -2
  140. package/sdk-core/tests/heavy_tests.rs +114 -17
  141. package/sdk-core/tests/integ_tests/activity_functions.rs +1 -1
  142. package/sdk-core/tests/integ_tests/client_tests.rs +2 -2
  143. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +38 -26
  144. package/sdk-core/tests/integ_tests/metrics_tests.rs +126 -17
  145. package/sdk-core/tests/integ_tests/polling_tests.rs +118 -2
  146. package/sdk-core/tests/integ_tests/update_tests.rs +3 -5
  147. package/sdk-core/tests/integ_tests/visibility_tests.rs +3 -3
  148. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +1 -1
  149. package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
  150. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
  151. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  152. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +3 -3
  153. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -4
  154. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -2
  155. package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +6 -10
  156. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +9 -7
  157. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -1
  158. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +14 -9
  159. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
  160. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +6 -13
  161. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +9 -6
  162. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +5 -5
  163. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
  164. package/sdk-core/tests/integ_tests/workflow_tests.rs +115 -11
  165. package/sdk-core/tests/main.rs +2 -2
  166. package/src/conversions.rs +57 -0
  167. package/src/lib.rs +1 -0
  168. package/src/runtime.rs +51 -35
  169. package/ts/index.ts +67 -3
  170. package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
  171. package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
  172. package/sdk-core/sdk/src/payload_converter.rs +0 -11
  173. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +0 -2
  174. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/docker-compose.yml +0 -15
  175. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/pipeline.yml +0 -10
  176. package/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
  177. 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.18"
23
+ opentelemetry = "0.22"
24
24
  parking_lot = "0.12"
25
- prost = "0.11"
26
- prost-types = "0.11"
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":";;;AAsfA,mCAA0E;AAAjE,uGAAA,aAAa,OAAA;AAAE,wGAAA,cAAc,OAAA;AAAE,yGAAA,eAAe,OAAA"}
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.9.2",
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": "^1.9.2",
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": "5fd66f5787deece0b30f085808db7651187600b1"
55
+ "gitHead": "39d702af7ae5d7e33ee90651292aa77fa07d33ca"
56
56
  }
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
- "--test", "integ_tests", "--test", "heavy_tests", "--", "--D", "warnings"]
4
+ "--test", "integ_tests", "--test", "heavy_tests", "--", "--D", "warnings"]
7
5
  test-lint = ["clippy", "--all", "--all-features", "--examples", "--workspace",
8
- "--tests", "--", "--D", "warnings"]
6
+ "--tests", "--", "--D", "warnings"]
@@ -30,4 +30,4 @@ jobs:
30
30
  - uses: actions-rs/cargo@v1
31
31
  with:
32
32
  command: integ-test
33
- args: -c "--release" -c "--features=save_wf_inputs" -t heavy_tests -- --test-threads 1
33
+ args: -c "--release" -t heavy_tests -- --test-threads 1
@@ -13,7 +13,7 @@ concurrency:
13
13
  jobs:
14
14
  build-and-test:
15
15
  name: "Format, docs, and lint"
16
- timeout-minutes: 20
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.74.0
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.74.0
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.74.0
88
+ toolchain: 1.77.0
87
89
  override: true
88
90
  - name: Install protoc
89
91
  uses: arduino/setup-protoc@v1
@@ -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
- tonic = "0.9"
12
- tonic-build = "0.9"
13
- opentelemetry = "0.21"
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"
@@ -1,5 +1,3 @@
1
- [![Build status](https://badge.buildkite.com/c23f47f4a827f04daece909963bd3a248496f0cdbabfbecee4.svg?branch=master)](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
- (contains subcrates). It is temporal agnostic.
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 --features=save_wf_inputs --test heavy_tests`.
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` is a
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
- derive_builder = "0.12"
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
- once_cell = "1.13"
23
- opentelemetry = { workspace = true, features = ["metrics"] }
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 = "0.11"
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.11"
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::retry::{CallType, RetryClient, RETRYABLE_ERROR_CODES};
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::{WorkflowExecutionInfo, WorkflowExecutionResult};
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.5, // each next retry delay will increase by 50%
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<HashMap<String, String>>>,
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
- let mut guard = self.headers.write();
292
- *guard = headers;
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
- let channel = channel.connect().await?;
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 = headers.unwrap_or_default();
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<HashMap<String, String>>>,
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
- let headers = &*self.headers.read();
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 respects_per_call_headers() {
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
- let mut static_headers = HashMap::new();
1572
- static_headers.insert("enchi".to_string(), "kitty".to_string());
1573
- let mut iceptor = ServiceCallInterceptor {
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: Arc::new(RwLock::new(static_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().insert("enchi", "cat".parse().unwrap());
1579
- let next_req = iceptor.call(req).unwrap();
1580
- assert_eq!(next_req.metadata().get("enchi").unwrap(), "cat");
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]