Skip to content

Commit 6fc46c7

Browse files
authored
Make warmup execute once (#5137)
1 parent 3ceb9ef commit 6fc46c7

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

src/WebJobs.Script.WebHost/Controllers/HostController.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class HostController : Controller
4848
private readonly IEnvironment _environment;
4949
private readonly IScriptHostManager _scriptHostManager;
5050
private readonly IFunctionsSyncManager _functionsSyncManager;
51+
private static int _warmupExecuted;
5152

5253
public HostController(IOptions<ScriptApplicationHostOptions> applicationHostOptions,
5354
IOptions<JobHostOptions> hostOptions,
@@ -292,10 +293,20 @@ public IActionResult GetAdminToken()
292293
[HttpGet]
293294
[HttpPost]
294295
[Route("admin/warmup")]
295-
[Authorize(Policy = PolicyNames.AdminAuthLevelOrInternal)]
296296
[RequiresRunningHost]
297297
public async Task<IActionResult> Warmup([FromServices] WebJobsScriptHostService hostService)
298298
{
299+
// Endpoint only for Windows Elastic Premium or Linux App Service plans
300+
if (!(_environment.IsLinuxAppService() || _environment.IsWindowsElasticPremium()))
301+
{
302+
return BadRequest("This API is not available for the current hosting plan");
303+
}
304+
305+
if (Interlocked.CompareExchange(ref _warmupExecuted, 1, 0) != 0)
306+
{
307+
return Ok();
308+
}
309+
299310
var jobHost = hostService.Services?.GetService<IScriptJobHost>();
300311
if (jobHost == null)
301312
{

src/WebJobs.Script/Config/ScriptSettingsManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public static ScriptSettingsManager Instance
3939

4040
public bool IsDynamicSku => WebsiteSku == ScriptConstants.DynamicSku;
4141

42+
public bool IsElasticPremiumSku => WebsiteSku == ScriptConstants.ElasticPremiumSku;
43+
4244
public virtual string AzureWebsiteInstanceId
4345
{
4446
get

src/WebJobs.Script/Environment/EnvironmentExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,18 @@ public static bool IsWindowsConsumption(this IEnvironment environment)
134134
return string.Equals(value, ScriptConstants.DynamicSku, StringComparison.OrdinalIgnoreCase);
135135
}
136136

137+
/// <summary>
138+
/// Gets a value indicating whether the application is running in a Windows Elastic Premium
139+
/// App Service environment.
140+
/// </summary>
141+
/// <param name="environment">The environment to verify</param>
142+
/// <returns><see cref="true"/> if running in a Windows Elastic Premium app; otherwise, false.</returns>
143+
public static bool IsWindowsElasticPremium(this IEnvironment environment)
144+
{
145+
string value = environment.GetEnvironmentVariable(AzureWebsiteSku);
146+
return string.Equals(value, ScriptConstants.ElasticPremiumSku, StringComparison.OrdinalIgnoreCase);
147+
}
148+
137149
/// <summary>
138150
/// Gets a value indicating whether the application is running in an Azure Windows managed hosting environment
139151
/// (i.e. Windows Consumption or Windows Dedicated)

src/WebJobs.Script/ScriptConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public static class ScriptConstants
8888
public const string AntaresColdStartHeaderName = "X-MS-COLDSTART";
8989
public const string SiteTokenHeaderName = "x-ms-site-restricted-token";
9090
public const string DynamicSku = "Dynamic";
91+
public const string ElasticPremiumSku = "ElasticPremium";
9192
public const string DefaultProductionSlotName = "production";
9293

9394
public const string AzureProxyFunctionLocalRedirectKey = "MS_ProxyLocalRedirectCount";

test/WebJobs.Script.Tests.Integration/Controllers/WarmupScenarios.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,17 @@ public async Task TestWarmupEndPoint_WhenHostStarts()
3232
{
3333
string testScriptPath = Path.Combine("TestScripts", "CSharp");
3434
string testLogPath = Path.Combine(TestHelpers.FunctionsTestDirectory, "Logs", Guid.NewGuid().ToString(), @"Functions");
35+
var settings = new Dictionary<string, string>()
36+
{
37+
["WEBSITE_SKU"] = "ElasticPremium"
38+
};
39+
var testEnvironment = new TestEnvironment(settings);
3540

3641
_testHost = new TestFunctionHost(testScriptPath, testLogPath,
3742
configureWebHostServices: services =>
3843
{
3944
services.AddSingleton<IScriptHostBuilder, PausingScriptHostBuilder>();
40-
45+
services.AddSingleton<IEnvironment>(testEnvironment);
4146
services.AddSingleton<IConfigureBuilder<IWebJobsBuilder>>(new DelegatedConfigureBuilder<IWebJobsBuilder>(b =>
4247
{
4348
b.UseHostId("1234");
@@ -64,8 +69,7 @@ public async Task TestWarmupEndPoint_WhenHostStarts()
6469

6570
// Let's make the warmup request and not wait for it to finish,
6671
// as warmup call needs the host to be running while the host is currently paused
67-
string masterKey = await _testHost.GetMasterKeyAsync();
68-
string uri = $"admin/warmup?code={masterKey}";
72+
string uri = "admin/warmup";
6973
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
7074
Task<HttpResponseMessage> responseTask = _testHost.HttpClient.SendAsync(request);
7175

0 commit comments

Comments
 (0)