33
44using System ;
55using System . IO ;
6+ using System . Linq ;
67using System . Threading ;
78using System . Threading . Tasks ;
89using Microsoft . AspNetCore . Http ;
@@ -20,6 +21,7 @@ public class HostWarmupMiddleware
2021 private readonly IEnvironment _environment ;
2122 private readonly IScriptHostManager _hostManager ;
2223 private readonly ILogger _logger ;
24+ private string _assemblyLocalPath ;
2325
2426 public HostWarmupMiddleware ( RequestDelegate next , IScriptWebHostEnvironment webHostEnvironment , IEnvironment environment , IScriptHostManager hostManager , ILogger < HostWarmupMiddleware > logger )
2527 {
@@ -28,6 +30,7 @@ public HostWarmupMiddleware(RequestDelegate next, IScriptWebHostEnvironment webH
2830 _environment = environment ;
2931 _hostManager = hostManager ;
3032 _logger = logger ;
33+ _assemblyLocalPath = Path . GetDirectoryName ( new Uri ( typeof ( HostWarmupMiddleware ) . Assembly . CodeBase ) . LocalPath ) ;
3134 }
3235
3336 public async Task Invoke ( HttpContext httpContext )
@@ -40,17 +43,58 @@ public async Task Invoke(HttpContext httpContext)
4043 PreJitPrepare ( WarmUpConstants . LinuxJitTraceFileName ) ;
4144 }
4245
46+ ReadRuntimeAssemblyFiles ( ) ;
47+
4348 await WarmUp ( httpContext . Request ) ;
4449 }
4550
4651 await _next . Invoke ( httpContext ) ;
4752 }
4853
54+ internal void ReadRuntimeAssemblyFiles ( )
55+ {
56+ try
57+ {
58+ string [ ] allFiles = Directory . GetFiles ( _assemblyLocalPath , "*.dll" , SearchOption . TopDirectoryOnly ) ;
59+ foreach ( string file in allFiles )
60+ {
61+ // Read file content to avoid disk reads during specialization. This is only to page-in bytes.
62+ ReadFileInChunks ( file ) ;
63+ }
64+ _logger . LogDebug ( new EventId ( 100 , nameof ( ReadRuntimeAssemblyFiles ) ) , $ "Number of files read: { allFiles . Count ( ) } .") ;
65+ }
66+ catch ( Exception ex )
67+ {
68+ _logger . LogDebug ( new EventId ( 100 , nameof ( ReadRuntimeAssemblyFiles ) ) , ex , "Reading ReadRuntimeAssemblyFiles failed" ) ;
69+ }
70+ }
71+
72+ private void ReadFileInChunks ( string file )
73+ {
74+ try
75+ {
76+ // Read File content in 4K chunks
77+ const int MAX_BUFFER = 4 * 1024 ;
78+ byte [ ] chunk = new byte [ MAX_BUFFER ] ;
79+ int bytesRead ;
80+ using ( FileStream fileStream = new FileStream ( file , FileMode . Open , FileAccess . Read ) )
81+ {
82+ while ( ( bytesRead = fileStream . Read ( chunk , 0 , MAX_BUFFER ) ) != 0 )
83+ {
84+ }
85+ }
86+ }
87+ catch ( Exception ex )
88+ {
89+ _logger . LogDebug ( new EventId ( 100 , nameof ( ReadFileInChunks ) ) , ex , $ "Reading file '{ file } ' failed") ;
90+ }
91+ }
92+
4993 private void PreJitPrepare ( string jitTraceFileName )
5094 {
5195 // This is to PreJIT all methods captured in coldstart.jittrace file to improve cold start time
5296 var path = Path . Combine (
53- Path . GetDirectoryName ( new Uri ( typeof ( HostWarmupMiddleware ) . Assembly . CodeBase ) . LocalPath ) ,
97+ _assemblyLocalPath ,
5498 WarmUpConstants . PreJitFolderName , jitTraceFileName ) ;
5599
56100 var file = new FileInfo ( path ) ;
0 commit comments