@@ -10,6 +10,7 @@ import {
1010 ListConfigurationSettingsOptions ,
1111 featureFlagPrefix ,
1212 isFeatureFlag ,
13+ isSecretReference ,
1314 GetSnapshotOptions ,
1415 GetSnapshotResponse ,
1516 KnownSnapshotComposition
@@ -102,6 +103,9 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
102103 #ffRefreshInterval: number = DEFAULT_REFRESH_INTERVAL_IN_MS ;
103104 #ffRefreshTimer: RefreshTimer ;
104105
106+ // Key Vault references
107+ #resolveSecretsInParallel: boolean = false ;
108+
105109 /**
106110 * Selectors of key-values obtained from @see AzureAppConfigurationOptions.selectors
107111 */
@@ -182,6 +186,10 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
182186 }
183187 }
184188
189+ if ( options ?. keyVaultOptions ?. parallelSecretResolutionEnabled ) {
190+ this . #resolveSecretsInParallel = options . keyVaultOptions . parallelSecretResolutionEnabled ;
191+ }
192+
185193 this . #adapters. push ( new AzureKeyVaultKeyValueAdapter ( options ?. keyVaultOptions ) ) ;
186194 this . #adapters. push ( new JsonKeyValueAdapter ( ) ) ;
187195 }
@@ -526,7 +534,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
526534 */
527535 async #loadSelectedAndWatchedKeyValues( ) {
528536 const keyValues : [ key : string , value : unknown ] [ ] = [ ] ;
529- const loadedSettings = await this . #loadConfigurationSettings( ) ;
537+ const loadedSettings : ConfigurationSetting [ ] = await this . #loadConfigurationSettings( ) ;
530538 if ( this . #refreshEnabled && ! this . #watchAll) {
531539 await this . #updateWatchedKeyValuesEtag( loadedSettings ) ;
532540 }
@@ -536,11 +544,25 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
536544 this . #aiConfigurationTracing. reset ( ) ;
537545 }
538546
539- // adapt configuration settings to key-values
547+ const secretResolutionPromises : Promise < void > [ ] = [ ] ;
540548 for ( const setting of loadedSettings ) {
549+ if ( this . #resolveSecretsInParallel && isSecretReference ( setting ) ) {
550+ // secret references are resolved asynchronously to improve performance
551+ const secretResolutionPromise = this . #processKeyValue( setting )
552+ . then ( ( [ key , value ] ) => {
553+ keyValues . push ( [ key , value ] ) ;
554+ } ) ;
555+ secretResolutionPromises . push ( secretResolutionPromise ) ;
556+ continue ;
557+ }
558+ // adapt configuration settings to key-values
541559 const [ key , value ] = await this . #processKeyValue( setting ) ;
542560 keyValues . push ( [ key , value ] ) ;
543561 }
562+ if ( secretResolutionPromises . length > 0 ) {
563+ // wait for all secret resolution promises to be resolved
564+ await Promise . all ( secretResolutionPromises ) ;
565+ }
544566
545567 this . #clearLoadedKeyValues( ) ; // clear existing key-values in case of configuration setting deletion
546568 for ( const [ k , v ] of keyValues ) {
@@ -585,7 +607,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
585607 */
586608 async #loadFeatureFlags( ) {
587609 const loadFeatureFlag = true ;
588- const featureFlagSettings = await this . #loadConfigurationSettings( loadFeatureFlag ) ;
610+ const featureFlagSettings : ConfigurationSetting [ ] = await this . #loadConfigurationSettings( loadFeatureFlag ) ;
589611
590612 if ( this . #requestTracingEnabled && this . #featureFlagTracing !== undefined ) {
591613 // Reset old feature flag tracing in order to track the information present in the current response from server.
0 commit comments