1919
2020namespace Microsoft . Azure . WebJobs . Script . WebHost . Management
2121{
22- public class InstanceManager : IInstanceManager
22+ public class AtlasInstanceManager : LinuxInstanceManager
2323 {
24- private static readonly object _assignmentLock = new object ( ) ;
25- private static HostAssignmentContext _assignmentContext ;
24+ private readonly object _assignmentLock = new object ( ) ;
2625
2726 private readonly ILogger _logger ;
2827 private readonly IMetricsLogger _metricsLogger ;
@@ -34,9 +33,10 @@ public class InstanceManager : IInstanceManager
3433 private readonly HttpClient _client ;
3534 private readonly IScriptWebHostEnvironment _webHostEnvironment ;
3635
37- public InstanceManager ( IOptionsFactory < ScriptApplicationHostOptions > optionsFactory , IHttpClientFactory httpClientFactory , IScriptWebHostEnvironment webHostEnvironment ,
38- IEnvironment environment , ILogger < InstanceManager > logger , IMetricsLogger metricsLogger , IMeshServiceClient meshServiceClient , IRunFromPackageHandler runFromPackageHandler ,
39- IPackageDownloadHandler packageDownloadHandler )
36+ public AtlasInstanceManager ( IOptionsFactory < ScriptApplicationHostOptions > optionsFactory , IHttpClientFactory httpClientFactory , IScriptWebHostEnvironment webHostEnvironment ,
37+ IEnvironment environment , ILogger < AtlasInstanceManager > logger , IMetricsLogger metricsLogger , IMeshServiceClient meshServiceClient , IRunFromPackageHandler runFromPackageHandler ,
38+ IPackageDownloadHandler packageDownloadHandler ) : base ( httpClientFactory , webHostEnvironment ,
39+ environment , logger , metricsLogger , meshServiceClient )
4040 {
4141 _client = httpClientFactory ? . CreateClient ( ) ?? throw new ArgumentNullException ( nameof ( httpClientFactory ) ) ;
4242 _webHostEnvironment = webHostEnvironment ?? throw new ArgumentNullException ( nameof ( webHostEnvironment ) ) ;
@@ -49,7 +49,7 @@ public InstanceManager(IOptionsFactory<ScriptApplicationHostOptions> optionsFact
4949 _optionsFactory = optionsFactory ?? throw new ArgumentNullException ( nameof ( optionsFactory ) ) ;
5050 }
5151
52- public async Task < string > SpecializeMSISidecar ( HostAssignmentContext context )
52+ public override async Task < string > SpecializeMSISidecar ( HostAssignmentContext context )
5353 {
5454 // No cold start optimization needed for side car scenarios
5555 if ( context . IsWarmupRequest )
@@ -103,65 +103,7 @@ await _meshServiceClient.NotifyHealthEvent(ContainerHealthEventType.Fatal, this.
103103 return null ;
104104 }
105105
106- public bool StartAssignment ( HostAssignmentContext context )
107- {
108- if ( ! _webHostEnvironment . InStandbyMode )
109- {
110- // This is only true when specializing pinned containers.
111- if ( ! context . Environment . TryGetValue ( EnvironmentSettingNames . ContainerStartContext , out string startContext ) )
112- {
113- _logger . LogError ( "Assign called while host is not in placeholder mode and start context is not present." ) ;
114- return false ;
115- }
116- }
117-
118- if ( _environment . IsContainerReady ( ) )
119- {
120- _logger . LogError ( "Assign called while container is marked as specialized." ) ;
121- return false ;
122- }
123-
124- if ( context . IsWarmupRequest )
125- {
126- // Based on profiling download code jit-ing holds up cold start.
127- // Pre-jit to avoid paying the cost later.
128- Task . Run ( async ( ) => await _packageDownloadHandler . Download ( context . GetRunFromPkgContext ( ) ) ) ;
129- return true ;
130- }
131- else if ( _assignmentContext == null )
132- {
133- lock ( _assignmentLock )
134- {
135- if ( _assignmentContext != null )
136- {
137- return _assignmentContext . Equals ( context ) ;
138- }
139- _assignmentContext = context ;
140- }
141-
142- _logger . LogInformation ( $ "Starting Assignment. Cloud Name: { _environment . GetCloudName ( ) } ") ;
143-
144- // set a flag which will cause any incoming http requests to buffer
145- // until specialization is complete
146- // the host is guaranteed not to receive any requests until AFTER assign
147- // has been initiated, so setting this flag here is sufficient to ensure
148- // that any subsequent incoming requests while the assign is in progress
149- // will be delayed until complete
150- _webHostEnvironment . DelayRequests ( ) ;
151-
152- // start the specialization process in the background
153- Task . Run ( async ( ) => await Assign ( context ) ) ;
154-
155- return true ;
156- }
157- else
158- {
159- // No lock needed here since _assignmentContext is not null when we are here
160- return _assignmentContext . Equals ( context ) ;
161- }
162- }
163-
164- public async Task < string > ValidateContext ( HostAssignmentContext assignmentContext )
106+ public override async Task < string > ValidateContext ( HostAssignmentContext assignmentContext )
165107 {
166108 _logger . LogInformation ( $ "Validating host assignment context (SiteId: { assignmentContext . SiteId } , SiteName: '{ assignmentContext . SiteName } '. IsWarmup: '{ assignmentContext . IsWarmupRequest } ')") ;
167109 RunFromPackageContext pkgContext = assignmentContext . GetRunFromPkgContext ( ) ;
@@ -214,6 +156,11 @@ public async Task<string> ValidateContext(HostAssignmentContext assignmentContex
214156 }
215157 }
216158
159+ protected override async Task < string > DownloadWarmupAsync ( RunFromPackageContext context )
160+ {
161+ return await _packageDownloadHandler . Download ( context ) ;
162+ }
163+
217164 private async Task < ( string Error , long ? ContentLength ) > ValidateBlobPackageContext ( RunFromPackageContext context )
218165 {
219166 string blobUri = context . Url ;
@@ -277,38 +224,8 @@ private async Task<string> ValidateAzureFilesContext(string connectionString, st
277224 }
278225 }
279226
280- private async Task Assign ( HostAssignmentContext assignmentContext )
227+ protected override async Task ApplyContextAsync ( HostAssignmentContext assignmentContext )
281228 {
282- try
283- {
284- // first make all environment and file system changes required for
285- // the host to be specialized
286- await ApplyContext ( assignmentContext ) ;
287- }
288- catch ( Exception ex )
289- {
290- _logger . LogError ( ex , "Assign failed" ) ;
291- await _meshServiceClient . NotifyHealthEvent ( ContainerHealthEventType . Fatal , GetType ( ) , "Assign failed" ) ;
292- throw ;
293- }
294- finally
295- {
296- // all assignment settings/files have been applied so we can flip
297- // the switch now on specialization
298- // even if there are failures applying context above, we want to
299- // leave placeholder mode
300- _logger . LogInformation ( "Triggering specialization" ) ;
301- _webHostEnvironment . FlagAsSpecializedAndReady ( ) ;
302-
303- _webHostEnvironment . ResumeRequests ( ) ;
304- }
305- }
306-
307- private async Task ApplyContext ( HostAssignmentContext assignmentContext )
308- {
309- _logger . LogInformation ( $ "Applying { assignmentContext . Environment . Count } app setting(s)") ;
310- assignmentContext . ApplyAppSettings ( _environment , _logger ) ;
311-
312229 // We need to get the non-PlaceholderMode script Path so we can unzip to the correct location.
313230 // This asks the factory to skip the PlaceholderMode check when configuring options.
314231 var options = _optionsFactory . Create ( ScriptApplicationHostOptionsSetup . SkipPlaceholder ) ;
@@ -447,20 +364,5 @@ await Utility.InvokeWithRetriesAsync(async () =>
447364 return false ;
448365 }
449366 }
450-
451- public IDictionary < string , string > GetInstanceInfo ( )
452- {
453- return new Dictionary < string , string >
454- {
455- { "FUNCTIONS_EXTENSION_VERSION" , ScriptHost . Version } ,
456- { "WEBSITE_NODE_DEFAULT_VERSION" , "8.5.0" }
457- } ;
458- }
459-
460- // for testing
461- internal static void Reset ( )
462- {
463- _assignmentContext = null ;
464- }
465367 }
466368}
0 commit comments