/// <summary> /// Loads (or reloads) the data for this provider. /// </summary> public override void Load() { var watch = Stopwatch.StartNew(); try { // Load() is invoked only once during application startup. We don't need to check for concurrent network // operations here because there can't be any other startup or refresh operation in progress at this time. LoadAll(_optional, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (ArgumentException) { // Instantly re-throw the exception throw; } catch { // AzureAppConfigurationProvider.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 propogate fatal errors. var waitInterval = MinDelayForUnhandledFailure.Subtract(watch.Elapsed); if (waitInterval.Ticks > 0) { Task.Delay(waitInterval).ConfigureAwait(false).GetAwaiter().GetResult(); } // Re-throw the exception after the additional delay (if required) throw; } finally { // Set the provider for AzureAppConfigurationRefresher instance after LoadAll has completed. // This stops applications from calling RefreshAsync until config has been initialized during startup. var refresher = (AzureAppConfigurationRefresher)_options.GetRefresher(); refresher.SetProvider(this); } // Mark all settings have loaded at startup. _isInitialLoadComplete = true; }
/// <summary> /// Loads (or reloads) the data for this provider. /// </summary> public override void Load() { var watch = Stopwatch.StartNew(); var refresher = (AzureAppConfigurationRefresher)_options.GetRefresher(); refresher.SetProvider(this); try { LoadAll(_optional).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (ArgumentException) { // Instantly re-throw the exception throw; } catch { // AzureAppConfigurationProvider.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 propogate fatal errors. var waitTime = MinDelayForUnhandledFailure.Subtract(watch.Elapsed); if (waitTime.Ticks > 0) { Task.Delay(waitTime).ConfigureAwait(false).GetAwaiter().GetResult(); } // Re-throw the exception after the additional delay (if required) throw; } // Mark all settings have loaded at startup. _isInitialLoadComplete = true; }