From 1bfd5e31cfa55dc534e56ae3a3798f3eb51d6db4 Mon Sep 17 00:00:00 2001 From: feywind <57276408+feywind@users.noreply.github.com> Date: Fri, 16 Oct 2026 19:49:14 +0000 Subject: [PATCH] feat(pubsub): add enabled option to HedgingOptions (post-merge adjustments) --- handwritten/pubsub/src/default-options.ts | 3 +++ handwritten/pubsub/src/publisher/hedging.ts | 13 +++++++++++++ handwritten/pubsub/system-test/hedging.test.ts | 8 ++++++++ handwritten/pubsub/test/publisher/hedging.ts | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/handwritten/pubsub/src/default-options.ts b/handwritten/pubsub/src/default-options.ts index d499f087cfc..83319ccb66e 100644 --- a/handwritten/pubsub/src/default-options.ts +++ b/handwritten/pubsub/src/default-options.ts @@ -57,6 +57,9 @@ export const defaultOptions = { maxDelayMillis: 10, hedging: { + // Whether publish hedging is enabled when hedging options are provided. + enabled: true, + // The default delay before sending a hedged publish RPC. hedgeDelay: Duration.from({milliseconds: 1000}), diff --git a/handwritten/pubsub/src/publisher/hedging.ts b/handwritten/pubsub/src/publisher/hedging.ts index 383fdf51093..a37d19eac86 100644 --- a/handwritten/pubsub/src/publisher/hedging.ts +++ b/handwritten/pubsub/src/publisher/hedging.ts @@ -80,6 +80,12 @@ const HEDGE_TOKEN_SCALE = 1000; * Settings for configuring publish hedging. */ export interface HedgingOptions { + /** + * Whether publish hedging is enabled. + * Default: true when a HedgingOptions object is provided. + */ + enabled?: boolean; + /** * Delay before sending a hedged (backup) publish RPC. * Default: 1000ms. Must satisfy 100ms <= hedgeDelay <= 10s. @@ -103,6 +109,7 @@ export interface HedgingOptions { * Validated and defaulted hedging configuration. */ export interface ResolvedHedgingOptions { + readonly enabled?: boolean; readonly hedgeDelay: Duration; readonly maxTokens: number; readonly refillRatio: number; @@ -164,6 +171,11 @@ export class HedgingTokenBucket { return undefined; } + const enabled = hedging.enabled ?? defaultOptions.publish.hedging.enabled; + if (!enabled) { + return undefined; + } + if (messageOrdering) { throw new Error( 'Publish hedging and message ordering cannot be enabled at the same time.', @@ -224,6 +236,7 @@ export class HedgingTokenBucket { } return { + enabled: true, hedgeDelay, maxTokens, refillRatio, diff --git a/handwritten/pubsub/system-test/hedging.test.ts b/handwritten/pubsub/system-test/hedging.test.ts index bba466298bf..374b1b60c96 100644 --- a/handwritten/pubsub/system-test/hedging.test.ts +++ b/handwritten/pubsub/system-test/hedging.test.ts @@ -178,6 +178,14 @@ describe('Publish Hedging System Tests', () => { assert.strictEqual(topic.publisher.tokenBucket?.getTokenBalance(), 1.0); + topic.setPublishOptions({ + batching: {maxMessages: 1}, + hedging: { + enabled: false, + }, + }); + assert.strictEqual(topic.publisher.tokenBucket, undefined); + const received = await waitForMessages(subscription, { count: 6, timeoutMs: 20000, diff --git a/handwritten/pubsub/test/publisher/hedging.ts b/handwritten/pubsub/test/publisher/hedging.ts index 9d17cc4b767..48d9f2e95d7 100644 --- a/handwritten/pubsub/test/publisher/hedging.ts +++ b/handwritten/pubsub/test/publisher/hedging.ts @@ -37,9 +37,27 @@ describe('Publisher Hedging', () => { ); }); + it('returns undefined when hedging.enabled is false', () => { + assert.strictEqual( + HedgingTokenBucket.validateAndResolveHedgingOptions({enabled: false}), + undefined, + ); + assert.strictEqual( + HedgingTokenBucket.validateAndResolveHedgingOptions( + {enabled: false}, + true, + ), + undefined, + ); + }); + it('applies default settings when an empty hedging object is provided', () => { const resolved = HedgingTokenBucket.validateAndResolveHedgingOptions({}); assert.ok(resolved); + assert.strictEqual( + resolved.enabled, + defaultOptions.publish.hedging.enabled, + ); assert.strictEqual( resolved.hedgeDelay.milliseconds, defaultOptions.publish.hedging.hedgeDelay.milliseconds,