Skip to content

Commit 99f2c29

Browse files
committed
refresh APIs apply for both kv and ff
1 parent 1182638 commit 99f2c29

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

src/AzureAppConfiguration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export type AzureAppConfiguration = {
1010
refresh(): Promise<void>;
1111

1212
/**
13-
* API to register callback listeners, which will be called only when a refresh operation successfully updates key-values.
13+
* API to register callback listeners, which will be called only when a refresh operation successfully updates key-values or feature flags.
1414
*
1515
* @param listener - Callback function to be registered.
1616
* @param thisArg - Optional. Value to use as `this` when executing callback.

src/AzureAppConfigurationImpl.ts

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -331,18 +331,42 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
331331
throw new Error("Refresh is not enabled for key-values and feature flags.");
332332
}
333333

334+
const refreshTasks: Promise<boolean>[] = [];
334335
if (this.#refreshEnabled) {
335-
await this.#refreshKeyValues();
336+
refreshTasks.push(this.#refreshKeyValues());
336337
}
337338
if (this.#featureFlagRefreshEnabled) {
338-
await this.#refreshFeatureFlags();
339+
refreshTasks.push(this.#refreshFeatureFlags());
340+
}
341+
342+
// wait until all tasks are either resolved or rejected
343+
const results = await Promise.allSettled(refreshTasks);
344+
345+
// check if any refresh task failed
346+
for (const result of results) {
347+
if (result.status === "rejected") {
348+
throw result.reason;
349+
}
350+
}
351+
352+
// check if any refresh task succeeded
353+
const anyRefreshed = results.some(result => result.status === "fulfilled" && result.value === true);
354+
if (anyRefreshed) {
355+
// successfully refreshed, run callbacks in async
356+
for (const listener of this.#onRefreshListeners) {
357+
listener();
358+
}
339359
}
340360
}
341361

342-
async #refreshKeyValues(): Promise<void> {
362+
/**
363+
* Refresh key-values.
364+
* @returns true if key-values are refreshed, false otherwise.
365+
*/
366+
async #refreshKeyValues(): Promise<boolean> {
343367
// if still within refresh interval/backoff, return
344368
if (!this.#refreshTimer.canRefresh()) {
345-
return Promise.resolve();
369+
return Promise.resolve(false);
346370
}
347371

348372
// try refresh if any of watched settings is changed.
@@ -360,6 +384,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
360384
break;
361385
}
362386
}
387+
363388
if (needRefresh) {
364389
try {
365390
await this.#loadSelectedAndWatchedKeyValues();
@@ -369,28 +394,32 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
369394
this.#refreshTimer.backoff();
370395
throw error;
371396
}
372-
373-
// successfully refreshed, run callbacks in async
374-
for (const listener of this.#onRefreshListeners) {
375-
listener();
376-
}
397+
return Promise.resolve(true);
377398
}
399+
400+
return Promise.resolve(false);
378401
}
379402

380-
async #refreshFeatureFlags(): Promise<void> {
403+
/**
404+
* Refresh feature flags.
405+
* @returns true if feature flags are refreshed, false otherwise.
406+
*/
407+
async #refreshFeatureFlags(): Promise<boolean> {
381408
// if still within refresh interval/backoff, return
382409
if (!this.#featureFlagRefreshTimer.canRefresh()) {
383-
return Promise.resolve();
410+
return Promise.resolve(false);
384411
}
385412

386413
try {
414+
// TODO: instead of refreshing all feature flags, only refresh the changed ones with etag
387415
await this.#loadFeatureFlags();
388416
this.#featureFlagRefreshTimer.reset();
389417
} catch (error) {
390418
// if refresh failed, backoff
391419
this.#featureFlagRefreshTimer.backoff();
392420
throw error;
393421
}
422+
return Promise.resolve(true);
394423
}
395424

396425
onRefresh(listener: () => any, thisArg?: any): Disposable {

0 commit comments

Comments
 (0)