Skip to content

Commit 58d1a70

Browse files
committed
Gating host specialization on WEBSITE_CONFIGURATION_READY (#2867)
1 parent 6bbd4fd commit 58d1a70

File tree

6 files changed

+28
-8
lines changed

6 files changed

+28
-8
lines changed

src/WebJobs.Script.WebHost/Management/InstanceManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ private async Task Assign(HostAssignmentContext assignmentContext)
102102
_logger.LogInformation("Triggering specialization");
103103
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0");
104104
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady, "1");
105+
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteConfigurationReady, "1");
105106
}
106107
catch (Exception ex)
107108
{

src/WebJobs.Script.WebHost/WebHostResolver.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ internal void EnsureInitialized(WebHostSettings settings)
110110
// 1) We _were_ in standby mode and now we're ready to specialize
111111
// 2) We're doing non-specialization normal initialization
112112
if (_activeHostManager == null &&
113-
(_standbyHostManager == null || _settingsManager.ContainerReady))
113+
(_standbyHostManager == null || (_settingsManager.ContainerReady && _settingsManager.ConfigurationReady)))
114114
{
115115
_specializationTimer?.Dispose();
116116
_specializationTimer = null;
@@ -239,12 +239,12 @@ private void OnSpecializationTimerTick(object state)
239239
{
240240
EnsureInitialized((WebHostSettings)state);
241241

242-
// We know we've just specialized, since this timer only runs
243-
// when in standby mode. We want to initialize the host manager
244-
// immediately. Note that the host might also be initialized
245-
// concurrently by incoming http requests, but the initialization
246-
// here ensures that it takes place in the absence of any http
247-
// traffic.
242+
// If the active manager is not null, we know we've just specialized,
243+
// since this timer only runs when in standby mode. We want to initialize
244+
// the host manager immediately.
245+
// Note that the host might also be initialized concurrently by incoming
246+
// http requests, but the initialization here ensures that it takes place
247+
// in the absence of any http traffic.
248248
_activeHostManager?.EnsureHostStarted(CancellationToken.None);
249249
}
250250

src/WebJobs.Script/Config/ScriptSettingsManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public bool IsLinuxContainerEnvironment
4848

4949
public virtual bool ContainerReady => !string.IsNullOrEmpty(GetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady));
5050

51+
public virtual bool ConfigurationReady => !string.IsNullOrEmpty(GetSetting(EnvironmentSettingNames.AzureWebsiteConfigurationReady));
52+
5153
public string WebsiteSku => GetSetting(EnvironmentSettingNames.AzureWebsiteSku);
5254

5355
public bool IsDynamicSku => WebsiteSku == ScriptConstants.DynamicSku;

src/WebJobs.Script/EnvironmentSettingNames.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public static class EnvironmentSettingNames
1515
public const string AzureWebsiteAltZipDeployment = "WEBSITE_RUN_FROM_ZIP";
1616
public const string RemoteDebuggingPort = "REMOTEDEBUGGINGPORT";
1717
public const string AzureWebsitePlaceholderMode = "WEBSITE_PLACEHOLDER_MODE";
18-
public const string AzureWebsiteContainerReady = "WEBSITE_CONTAINER_READY";
1918
public const string AzureWebsiteHomePath = "HOME";
2019
public const string AzureWebJobsScriptRoot = "AzureWebJobsScriptRoot";
2120
public const string AzureWebJobsEnvironment = "AzureWebJobsEnv";
@@ -32,5 +31,18 @@ public static class EnvironmentSettingNames
3231
public const string ContainerEncryptionKey = "CONTAINER_ENCRYPTION_KEY";
3332
public const string ConsoleLoggingDisabled = "CONSOLE_LOGGING_DISABLED";
3433
public const string SkipSslValidation = "SCM_SKIP_SSL_VALIDATION";
34+
35+
/// <summary>
36+
/// Environment variable dynamically set by the platform when it is safe to
37+
/// start specializing the host instance (e.g. file system is ready, etc.)
38+
/// </summary>
39+
public const string AzureWebsiteContainerReady = "WEBSITE_CONTAINER_READY";
40+
41+
/// <summary>
42+
/// Environment variable dynamically set by the platform when configuration has been
43+
/// completely initialized (e.g. EnvSettings module has ran) and it is safe to read
44+
/// configuration values.
45+
/// </summary>
46+
public const string AzureWebsiteConfigurationReady = "WEBSITE_CONFIGURATION_READY";
3547
}
3648
}

test/WebJobs.Script.Tests.Integration/Host/StandbyManagerTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public async Task StandbyMode_EndToEnd()
108108
{ EnvironmentSettingNames.AzureWebsiteContainerReady, null },
109109
{ EnvironmentSettingNames.AzureWebsiteSku, "Dynamic" },
110110
{ EnvironmentSettingNames.AzureWebsiteHomePath, null },
111+
{ EnvironmentSettingNames.AzureWebsiteConfigurationReady, null },
111112
{ EnvironmentSettingNames.AzureWebsiteInstanceId, "87654639876900123453445678890144" },
112113
{ "AzureWebEncryptionKey", "0F75CA46E7EBDD39E4CA6B074D1F9A5972B849A55F91A248" }
113114
};
@@ -121,6 +122,7 @@ public async Task StandbyMode_EndToEnd()
121122
// now specialize the host
122123
ScriptSettingsManager.Instance.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0");
123124
ScriptSettingsManager.Instance.SetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady, "1");
125+
ScriptSettingsManager.Instance.SetSetting(EnvironmentSettingNames.AzureWebsiteConfigurationReady, "1");
124126

125127
Assert.False(WebScriptHostManager.InStandbyMode);
126128
Assert.True(ScriptSettingsManager.Instance.ContainerReady);
@@ -164,6 +166,7 @@ public async Task StandbyMode_EndToEnd_LinuxContainer()
164166
{ EnvironmentSettingNames.AzureWebsiteName, "TestApp" },
165167
{ EnvironmentSettingNames.ContainerEncryptionKey, encryptionKey },
166168
{ EnvironmentSettingNames.AzureWebsiteContainerReady, null },
169+
{ EnvironmentSettingNames.AzureWebsiteConfigurationReady, null },
167170
{ EnvironmentSettingNames.AzureWebsiteSku, "Dynamic" },
168171
{ EnvironmentSettingNames.AzureWebsiteZipDeployment, null },
169172
{ "AzureWebEncryptionKey", "0F75CA46E7EBDD39E4CA6B074D1F9A5972B849A55F91A248" }

test/WebJobs.Script.Tests.Integration/Host/StandbyModeTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public async Task EnsureInitialized_PlaceholderMode()
111111

112112
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0");
113113
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady, "1");
114+
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteConfigurationReady, "1");
114115
Assert.False(WebScriptHostManager.InStandbyMode);
115116
_webHostResolver.EnsureInitialized(settings);
116117

@@ -138,6 +139,7 @@ private async Task TestGetter<T>(Func<WebHostSettings, T> func)
138139

139140
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0");
140141
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady, "1");
142+
_settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteConfigurationReady, "1");
141143
current = func(settings);
142144
Assert.NotNull(current);
143145
Assert.NotSame(prev, current);

0 commit comments

Comments
 (0)