|
2 | 2 | // Licensed under the MIT License. See License.txt in the project root for license information.
|
3 | 3 |
|
4 | 4 | using System;
|
| 5 | +using System.Buffers; |
5 | 6 | using System.Collections.Generic;
|
6 | 7 | using System.IO;
|
7 | 8 | using System.Linq;
|
8 | 9 | using System.Text.Json;
|
9 | 10 | using System.Text.RegularExpressions;
|
| 11 | +using System.Threading.Tasks; |
10 | 12 | using Microsoft.Azure.WebJobs.Script.Diagnostics;
|
11 | 13 | using Microsoft.Azure.WebJobs.Script.Workers.Profiles;
|
12 | 14 | using Microsoft.Extensions.Configuration;
|
@@ -357,13 +359,43 @@ internal bool ShouldAddWorkerConfig(string workerDescriptionLanguage)
|
357 | 359 |
|
358 | 360 | private void ReadLanguageWorkerFile(string workerPath)
|
359 | 361 | {
|
360 |
| - if (_environment.IsPlaceholderModeEnabled() |
361 |
| - && !string.IsNullOrEmpty(_workerRuntime) |
362 |
| - && File.Exists(workerPath)) |
| 362 | + if (!_environment.IsPlaceholderModeEnabled() |
| 363 | + || string.IsNullOrWhiteSpace(_workerRuntime) |
| 364 | + || !File.Exists(workerPath)) |
363 | 365 | {
|
364 |
| - // Read language worker file to avoid disk reads during specialization. This is only to page-in bytes. |
365 |
| - File.ReadAllBytes(workerPath); |
| 366 | + return; |
366 | 367 | }
|
| 368 | + |
| 369 | + // Reads the file to warm up the operating system's file cache. Can run in the background. |
| 370 | + _ = Task.Run(() => |
| 371 | + { |
| 372 | + const int bufferSize = 4096; |
| 373 | + var buffer = ArrayPool<byte>.Shared.Rent(bufferSize); |
| 374 | + |
| 375 | + try |
| 376 | + { |
| 377 | + using var fs = new FileStream( |
| 378 | + workerPath, |
| 379 | + FileMode.Open, |
| 380 | + FileAccess.Read, |
| 381 | + FileShare.Read, |
| 382 | + bufferSize, |
| 383 | + FileOptions.SequentialScan); |
| 384 | + |
| 385 | + while (fs.Read(buffer, 0, bufferSize) > 0) |
| 386 | + { |
| 387 | + // Do nothing. The goal is to read the file into the OS cache. |
| 388 | + } |
| 389 | + } |
| 390 | + catch (Exception ex) |
| 391 | + { |
| 392 | + _logger.LogError(ex, "Unexpected error warming up worker file: {filePath}", workerPath); |
| 393 | + } |
| 394 | + finally |
| 395 | + { |
| 396 | + ArrayPool<byte>.Shared.Return(buffer); |
| 397 | + } |
| 398 | + }); |
367 | 399 | }
|
368 | 400 | }
|
369 | 401 | }
|
0 commit comments