@@ -10,6 +10,7 @@ import {
1010 ListConfigurationSettingsOptions ,
1111 featureFlagPrefix ,
1212 isFeatureFlag ,
13+ isSecretReference ,
1314 GetSnapshotOptions ,
1415 GetSnapshotResponse ,
1516 KnownSnapshotComposition
@@ -104,6 +105,9 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
104105 #ffRefreshInterval: number = DEFAULT_REFRESH_INTERVAL_IN_MS ;
105106 #ffRefreshTimer: RefreshTimer ;
106107
108+ // Key Vault references
109+ #resolveSecretsInParallel: boolean = false ;
110+
107111 /**
108112 * Selectors of key-values obtained from @see AzureAppConfigurationOptions.selectors
109113 */
@@ -184,6 +188,10 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
184188 }
185189 }
186190
191+ if ( options ?. keyVaultOptions ?. parallelSecretResolutionEnabled ) {
192+ this . #resolveSecretsInParallel = options . keyVaultOptions . parallelSecretResolutionEnabled ;
193+ }
194+
187195 this . #adapters. push ( new AzureKeyVaultKeyValueAdapter ( options ?. keyVaultOptions ) ) ;
188196 this . #adapters. push ( new JsonKeyValueAdapter ( ) ) ;
189197 }
@@ -529,7 +537,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
529537 */
530538 async #loadSelectedAndWatchedKeyValues( ) {
531539 const keyValues : [ key : string , value : unknown ] [ ] = [ ] ;
532- const loadedSettings = await this . #loadConfigurationSettings( ) ;
540+ const loadedSettings : ConfigurationSetting [ ] = await this . #loadConfigurationSettings( ) ;
533541 if ( this . #refreshEnabled && ! this . #watchAll) {
534542 await this . #updateWatchedKeyValuesEtag( loadedSettings ) ;
535543 }
@@ -539,11 +547,25 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
539547 this . #aiConfigurationTracing. reset ( ) ;
540548 }
541549
542- // adapt configuration settings to key-values
550+ const secretResolutionPromises : Promise < void > [ ] = [ ] ;
543551 for ( const setting of loadedSettings ) {
552+ if ( this . #resolveSecretsInParallel && isSecretReference ( setting ) ) {
553+ // secret references are resolved asynchronously to improve performance
554+ const secretResolutionPromise = this . #processKeyValue( setting )
555+ . then ( ( [ key , value ] ) => {
556+ keyValues . push ( [ key , value ] ) ;
557+ } ) ;
558+ secretResolutionPromises . push ( secretResolutionPromise ) ;
559+ continue ;
560+ }
561+ // adapt configuration settings to key-values
544562 const [ key , value ] = await this . #processKeyValue( setting ) ;
545563 keyValues . push ( [ key , value ] ) ;
546564 }
565+ if ( secretResolutionPromises . length > 0 ) {
566+ // wait for all secret resolution promises to be resolved
567+ await Promise . all ( secretResolutionPromises ) ;
568+ }
547569
548570 this . #clearLoadedKeyValues( ) ; // clear existing key-values in case of configuration setting deletion
549571 for ( const [ k , v ] of keyValues ) {
@@ -588,7 +610,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
588610 */
589611 async #loadFeatureFlags( ) {
590612 const loadFeatureFlag = true ;
591- const featureFlagSettings = await this . #loadConfigurationSettings( loadFeatureFlag ) ;
613+ const featureFlagSettings : ConfigurationSetting [ ] = await this . #loadConfigurationSettings( loadFeatureFlag ) ;
592614
593615 if ( this . #requestTracingEnabled && this . #featureFlagTracing !== undefined ) {
594616 // Reset old feature flag tracing in order to track the information present in the current response from server.
@@ -959,7 +981,9 @@ function getValidFeatureFlagSelectors(selectors?: SettingSelector[]): SettingSel
959981 return [ { keyFilter : `${ featureFlagPrefix } ${ KeyFilter . Any } ` , labelFilter : LabelFilter . Null } ] ;
960982 }
961983 selectors . forEach ( selector => {
962- selector . keyFilter = `${ featureFlagPrefix } ${ selector . keyFilter } ` ;
984+ if ( selector . keyFilter ) {
985+ selector . keyFilter = `${ featureFlagPrefix } ${ selector . keyFilter } ` ;
986+ }
963987 } ) ;
964988 return getValidSettingSelectors ( selectors ) ;
965989}
0 commit comments