Skip to content

Commit 3a14d07

Browse files
committed
Expose gRPC compression options
1 parent 351607d commit 3a14d07

5 files changed

Lines changed: 99 additions & 7 deletions

File tree

packages/core-bridge/src/client.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub fn client_new(
5252
) -> BridgeResult<BridgeFuture<OpaqueOutboundHandle<Client>>> {
5353
let runtime = runtime.borrow()?.core_runtime.clone();
5454
let metric_meter = runtime.telemetry().get_temporal_metric_meter();
55-
let options = config.into_connection_options(metric_meter);
55+
let options = config.into_connection_options(metric_meter)?;
5656

5757
runtime.clone().future_to_promise(async move {
5858
let core_connection = match Connection::connect(options).await {
@@ -621,15 +621,19 @@ mod config {
621621

622622
use temporalio_client::{
623623
ClientTlsOptions as CoreClientTlsOptions, ConnectionOptions, DnsLoadBalancingOptions,
624-
HttpConnectProxyOptions, TlsOptions as CoreTlsOptions,
624+
GrpcCompression as CoreGrpcCompression, HttpConnectProxyOptions,
625+
TlsOptions as CoreTlsOptions,
625626
};
626627
use temporalio_common::telemetry::metrics::TemporalMeter;
627628
use temporalio_sdk_core::Url;
628629
use tracing::warn;
629630

630631
use bridge_macros::TryFromJs;
631632

632-
use crate::client::MetadataValue;
633+
use crate::{
634+
client::MetadataValue,
635+
helpers::{BridgeError, BridgeResult},
636+
};
633637

634638
#[derive(Debug, Clone, TryFromJs)]
635639
pub(super) struct ClientOptions {
@@ -639,6 +643,7 @@ mod config {
639643
tls: Option<TlsOptions>,
640644
http_connect_proxy: Option<HttpConnectProxy>,
641645
dns_load_balancing_config: Option<DnsLoadBalancingConfig>,
646+
grpc_compression: Option<GrpcCompressionConfig>,
642647
headers: Option<HashMap<String, MetadataValue>>,
643648
api_key: Option<String>,
644649
disable_error_code_metric_tags: bool,
@@ -675,11 +680,16 @@ mod config {
675680
resolution_interval_millis: u64,
676681
}
677682

683+
#[derive(Debug, Clone, TryFromJs)]
684+
struct GrpcCompressionConfig {
685+
codec: String,
686+
}
687+
678688
impl ClientOptions {
679689
pub(super) fn into_connection_options(
680690
self,
681691
metrics_meter: Option<TemporalMeter>,
682-
) -> ConnectionOptions {
692+
) -> BridgeResult<ConnectionOptions> {
683693
let (ascii_headers, bin_headers) = partition_headers(self.headers);
684694
let has_http_connect_proxy = self.http_connect_proxy.is_some();
685695
// Core rejects DNS load balancing alongside an HTTP CONNECT proxy, so
@@ -694,13 +704,17 @@ mod config {
694704
self.dns_load_balancing_config.map(Into::into)
695705
};
696706
let http_connect_proxy = self.http_connect_proxy.map(Into::into);
707+
let grpc_compression = self
708+
.grpc_compression
709+
.map_or(Ok(CoreGrpcCompression::Gzip), TryInto::try_into)?;
697710

698-
ConnectionOptions::new(self.target_url)
711+
Ok(ConnectionOptions::new(self.target_url)
699712
.client_name(self.client_name)
700713
.client_version(self.client_version)
701714
.maybe_tls_options(self.tls.map(Into::into))
702715
.maybe_http_connect_proxy(http_connect_proxy)
703716
.dns_load_balancing(dns_load_balancing)
717+
.grpc_compression(grpc_compression)
704718
.maybe_headers(ascii_headers)
705719
.maybe_binary_headers(bin_headers)
706720
.maybe_api_key(self.api_key)
@@ -711,7 +725,22 @@ mod config {
711725
// override_origin -- skipped: will default to tls_cfg.domain
712726
// keep_alive -- skipped: defaults to true; is there any reason to disable this?
713727
// skip_get_system_info -- skipped: defaults to false; is there any reason to set this?
714-
.build()
728+
.build())
729+
}
730+
}
731+
732+
impl TryFrom<GrpcCompressionConfig> for CoreGrpcCompression {
733+
type Error = BridgeError;
734+
735+
fn try_from(val: GrpcCompressionConfig) -> Result<Self, Self::Error> {
736+
match val.codec.as_str() {
737+
"gzip" => Ok(Self::Gzip),
738+
"none" => Ok(Self::None),
739+
codec => Err(BridgeError::InvalidVariant {
740+
enum_name: "GrpcCompressionConfig".to_string(),
741+
variant: codec.to_string(),
742+
}),
743+
}
715744
}
716745
}
717746

packages/core-bridge/ts/native.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export interface ClientOptions {
136136
tls: Option<TlsOptions>;
137137
httpConnectProxy: Option<HttpConnectProxy>;
138138
dnsLoadBalancingConfig: Option<DnsLoadBalancingConfig>;
139+
grpcCompression?: GrpcCompressionConfig;
139140
headers: Option<Record<string, MetadataValue>>;
140141
apiKey: Option<string>;
141142
disableErrorCodeMetricTags: boolean;
@@ -169,6 +170,16 @@ export interface DnsLoadBalancingConfig {
169170
resolutionIntervalMillis: number;
170171
}
171172

173+
export type GrpcCompressionConfig = GzipGrpcCompressionConfig | NoneGrpcCompressionConfig;
174+
175+
export interface GzipGrpcCompressionConfig {
176+
codec: 'gzip';
177+
}
178+
179+
export interface NoneGrpcCompressionConfig {
180+
codec: 'none';
181+
}
182+
172183
export interface RpcCall {
173184
rpc: string;
174185
req: Buffer;

packages/test/src/test-native-connection.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,13 @@ test('NativeConnection: DNS load balancing config is converted to native millise
510510
});
511511
t.deepEqual(options.dnsLoadBalancingConfig, { resolutionIntervalMillis: 5000 });
512512
});
513+
514+
test('NativeConnection: gRPC compression defaults to gzip', (t) => {
515+
const options = toNativeClientOptions({});
516+
t.deepEqual(options.grpcCompression, { codec: 'gzip' });
517+
});
518+
519+
test('NativeConnection: gRPC compression can be disabled', (t) => {
520+
const options = toNativeClientOptions({ grpcCompression: { codec: 'none' } });
521+
t.deepEqual(options.grpcCompression, { codec: 'none' });
522+
});

packages/worker/src/connection-options.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@ export interface DNSLoadBalancingConfig {
2525
resolutionInterval: Duration;
2626
}
2727

28+
/**
29+
* Use gzip for transport-level gRPC compression.
30+
*/
31+
export interface GzipGrpcCompressionConfig {
32+
codec: 'gzip';
33+
}
34+
35+
/**
36+
* Disable transport-level gRPC compression.
37+
*/
38+
export interface NoneGrpcCompressionConfig {
39+
codec: 'none';
40+
}
41+
42+
/**
43+
* Transport-level gRPC compression configuration.
44+
*/
45+
export type GrpcCompressionConfig = GzipGrpcCompressionConfig | NoneGrpcCompressionConfig;
46+
2847
/**
2948
* The default Temporal Server's TCP port for public gRPC connections.
3049
*/
@@ -64,6 +83,14 @@ export interface NativeConnectionOptions {
6483
*/
6584
dnsLoadBalancingConfig?: DNSLoadBalancingConfig | null;
6685

86+
/**
87+
* Transport-level gRPC compression configuration for Core service requests.
88+
*
89+
* Defaults to gzip, which compresses outbound request bodies and accepts
90+
* gzip-compressed responses. Set to `{ codec: 'none' }` to opt out.
91+
*/
92+
grpcCompression?: GrpcCompressionConfig;
93+
6794
/**
6895
* Optional mapping of gRPC metadata (HTTP headers) to send with each request to the server.
6996
*
@@ -138,6 +165,15 @@ export function toNativeClientOptions(options: NativeConnectionOptions): native.
138165
}
139166
: null;
140167

168+
const grpcCompression: native.GrpcCompressionConfig = options.grpcCompression ?? { codec: 'gzip' };
169+
switch (grpcCompression.codec) {
170+
case 'gzip':
171+
case 'none':
172+
break;
173+
default:
174+
throw new TypeError(`Unsupported gRPC compression codec: ${(grpcCompression as { codec: string }).codec}`);
175+
}
176+
141177
if (options?.apiKey && options.metadata?.['Authorization']) {
142178
throw new TypeError(
143179
'Both `apiKey` option and `Authorization` header were provided. Only one makes sense to use at a time.'
@@ -163,6 +199,7 @@ export function toNativeClientOptions(options: NativeConnectionOptions): native.
163199
tls,
164200
httpConnectProxy,
165201
dnsLoadBalancingConfig,
202+
grpcCompression,
166203
headers,
167204
apiKey: options.apiKey ?? null,
168205
disableErrorCodeMetricTags: options.disableErrorCodeMetricTags ?? false,

packages/worker/src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@
3535
*/
3636

3737
export { NativeConnection, NativeConnectionPlugin } from './connection';
38-
export { DNSLoadBalancingConfig, NativeConnectionOptions, TLSConfig } from './connection-options';
38+
export {
39+
DNSLoadBalancingConfig,
40+
GrpcCompressionConfig,
41+
NativeConnectionOptions,
42+
TLSConfig,
43+
} from './connection-options';
3944
export { startDebugReplayer } from './debug-replayer';
4045
export { IllegalStateError } from '@temporalio/common';
4146
export {

0 commit comments

Comments
 (0)