From fcaa6b8058afa26b3153e7deb1156b50eae79e59 Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Wed, 14 Jan 2026 17:03:08 +0600 Subject: [PATCH 1/3] [FSSDK-12147] update event retry default config --- lib/event_processor/batch_event_processor.ts | 6 +++--- .../event_processor_factory.browser.spec.ts | 6 +++--- lib/event_processor/event_processor_factory.browser.ts | 4 ++-- lib/event_processor/event_processor_factory.node.spec.ts | 6 +++--- lib/event_processor/event_processor_factory.node.ts | 4 ++-- .../event_processor_factory.react_native.spec.ts | 6 +++--- .../event_processor_factory.react_native.ts | 4 ++-- lib/odp/odp_manager_factory.ts | 8 ++++---- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/event_processor/batch_event_processor.ts b/lib/event_processor/batch_event_processor.ts index 81547352f..9c70e04ee 100644 --- a/lib/event_processor/batch_event_processor.ts +++ b/lib/event_processor/batch_event_processor.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,8 @@ import { sprintf } from "../utils/fns"; import { SERVICE_STOPPED_BEFORE_RUNNING } from "../service"; import { Platform } from '../platform_support'; -export const DEFAULT_MIN_BACKOFF = 1000; -export const DEFAULT_MAX_BACKOFF = 32000; +export const DEFAULT_MIN_BACKOFF = 200; +export const DEFAULT_MAX_BACKOFF = 1000; export const MAX_EVENTS_IN_STORE = 500; export type EventWithId = { diff --git a/lib/event_processor/event_processor_factory.browser.spec.ts b/lib/event_processor/event_processor_factory.browser.spec.ts index b94be035e..61c6c483c 100644 --- a/lib/event_processor/event_processor_factory.browser.spec.ts +++ b/lib/event_processor/event_processor_factory.browser.spec.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -227,10 +227,10 @@ describe('createBatchEventProcessor', () => { expect(mockGetOpaqueBatchEventProcessor.mock.calls[1][0].batchSize).toBe(undefined); }); - it('uses maxRetries value of 5 by default', () => { + it('uses maxRetries value of 2 by default', () => { const processor = createBatchEventProcessor({ }); expect(Object.is(processor, mockGetOpaqueBatchEventProcessor.mock.results[0].value)).toBe(true); - expect(mockGetOpaqueBatchEventProcessor.mock.calls[0][0].retryOptions?.maxRetries).toBe(5); + expect(mockGetOpaqueBatchEventProcessor.mock.calls[0][0].retryOptions?.maxRetries).toBe(2); }); it('uses the provided maxRetries value', () => { diff --git a/lib/event_processor/event_processor_factory.browser.ts b/lib/event_processor/event_processor_factory.browser.ts index b69219a7f..a4d782c7a 100644 --- a/lib/event_processor/event_processor_factory.browser.ts +++ b/lib/event_processor/event_processor_factory.browser.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ import { DEFAULT_MAX_EVENTS_IN_STORE, EventStore } from './event_store'; import { Platform } from '../platform_support'; export const DEFAULT_EVENT_BATCH_SIZE = 10; export const DEFAULT_EVENT_FLUSH_INTERVAL = 1_000; -export const EVENT_MAX_RETRIES_BROWSER = 5; +export const EVENT_MAX_RETRIES_BROWSER = 2; export const createForwardingEventProcessor = ( eventDispatcher: EventDispatcher = defaultEventDispatcher, diff --git a/lib/event_processor/event_processor_factory.node.spec.ts b/lib/event_processor/event_processor_factory.node.spec.ts index a8e9ff902..3ec073882 100644 --- a/lib/event_processor/event_processor_factory.node.spec.ts +++ b/lib/event_processor/event_processor_factory.node.spec.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -184,10 +184,10 @@ describe('createBatchEventProcessor', () => { expect(mockGetOpaqueBatchEventProcessor.mock.calls[1][0].batchSize).toBe(undefined); }); - it('uses maxRetries value of 5 by default', () => { + it('uses maxRetries value of 2 by default', () => { const processor = createBatchEventProcessor({ }); expect(Object.is(processor, mockGetOpaqueBatchEventProcessor.mock.results[0].value)).toBe(true); - expect(mockGetOpaqueBatchEventProcessor.mock.calls[0][0].retryOptions?.maxRetries).toBe(5); + expect(mockGetOpaqueBatchEventProcessor.mock.calls[0][0].retryOptions?.maxRetries).toBe(2); }); it('uses the provided maxRetries value', () => { diff --git a/lib/event_processor/event_processor_factory.node.ts b/lib/event_processor/event_processor_factory.node.ts index 15fe6f4e9..1feb6f3a1 100644 --- a/lib/event_processor/event_processor_factory.node.ts +++ b/lib/event_processor/event_processor_factory.node.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import { import { Platform } from '../platform_support'; export const DEFAULT_EVENT_BATCH_SIZE = 10; export const DEFAULT_EVENT_FLUSH_INTERVAL = 30_000; -export const EVENT_MAX_RETRIES_NODE = 5; +export const EVENT_MAX_RETRIES_NODE = 2; export const createForwardingEventProcessor = ( eventDispatcher: EventDispatcher = defaultEventDispatcher, diff --git a/lib/event_processor/event_processor_factory.react_native.spec.ts b/lib/event_processor/event_processor_factory.react_native.spec.ts index c60af49e4..2a4c5d170 100644 --- a/lib/event_processor/event_processor_factory.react_native.spec.ts +++ b/lib/event_processor/event_processor_factory.react_native.spec.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -281,10 +281,10 @@ describe('createBatchEventProcessor', () => { expect(mockGetOpaqueBatchEventProcessor.mock.calls[1][0].batchSize).toBe(undefined); }); - it('uses maxRetries value of 5 by default', () => { + it('uses maxRetries value of 2 by default', () => { const processor = createBatchEventProcessor({}); expect(Object.is(processor, mockGetOpaqueBatchEventProcessor.mock.results[0].value)).toBe(true); - expect(mockGetOpaqueBatchEventProcessor.mock.calls[0][0].retryOptions?.maxRetries).toBe(5); + expect(mockGetOpaqueBatchEventProcessor.mock.calls[0][0].retryOptions?.maxRetries).toBe(2); }); it('uses the provided maxRetries value', () => { diff --git a/lib/event_processor/event_processor_factory.react_native.ts b/lib/event_processor/event_processor_factory.react_native.ts index 525dd91cf..1b4f58dc9 100644 --- a/lib/event_processor/event_processor_factory.react_native.ts +++ b/lib/event_processor/event_processor_factory.react_native.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ import { DEFAULT_MAX_EVENTS_IN_STORE, EventStore } from './event_store'; import { Platform } from '../platform_support'; export const DEFAULT_EVENT_BATCH_SIZE = 10; export const DEFAULT_EVENT_FLUSH_INTERVAL = 1_000; -export const EVENT_MAX_RETRIES_REACT_NATIVE = 5; +export const EVENT_MAX_RETRIES_REACT_NATIVE = 2; export const createForwardingEventProcessor = ( eventDispatcher: EventDispatcher = defaultEventDispatcher, diff --git a/lib/odp/odp_manager_factory.ts b/lib/odp/odp_manager_factory.ts index f61c25209..053eb11cb 100644 --- a/lib/odp/odp_manager_factory.ts +++ b/lib/odp/odp_manager_factory.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,9 +32,9 @@ export const DEFAULT_CACHE_TIMEOUT = 600_000; export const DEFAULT_EVENT_BATCH_SIZE = 100; export const DEFAULT_EVENT_FLUSH_INTERVAL = 10_000; -export const DEFAULT_EVENT_MAX_RETRIES = 5; -export const DEFAULT_EVENT_MIN_BACKOFF = 1000; -export const DEFAULT_EVENT_MAX_BACKOFF = 32_000; +export const DEFAULT_EVENT_MAX_RETRIES = 2; +export const DEFAULT_EVENT_MIN_BACKOFF = 200; +export const DEFAULT_EVENT_MAX_BACKOFF = 1_000; export const INVALID_CACHE = 'Invalid cache'; export const INVALID_CACHE_METHOD = 'Invalid cache method %s'; From aa5d2b83792340bcc113ba9d82a8fe6f2d319afb Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Wed, 14 Jan 2026 19:28:26 +0600 Subject: [PATCH 2/3] jitter --- lib/event_processor/event_processor_factory.ts | 2 +- lib/odp/odp_manager_factory.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/event_processor/event_processor_factory.ts b/lib/event_processor/event_processor_factory.ts index 7336dfa86..77d54326b 100644 --- a/lib/event_processor/event_processor_factory.ts +++ b/lib/event_processor/event_processor_factory.ts @@ -105,7 +105,7 @@ export const getBatchEventProcessor = ( backoffProvider: () => { const minBackoff = retryOptions?.minBackoff ?? DEFAULT_MIN_BACKOFF; const maxBackoff = retryOptions?.maxBackoff ?? DEFAULT_MAX_BACKOFF; - return new ExponentialBackoff(minBackoff, maxBackoff, 500); + return new ExponentialBackoff(minBackoff, maxBackoff, 50); } } : undefined; diff --git a/lib/odp/odp_manager_factory.ts b/lib/odp/odp_manager_factory.ts index 053eb11cb..126392279 100644 --- a/lib/odp/odp_manager_factory.ts +++ b/lib/odp/odp_manager_factory.ts @@ -107,7 +107,7 @@ const getDefaultEventManager = (options: OdpManagerFactoryOptions) => { backoffProvider: () => new ExponentialBackoff( options.eventMinBackoff || DEFAULT_EVENT_MIN_BACKOFF, options.eventMaxBackoff || DEFAULT_EVENT_MAX_BACKOFF, - 500, + 50, ), }, }); From 8d91b0a90fe9fb4e6668f8431dac7c7ff58784fb Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Wed, 14 Jan 2026 19:46:40 +0600 Subject: [PATCH 3/3] upd --- lib/event_processor/event_processor_factory.spec.ts | 4 ++-- lib/utils/repeater/repeater.ts | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/event_processor/event_processor_factory.spec.ts b/lib/event_processor/event_processor_factory.spec.ts index 16e82bdea..d7105fa75 100644 --- a/lib/event_processor/event_processor_factory.spec.ts +++ b/lib/event_processor/event_processor_factory.spec.ts @@ -222,7 +222,7 @@ describe('getBatchEventProcessor', () => { expect(backoffProvider).not.toBe(undefined); const backoff = backoffProvider?.(); expect(Object.is(backoff, MockExponentialBackoff.mock.instances[0])).toBe(true); - expect(MockExponentialBackoff).toHaveBeenNthCalledWith(1, DEFAULT_MIN_BACKOFF, DEFAULT_MAX_BACKOFF, 500); + expect(MockExponentialBackoff).toHaveBeenNthCalledWith(1, DEFAULT_MIN_BACKOFF, DEFAULT_MAX_BACKOFF, 50); }); it('uses exponential backoff with provided backoff values in retryOptions', () => { @@ -243,7 +243,7 @@ describe('getBatchEventProcessor', () => { expect(backoffProvider).not.toBe(undefined); const backoff = backoffProvider?.(); expect(Object.is(backoff, MockExponentialBackoff.mock.instances[0])).toBe(true); - expect(MockExponentialBackoff).toHaveBeenNthCalledWith(1, 1000, 2000, 500); + expect(MockExponentialBackoff).toHaveBeenNthCalledWith(1, 1000, 2000, 50); }); it('uses a IntervalRepeater with default flush interval and adds a startup log if flushInterval is not provided', () => { diff --git a/lib/utils/repeater/repeater.ts b/lib/utils/repeater/repeater.ts index cdb9ec9f3..fe8dd752a 100644 --- a/lib/utils/repeater/repeater.ts +++ b/lib/utils/repeater/repeater.ts @@ -1,5 +1,5 @@ /** - * Copyright 2024-2025, Optimizely + * Copyright 2024-2026, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,6 +51,10 @@ export class ExponentialBackoff implements BackoffController { this.base = base; this.max = max; this.maxJitter = maxJitter; + if (this.maxJitter > this.base / 2) { + this.maxJitter = this.base / 2; + } + this.maxJitter = maxJitter; this.current = base; }