Skip to content

Load From Azure Front Door #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 75 commits into
base: preview
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
ce9f550
use pipeline policy to ensure cdn request uses correct api version
zhiyuanliang-ms Nov 4, 2024
2adadc7
fix lint & add comments
zhiyuanliang-ms Nov 4, 2024
30108ab
update
zhiyuanliang-ms Nov 5, 2024
197db89
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Nov 5, 2024
04d8a2c
update
zhiyuanliang-ms Nov 7, 2024
bf99b31
fix lint
zhiyuanliang-ms Nov 7, 2024
14364c5
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Nov 10, 2024
62ac2b9
add request tracing for cdn
zhiyuanliang-ms Nov 10, 2024
bd1c875
only send conditional request when cdn is not used
zhiyuanliang-ms Nov 14, 2024
0856707
add testcase
zhiyuanliang-ms Nov 14, 2024
2b78b27
fix lint
zhiyuanliang-ms Nov 15, 2024
fdd30e2
refresh based on page etag
zhiyuanliang-ms Nov 18, 2024
c886936
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Nov 18, 2024
2a7399b
merge preview
zhiyuanliang-ms Nov 18, 2024
b4afe7a
merge preview
zhiyuanliang-ms Nov 18, 2024
50fc5b6
remove watchAll & reorganize the code
zhiyuanliang-ms Nov 19, 2024
70bbdee
add testcase
zhiyuanliang-ms Nov 19, 2024
d8103a5
fix lint & update method name
zhiyuanliang-ms Nov 19, 2024
e123f0e
resolve merge conflict
zhiyuanliang-ms Nov 19, 2024
6958ad5
add comment
zhiyuanliang-ms Nov 19, 2024
635ca48
Merge branch 'zhiyuanliang/register-all-refresh' of https://github.co…
zhiyuanliang-ms Nov 19, 2024
61e4a65
not use conditional request
zhiyuanliang-ms Nov 19, 2024
4f36a1c
fix vulnerability
zhiyuanliang-ms Nov 20, 2024
d325127
resolve merge conflict
zhiyuanliang-ms Dec 2, 2024
647c7a6
resolve conflict
zhiyuanliang-ms Dec 2, 2024
b74e983
update variable name
zhiyuanliang-ms Dec 2, 2024
eec7114
merge
zhiyuanliang-ms Dec 2, 2024
01a7034
move public method
zhiyuanliang-ms Dec 2, 2024
0fb81da
Merge branch 'zhiyuanliang/register-all-refresh' of https://github.co…
zhiyuanliang-ms Dec 2, 2024
b0ab944
append etag to url
zhiyuanliang-ms Dec 3, 2024
c094801
update
zhiyuanliang-ms Dec 4, 2024
bbf1938
update
zhiyuanliang-ms Dec 4, 2024
f3ac831
add more comments
zhiyuanliang-ms Dec 5, 2024
e6fea3c
merge preview
zhiyuanliang-ms Dec 13, 2024
072bcdf
Merge branch 'zhiyuanliang/register-all-refresh' of https://github.co…
zhiyuanliang-ms Dec 13, 2024
356e664
fix lint
zhiyuanliang-ms Dec 13, 2024
2b95ab4
resolve merge conflict
zhiyuanliang-ms Dec 13, 2024
d3c2799
resolve merge conflict
zhiyuanliang-ms Dec 18, 2024
290d338
merge preview
zhiyuanliang-ms Dec 18, 2024
ea7709e
merge
zhiyuanliang-ms Dec 18, 2024
8ed48b5
merge preview
zhiyuanliang-ms Dec 19, 2024
6e34f62
resolve merge conflict
zhiyuanliang-ms Dec 19, 2024
14dbe96
update
zhiyuanliang-ms Dec 19, 2024
8441b32
resolve copilot comment
zhiyuanliang-ms Dec 19, 2024
6fe042a
fix lint
zhiyuanliang-ms Dec 19, 2024
33a5964
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Feb 12, 2025
f23ebe4
Merge branch 'preview' into zhiyuanliang/enforce-api-version-for-cdn
zhiyuanliang-ms Feb 20, 2025
e77d37d
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Apr 29, 2025
41ad554
fix lint
zhiyuanliang-ms Apr 29, 2025
334a047
update testcase
zhiyuanliang-ms Apr 29, 2025
9dec453
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms May 13, 2025
e457605
update
zhiyuanliang-ms Jun 3, 2025
12b0216
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Jun 3, 2025
c096a50
update
zhiyuanliang-ms Jun 4, 2025
811b0e4
fix lint
zhiyuanliang-ms Jun 4, 2025
03d956d
disable replica discovery for CDN
zhiyuanliang-ms Jun 4, 2025
96df9d9
WIP
zhiyuanliang-ms Jun 4, 2025
ac33118
update to latest design
zhiyuanliang-ms Jun 5, 2025
3528e87
update
zhiyuanliang-ms Jun 5, 2025
f688702
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Jun 5, 2025
19b70c2
update
zhiyuanliang-ms Jun 6, 2025
a30b421
update naming
zhiyuanliang-ms Jun 6, 2025
3f05285
update
zhiyuanliang-ms Jun 10, 2025
4f99512
rename api to loadFromAzureFrontDoor
zhiyuanliang-ms Jun 12, 2025
08f4732
update error message
zhiyuanliang-ms Jun 13, 2025
c0ae98a
add policy to remove authorization header
zhiyuanliang-ms Jun 26, 2025
c061b98
add test
zhiyuanliang-ms Jun 26, 2025
9254069
Merge branch 'zhiyuanliang/enforce-api-version-for-cdn' of https://gi…
zhiyuanliang-ms Jun 26, 2025
3005407
fix lint
zhiyuanliang-ms Jun 26, 2025
f367161
update
zhiyuanliang-ms Jun 26, 2025
d74fdd2
add cache break token test
zhiyuanliang-ms Jun 26, 2025
333eb3b
update request tracing testcase
zhiyuanliang-ms Jun 26, 2025
486ef1b
update
zhiyuanliang-ms Jul 10, 2025
26ff70f
add example
zhiyuanliang-ms Jul 30, 2025
047ad58
Merge branch 'preview' of https://github.com/Azure/AppConfiguration-J…
zhiyuanliang-ms Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
…avaScriptProvider into zhiyuanliang/enforce-api-version-for-cdn
  • Loading branch information
zhiyuanliang-ms committed Apr 29, 2025
commit e77d37d2bcd078c5bc2a57c24ba6872f26d0aa8b
90 changes: 60 additions & 30 deletions src/AzureAppConfigurationImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
import { KeyFilter, LabelFilter, SettingSelector } from "./types.js";
import { ConfigurationClientManager } from "./ConfigurationClientManager.js";
import { ETAG_LOOKUP_HEADER } from "./EtagUrlPipelinePolicy.js";
import { getFixedBackoffDuration, getExponentialBackoffDuration } from "./common/backoffUtils.js";
import { InvalidOperationError, ArgumentError, isFailoverableError, isInputError } from "./common/error.js";

const MIN_DELAY_FOR_UNHANDLED_FAILURE = 5_000; // 5 seconds

type PagedSettingSelector = SettingSelector & {
pageEtags?: string[];
Expand Down Expand Up @@ -249,39 +253,40 @@
* @internal
*/
async load() {
await this.#inspectFmPackage();
await this.#loadSelectedAndWatchedKeyValues();

if (this.#featureFlagEnabled) {
await this.#loadFeatureFlags();
}

if (this.#isCdnUsed) {
if (this.#watchAll) { // collection monitoring based refresh
// use the first page etag of the first kv selector
const defaultSelector = this.#kvSelectorCollection.selectors.find(s => s.pageEtags !== undefined);
if (defaultSelector && defaultSelector.pageEtags!.length > 0) {
this.#kvSelectorCollection.cdnCacheBreakString = defaultSelector.pageEtags![0];
} else {
this.#kvSelectorCollection.cdnCacheBreakString = undefined;
}
} else if (this.#refreshEnabled) { // watched settings based refresh
// use the etag of the first watched setting (sentinel)
this.#kvSelectorCollection.cdnCacheBreakString = this.#sentinels.find(s => s.etag !== undefined)?.etag;
}

if (this.#featureFlagRefreshEnabled) {
const defaultSelector = this.#ffSelectorCollection.selectors.find(s => s.pageEtags !== undefined);
if (defaultSelector && defaultSelector.pageEtags!.length > 0) {
this.#ffSelectorCollection.cdnCacheBreakString = defaultSelector.pageEtags![0];
} else {
this.#ffSelectorCollection.cdnCacheBreakString = undefined;
const startTimestamp = Date.now();
const startupTimeout: number = this.#options?.startupOptions?.timeoutInMs ?? DEFAULT_STARTUP_TIMEOUT_IN_MS;
const abortController = new AbortController();
const abortSignal = abortController.signal;
let timeoutId;
try {
// Promise.race will be settled when the first promise in the list is settled.
// It will not cancel the remaining promises in the list.
// To avoid memory leaks, we must ensure other promises will be eventually terminated.
await Promise.race([
this.#initializeWithRetryPolicy(abortSignal),
// this promise will be rejected after timeout
new Promise((_, reject) => {
timeoutId = setTimeout(() => {
abortController.abort(); // abort the initialization promise
reject(new Error("Load operation timed out."));
},
startupTimeout);
})
]);
} catch (error) {
if (!isInputError(error)) {
const timeElapsed = Date.now() - startTimestamp;
if (timeElapsed < MIN_DELAY_FOR_UNHANDLED_FAILURE) {
// load() method is called in the application's startup code path.
// Unhandled exceptions cause application crash which can result in crash loops as orchestrators attempt to restart the application.
// Knowing the intended usage of the provider in startup code path, we mitigate back-to-back crash loops from overloading the server with requests by waiting a minimum time to propagate fatal errors.
await new Promise(resolve => setTimeout(resolve, MIN_DELAY_FOR_UNHANDLED_FAILURE - timeElapsed));
}
}
throw new Error("Failed to load.", { cause: error });
} finally {
clearTimeout(timeoutId); // cancel the timeout promise
}

// mark all settings have loaded at startup.
this.#isInitialLoadCompleted = true;
}

/**
Expand Down Expand Up @@ -380,6 +385,31 @@
if (this.#featureFlagEnabled) {
await this.#loadFeatureFlags();
}

if (this.#isCdnUsed) {
if (this.#watchAll) { // collection monitoring based refresh
// use the first page etag of the first kv selector
const defaultSelector = this.#kvSelectorCollection.selectors.find(s => s.pageEtags !== undefined);
if (defaultSelector && defaultSelector.pageEtags!.length > 0) {
this.#kvSelectorCollection.cdnCacheBreakString = defaultSelector.pageEtags![0];
} else {
this.#kvSelectorCollection.cdnCacheBreakString = undefined;
}
} else if (this.#refreshEnabled) { // watched settings based refresh
// use the etag of the first watched setting (sentinel)
this.#kvSelectorCollection.cdnCacheBreakString = this.#sentinels.find(s => s.etag !== undefined)?.etag;
}

Check failure on line 402 in src/AzureAppConfigurationImpl.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Trailing spaces not allowed

Check failure on line 402 in src/AzureAppConfigurationImpl.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Trailing spaces not allowed

Check failure on line 402 in src/AzureAppConfigurationImpl.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Trailing spaces not allowed
if (this.#featureFlagRefreshEnabled) {
const defaultSelector = this.#ffSelectorCollection.selectors.find(s => s.pageEtags !== undefined);
if (defaultSelector && defaultSelector.pageEtags!.length > 0) {
this.#ffSelectorCollection.cdnCacheBreakString = defaultSelector.pageEtags![0];
} else {
this.#ffSelectorCollection.cdnCacheBreakString = undefined;
}
}
}

Check failure on line 412 in src/AzureAppConfigurationImpl.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Trailing spaces not allowed

Check failure on line 412 in src/AzureAppConfigurationImpl.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Trailing spaces not allowed

Check failure on line 412 in src/AzureAppConfigurationImpl.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Trailing spaces not allowed
this.#isInitialLoadCompleted = true;
break;
} catch (error) {
Expand Down
5 changes: 3 additions & 2 deletions src/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { TokenCredential } from "@azure/identity";
import { AzureAppConfiguration } from "./AzureAppConfiguration.js";
import { AzureAppConfigurationImpl } from "./AzureAppConfigurationImpl.js";
import { AzureAppConfigurationOptions } from "./AzureAppConfigurationOptions.js";
import { ConfigurationClientManager, instanceOfTokenCredential } from "./ConfigurationClientManager.js";
import { ConfigurationClientManager } from "./ConfigurationClientManager.js";
import { EtagUrlPipelinePolicy } from "./EtagUrlPipelinePolicy.js";
import { instanceOfTokenCredential } from "./common/utils.js";

const MIN_DELAY_FOR_UNHANDLED_ERROR: number = 5_000; // 5 seconds

Expand Down Expand Up @@ -89,4 +90,4 @@ export async function loadFromCdn(
};

return await load(cdnEndpoint, emptyTokenCredential, appConfigOptions);
}
}
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.