Skip to content

Commit 104642b

Browse files
committed
chore: ConfigurationManager
1 parent a077817 commit 104642b

8 files changed

+264
-214
lines changed

src/client/eppo-client-with-bandits.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { IAssignmentEvent, IAssignmentLogger } from '../assignment-logger';
1313
import { BanditEvaluation, BanditEvaluator } from '../bandit-evaluator';
1414
import { IBanditEvent, IBanditLogger } from '../bandit-logger';
1515
import ConfigurationRequestor from '../configuration-requestor';
16+
import { ConfigurationManager } from '../configuration-store/configuration-manager';
1617
import { MemoryOnlyConfigurationStore } from '../configuration-store/memory.store';
1718
import {
1819
IConfigurationWire,
@@ -64,12 +65,12 @@ describe('EppoClient Bandits E2E test', () => {
6465
},
6566
});
6667
const httpClient = new FetchHttpClient(apiEndpoints, 1000);
67-
const configurationRequestor = new ConfigurationRequestor(
68-
httpClient,
68+
const configManager = new ConfigurationManager(
6969
flagStore,
7070
banditVariationStore,
7171
banditModelStore,
7272
);
73+
const configurationRequestor = new ConfigurationRequestor(httpClient, configManager, true);
7374
await configurationRequestor.fetchAndStoreConfigurations();
7475
});
7576

src/client/eppo-client.ts

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import { LRUInMemoryAssignmentCache } from '../cache/lru-in-memory-assignment-ca
1515
import { NonExpiringInMemoryAssignmentCache } from '../cache/non-expiring-in-memory-cache-assignment';
1616
import { TLRUInMemoryAssignmentCache } from '../cache/tlru-in-memory-assignment-cache';
1717
import ConfigurationRequestor from '../configuration-requestor';
18+
import { ConfigurationManager } from '../configuration-store/configuration-manager';
1819
import { IConfigurationStore, ISyncStore } from '../configuration-store/configuration-store';
20+
import { IConfigurationManager } from '../configuration-store/i-configuration-manager';
1921
import { MemoryOnlyConfigurationStore } from '../configuration-store/memory.store';
2022
import {
2123
ConfigurationWireV1,
@@ -41,7 +43,7 @@ import {
4143
} from '../flag-evaluation-details-builder';
4244
import { FlagEvaluationError } from '../flag-evaluation-error';
4345
import FetchHttpClient from '../http-client';
44-
import { IConfiguration, StoreBackedConfiguration } from '../i-configuration';
46+
import { IConfiguration } from '../i-configuration';
4547
import {
4648
BanditModelData,
4749
BanditParameters,
@@ -138,6 +140,7 @@ export default class EppoClient {
138140
private readonly evaluator = new Evaluator();
139141
private configurationRequestor?: ConfigurationRequestor;
140142
private readonly overrideValidator = new OverrideValidator();
143+
private configurationManager: IConfigurationManager;
141144

142145
constructor({
143146
eventDispatcher = new NoOpEventDispatcher(),
@@ -165,16 +168,18 @@ export default class EppoClient {
165168
this.overrideStore = overrideStore;
166169
this.configurationRequestParameters = configurationRequestParameters;
167170
this.expectObfuscated = isObfuscated;
171+
172+
// Initialize the configuration manager
173+
this.configurationManager = new ConfigurationManager(
174+
this.flagConfigurationStore,
175+
this.banditVariationConfigurationStore ||
176+
new MemoryOnlyConfigurationStore<BanditVariation[]>(),
177+
this.banditModelConfigurationStore || new MemoryOnlyConfigurationStore<BanditParameters>(),
178+
);
168179
}
169180

170181
private getConfiguration(): IConfiguration {
171-
return this.configurationRequestor
172-
? this.configurationRequestor.getConfiguration()
173-
: new StoreBackedConfiguration(
174-
this.flagConfigurationStore,
175-
this.banditVariationConfigurationStore,
176-
this.banditModelConfigurationStore,
177-
);
182+
return this.configurationManager.getConfiguration();
178183
}
179184

180185
private maybeWarnAboutObfuscationMismatch(configObfuscated: boolean) {
@@ -238,21 +243,51 @@ export default class EppoClient {
238243
this.configurationRequestParameters = configurationRequestParameters;
239244
}
240245

241-
// noinspection JSUnusedGlobalSymbols
242246
setFlagConfigurationStore(flagConfigurationStore: IConfigurationStore<Flag | ObfuscatedFlag>) {
243247
this.flagConfigurationStore = flagConfigurationStore;
244248
this.configObfuscatedCache = undefined;
249+
250+
// Update the configuration manager
251+
this.configurationManager.setConfigurationStores({
252+
flagConfigurationStore: this.flagConfigurationStore,
253+
banditReferenceConfigurationStore:
254+
this.banditVariationConfigurationStore ||
255+
new MemoryOnlyConfigurationStore<BanditVariation[]>(),
256+
banditConfigurationStore:
257+
this.banditModelConfigurationStore || new MemoryOnlyConfigurationStore<BanditParameters>(),
258+
});
245259
}
246260

247-
// noinspection JSUnusedGlobalSymbols
248261
setBanditVariationConfigurationStore(
249262
banditVariationConfigurationStore: IConfigurationStore<BanditVariation[]>,
250263
) {
251264
this.banditVariationConfigurationStore = banditVariationConfigurationStore;
265+
266+
// Update the configuration manager
267+
this.configurationManager.setConfigurationStores({
268+
flagConfigurationStore: this.flagConfigurationStore,
269+
banditReferenceConfigurationStore: this.banditVariationConfigurationStore,
270+
banditConfigurationStore:
271+
this.banditModelConfigurationStore || new MemoryOnlyConfigurationStore<BanditParameters>(),
272+
});
273+
}
274+
275+
setBanditModelConfigurationStore(
276+
banditModelConfigurationStore: IConfigurationStore<BanditParameters>,
277+
) {
278+
this.banditModelConfigurationStore = banditModelConfigurationStore;
279+
280+
// Update the configuration manager
281+
this.configurationManager.setConfigurationStores({
282+
flagConfigurationStore: this.flagConfigurationStore,
283+
banditReferenceConfigurationStore:
284+
this.banditVariationConfigurationStore ||
285+
new MemoryOnlyConfigurationStore<BanditVariation[]>(),
286+
banditConfigurationStore: this.banditModelConfigurationStore,
287+
});
252288
}
253289

254290
/** Sets the EventDispatcher instance to use when tracking events with {@link track}. */
255-
// noinspection JSUnusedGlobalSymbols
256291
setEventDispatcher(eventDispatcher: EventDispatcher) {
257292
this.eventDispatcher = eventDispatcher;
258293
}
@@ -272,25 +307,6 @@ export default class EppoClient {
272307
this.eventDispatcher?.attachContext(key, value);
273308
}
274309

275-
// noinspection JSUnusedGlobalSymbols
276-
setBanditModelConfigurationStore(
277-
banditModelConfigurationStore: IConfigurationStore<BanditParameters>,
278-
) {
279-
this.banditModelConfigurationStore = banditModelConfigurationStore;
280-
}
281-
282-
// noinspection JSUnusedGlobalSymbols
283-
/**
284-
* Setting this value will have no side effects other than triggering a warning when the actual
285-
* configuration's obfuscated does not match the value set here.
286-
*
287-
* @deprecated The client determines whether the configuration is obfuscated by inspection
288-
* @param isObfuscated
289-
*/
290-
setIsObfuscated(isObfuscated: boolean) {
291-
this.expectObfuscated = isObfuscated;
292-
}
293-
294310
setOverrideStore(store: ISyncStore<Variation>): void {
295311
this.overrideStore = store;
296312
}
@@ -322,7 +338,7 @@ export default class EppoClient {
322338
apiKey,
323339
sdkName,
324340
sdkVersion,
325-
baseUrl, // Default is set in ApiEndpoints constructor if undefined
341+
baseUrl,
326342
requestTimeoutMs = DEFAULT_REQUEST_TIMEOUT_MS,
327343
numInitialRequestRetries = DEFAULT_INITIAL_CONFIG_REQUEST_RETRIES,
328344
numPollRequestRetries = DEFAULT_POLL_CONFIG_REQUEST_RETRIES,
@@ -338,22 +354,22 @@ export default class EppoClient {
338354
pollingIntervalMs = DEFAULT_POLL_INTERVAL_MS;
339355
}
340356

341-
// todo: Inject the chain of dependencies below
342357
const apiEndpoints = new ApiEndpoints({
343358
baseUrl,
344359
queryParams: { apiKey, sdkName, sdkVersion },
345360
});
346361
const httpClient = new FetchHttpClient(apiEndpoints, requestTimeoutMs);
362+
363+
// Use the configuration manager when creating the requestor
347364
const configurationRequestor = new ConfigurationRequestor(
348365
httpClient,
349-
this.flagConfigurationStore,
350-
this.banditVariationConfigurationStore ?? null,
351-
this.banditModelConfigurationStore ?? null,
366+
this.configurationManager,
367+
!!this.banditModelConfigurationStore && !!this.banditVariationConfigurationStore,
352368
);
353369
this.configurationRequestor = configurationRequestor;
354370

355371
const pollingCallback = async () => {
356-
if (await configurationRequestor.isFlagConfigExpired()) {
372+
if (await this.flagConfigurationStore.isExpired()) {
357373
this.configObfuscatedCache = undefined;
358374
return configurationRequestor.fetchAndStoreConfigurations();
359375
}

src/client/test-utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ApiEndpoints from '../api-endpoints';
22
import ConfigurationRequestor from '../configuration-requestor';
3+
import { ConfigurationManager } from '../configuration-store/configuration-manager';
34
import { IConfigurationStore } from '../configuration-store/configuration-store';
45
import FetchHttpClient from '../http-client';
56
import { Flag, ObfuscatedFlag } from '../interfaces';
@@ -18,9 +19,8 @@ export async function initConfiguration(
1819
const httpClient = new FetchHttpClient(apiEndpoints, 1000);
1920
const configurationRequestor = new ConfigurationRequestor(
2021
httpClient,
21-
configurationStore,
22-
null,
23-
null,
22+
new ConfigurationManager(configurationStore, null, null),
23+
false,
2424
);
2525
await configurationRequestor.fetchAndStoreConfigurations();
2626
}

0 commit comments

Comments
 (0)