Skip to content

Commit 551573d

Browse files
felipecslsameerank
andauthored
feat(events): Allow providing config for DefaultEventDispatcher (#122)
* feat(events): Allow providing config for DefaultEventDispatcher * write test * fix tests * fix: for common v4.6.2 (#123) * Include subject info in log * Update to setSubjectAndPrecomputedFlagsRequestParameters --------- Co-authored-by: Sameeran Kunche <[email protected]>
1 parent f4a8a3f commit 551573d

8 files changed

+123
-11
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
2+
3+
[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IClientConfig](./js-client-sdk.iclientconfig.md) &gt; [eventIngestionConfig](./js-client-sdk.iclientconfig.eventingestionconfig.md)
4+
5+
## IClientConfig.eventIngestionConfig property
6+
7+
Configuration settings for the event dispatcher
8+
9+
**Signature:**
10+
11+
```typescript
12+
eventIngestionConfig?: {
13+
deliveryIntervalMs?: number;
14+
retryIntervalMs?: number;
15+
maxRetryDelayMs?: number;
16+
maxRetries?: number;
17+
batchSize?: number;
18+
};
19+
```

docs/js-client-sdk.iclientconfig.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,25 @@ Description
3838
</th></tr></thead>
3939
<tbody><tr><td>
4040
41+
[eventIngestionConfig?](./js-client-sdk.iclientconfig.eventingestionconfig.md)
42+
43+
44+
</td><td>
45+
46+
47+
</td><td>
48+
49+
{ deliveryIntervalMs?: number; retryIntervalMs?: number; maxRetryDelayMs?: number; maxRetries?: number; batchSize?: number; }
50+
51+
52+
</td><td>
53+
54+
_(Optional)_ Configuration settings for the event dispatcher
55+
56+
57+
</td></tr>
58+
<tr><td>
59+
4160
[forceReinitialize?](./js-client-sdk.iclientconfig.forcereinitialize.md)
4261
4362

js-client-sdk.api.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ export { IAsyncStore }
116116
//
117117
// @public
118118
export interface IClientConfig extends IBaseRequestConfig {
119+
eventIngestionConfig?: {
120+
deliveryIntervalMs?: number;
121+
retryIntervalMs?: number;
122+
maxRetryDelayMs?: number;
123+
maxRetries?: number;
124+
batchSize?: number;
125+
};
119126
forceReinitialize?: boolean;
120127
maxCacheAgeSeconds?: number;
121128
persistentStore?: IAsyncStore<Flag>;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"webpack-cli": "^4.10.0"
6060
},
6161
"dependencies": {
62-
"@eppo/js-client-sdk-common": "^4.5.4"
62+
"@eppo/js-client-sdk-common": "^4.6.2"
6363
},
6464
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
6565
}

src/i-client-config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { AttributeType, Flag, IAssignmentLogger, IAsyncStore } from '@eppo/js-client-sdk-common';
2+
import { EventDispatcherConfig } from '@eppo/js-client-sdk-common/src/events/default-event-dispatcher';
23

34
import { ServingStoreUpdateStrategy } from './isolatable-hybrid.store';
45

@@ -120,4 +121,18 @@ export interface IClientConfig extends IBaseRequestConfig {
120121
* Force reinitialize the SDK if it is already initialized.
121122
*/
122123
forceReinitialize?: boolean;
124+
125+
/** Configuration settings for the event dispatcher */
126+
eventIngestionConfig?: {
127+
// number of milliseconds to wait between each batch delivery. Default is 10 seconds.
128+
deliveryIntervalMs?: number;
129+
// minimum amount of milliseconds to wait before retrying a failed delivery. Default is 5 seconds
130+
retryIntervalMs?: number;
131+
// maximum amount of milliseconds to wait before retrying a failed delivery. Default is 30 seconds.
132+
maxRetryDelayMs?: number;
133+
// maximum number of retry attempts before giving up on a batch delivery. Default is 3.
134+
maxRetries?: number;
135+
// maximum number of events to send per delivery request. Default is 100.
136+
batchSize?: number;
137+
};
123138
}

src/index.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { IClientConfig } from './i-client-config';
2929
import { ServingStoreUpdateStrategy } from './isolatable-hybrid.store';
3030

3131
import {
32+
EppoJSClient,
3233
EppoPrecomputedJSClient,
3334
getConfigUrl,
3435
getInstance,
@@ -1177,3 +1178,36 @@ describe('EppoPrecomputedJSClient E2E test', () => {
11771178
});
11781179
});
11791180
});
1181+
1182+
describe('EppoClient config', () => {
1183+
it('should initialize event dispatcher with default values', async () => {
1184+
global.fetch = jest.fn(() => {
1185+
return Promise.resolve({
1186+
ok: true,
1187+
status: 200,
1188+
json: () => Promise.resolve({}),
1189+
});
1190+
}) as jest.Mock;
1191+
EppoJSClient.initialized = false;
1192+
const client = await init({
1193+
apiKey: 'zCsQuoHJxVPp895.ZWg9MTIzNDU2LmUudGVzdGluZy5lcHBvLmNsb3Vk',
1194+
assignmentLogger: td.object<IAssignmentLogger>(),
1195+
eventIngestionConfig: {
1196+
deliveryIntervalMs: 1,
1197+
retryIntervalMs: 2,
1198+
maxRetryDelayMs: 3,
1199+
maxRetries: 4,
1200+
batchSize: 5,
1201+
},
1202+
});
1203+
// hack to read the private class members config
1204+
const eventDispatcher = client['eventDispatcher'];
1205+
const retryManager = eventDispatcher['retryManager'];
1206+
const batchProcessor = eventDispatcher['batchProcessor'];
1207+
expect(eventDispatcher['deliveryIntervalMs']).toEqual(1);
1208+
expect(batchProcessor['batchSize']).toEqual(5);
1209+
expect(retryManager['config']['retryIntervalMs']).toEqual(2);
1210+
expect(retryManager['config']['maxRetryDelayMs']).toEqual(3);
1211+
expect(retryManager['config']['maxRetries']).toEqual(4);
1212+
});
1213+
});

src/index.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
ObfuscatedFlag,
1818
BoundedEventQueue,
1919
validation,
20+
Event,
2021
} from '@eppo/js-client-sdk-common';
2122

2223
import { assignmentCacheFactory } from './cache/assignment-cache-factory';
@@ -335,6 +336,7 @@ export async function init(config: IClientConfig): Promise<EppoClient> {
335336
pollAfterSuccessfulInitialization = false,
336337
pollAfterFailedInitialization = false,
337338
skipInitialRequest = false,
339+
eventIngestionConfig,
338340
} = config;
339341
try {
340342
if (EppoJSClient.initialized) {
@@ -404,7 +406,7 @@ export async function init(config: IClientConfig): Promise<EppoClient> {
404406
skipInitialPoll: skipInitialRequest,
405407
};
406408
instance.setConfigurationRequestParameters(requestConfiguration);
407-
instance.setEventDispatcher(newEventDispatcher(apiKey));
409+
instance.setEventDispatcher(newEventDispatcher(apiKey, eventIngestionConfig));
408410

409411
// We have two at-bats for initialization: from the configuration store and from fetching
410412
// We can resolve the initialization promise as soon as either one succeeds
@@ -595,7 +597,7 @@ export async function precomputedInit(
595597
throwOnFailedInitialization: true, // always use true here as underlying instance fetch is surrounded by try/catch
596598
skipInitialPoll: skipInitialRequest,
597599
};
598-
instance.setPrecomputedFlagsRequestParameters(precomputedFlagsRequestParameters);
600+
instance.setSubjectAndPrecomputedFlagsRequestParameters(precomputedFlagsRequestParameters);
599601

600602
await instance.fetchPrecomputedFlags();
601603

@@ -613,14 +615,30 @@ export function getPrecomputedInstance(): EppoPrecomputedClient {
613615
return EppoPrecomputedJSClient.instance;
614616
}
615617

616-
function newEventDispatcher(sdkKey: string): EventDispatcher {
618+
function newEventDispatcher(
619+
sdkKey: string,
620+
config: IClientConfig['eventIngestionConfig'] = {},
621+
): EventDispatcher {
617622
const eventQueue = hasWindowLocalStorage()
618-
? new LocalStorageBackedNamedEventQueue('events')
619-
: new BoundedEventQueue('events');
623+
? new LocalStorageBackedNamedEventQueue<Event>('events')
624+
: new BoundedEventQueue<Event>('events');
620625
const emptyNetworkStatusListener =
621626
// eslint-disable-next-line @typescript-eslint/no-empty-function
622627
{ isOffline: () => false, onNetworkStatusChange: () => {} };
623628
const networkStatusListener =
624629
typeof window !== 'undefined' ? new BrowserNetworkStatusListener() : emptyNetworkStatusListener;
625-
return newDefaultEventDispatcher(eventQueue, networkStatusListener, sdkKey);
630+
// initialize config with default values
631+
const {
632+
batchSize = 100,
633+
deliveryIntervalMs = 10_000,
634+
retryIntervalMs = 5_000,
635+
maxRetryDelayMs = 30_000,
636+
maxRetries = 3,
637+
} = config;
638+
return newDefaultEventDispatcher(eventQueue, networkStatusListener, sdkKey, batchSize, {
639+
deliveryIntervalMs,
640+
retryIntervalMs,
641+
maxRetryDelayMs,
642+
maxRetries,
643+
});
626644
}

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,10 @@
380380
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
381381
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
382382

383-
"@eppo/js-client-sdk-common@^4.5.4":
384-
version "4.5.4"
385-
resolved "https://registry.yarnpkg.com/@eppo/js-client-sdk-common/-/js-client-sdk-common-4.5.4.tgz#089e0eb28ec2fd567f8ed2ec516b1b93f2ceb473"
386-
integrity sha512-q3E9BTOcyAuPxWm9MqdqqV9uhaO4v8QW5d6tyDqQVZXC1hAgiMynAHH2DcuSEfE3v4s3JT0xjwzqkrcGNRCRlg==
383+
"@eppo/js-client-sdk-common@^4.6.2":
384+
version "4.6.2"
385+
resolved "https://registry.yarnpkg.com/@eppo/js-client-sdk-common/-/js-client-sdk-common-4.6.2.tgz#18b845e1411a9edf861a52e935a17d25ce5055af"
386+
integrity sha512-jXxu3zaRd74IKepYj/s1TSMtRqp5pNLqgle7aD4PqfVGxmCFiBU81Jd/v9px7YzLId/8uUrQvLgIm6GAmTJMxg==
387387
dependencies:
388388
buffer "npm:@eppo/[email protected]"
389389
js-base64 "^3.7.7"

0 commit comments

Comments
 (0)