Skip to content

Commit

Permalink
Download inputs from previous jobs + improve resilience
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan committed May 23, 2024
1 parent b791ad2 commit 91e22a7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
23 changes: 18 additions & 5 deletions Runner/FuzzLibrariesJob.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using System.IO.Compression;
using System.Text.RegularExpressions;

namespace Runner;

Expand Down Expand Up @@ -101,6 +102,7 @@ private async Task RunFuzzersAsync(string fuzzerNamePattern)
int remainingFuzzers = matchingFuzzers.Length - i;
TimeSpan remainingTime = MaxJobDuration - JobStopwatch.Elapsed - TimeSpan.FromMinutes(15);
int durationSeconds = (int)(remainingTime / remainingFuzzers).TotalSeconds;
durationSeconds = Math.Min(3600, durationSeconds);

ArgumentOutOfRangeException.ThrowIfLessThan(durationSeconds, 60);

Expand All @@ -116,17 +118,28 @@ private async Task<bool> RunFuzzerAsync(string fuzzerName, int durationSeconds)

string fuzzerDirectory = $"{DeploymentPath}/{fuzzerName}";
string inputsDirectory = $"{fuzzerName}-inputs";
string artifactPathPrefix = $"{fuzzerName}-artifact-";

Directory.CreateDirectory(inputsDirectory);

string artifactPathPrefix = $"{fuzzerName}-artifact-";
try
{
var remoteInputsZipBlob = PersistentStateClient.GetBlobClient($"{inputsDirectory}.zip");
if (await remoteInputsZipBlob.ExistsAsync(JobTimeout))
{
var content = (await remoteInputsZipBlob.DownloadContentAsync(JobTimeout)).Value;
ZipFile.ExtractToDirectory(content.Content.ToStream(), inputsDirectory);
}
}
catch (Exception ex)
{
await LogAsync($"Failed to download previous inputs archive: {ex}");
}

int parallelism = Environment.ProcessorCount;

await LogAsync($"Starting {parallelism} parallel fuzzer instances");

using CancellationTokenSource failureCts = new();

int failureStackUploaded = 0;

await Parallel.ForEachAsync(Enumerable.Range(1, parallelism), async (i, _) =>
Expand Down Expand Up @@ -173,7 +186,7 @@ await RunProcessAsync(

if (Directory.EnumerateFiles(inputsDirectory).Any())
{
await ZipAndUploadArtifactAsync($"{fuzzerName}-inputs", inputsDirectory);
await ZipAndUploadArtifactAsync(inputsDirectory, inputsDirectory);
}

return failureStackUploaded == 0;
Expand Down
42 changes: 34 additions & 8 deletions Runner/JobBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Runtime.InteropServices;
using System.Threading.Channels;
using System.IO.Compression;
using Azure.Storage.Blobs;

namespace Runner;

Expand Down Expand Up @@ -56,6 +57,8 @@ private bool TryGetArgument(string argument, [NotNullWhen(true)] out string? val
return value.Length > 0;
}

protected BlobContainerClient PersistentStateClient => new(new Uri(Metadata["PersistentStateSasUri"]));

public JobBase(HttpClient client, Dictionary<string, string> metadata)
{
_client = client;
Expand Down Expand Up @@ -197,6 +200,12 @@ private async Task ReadChannelAsync()
catch { }
});

try
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.AboveNormal;
}
catch { }

try
{
ChannelReader<string> reader = _channel.Reader;
Expand Down Expand Up @@ -251,6 +260,12 @@ protected async Task RunProcessAsync(

process.Start();

try
{
process.PriorityClass = ProcessPriorityClass.BelowNormal;
}
catch { }

await Task.WhenAll(
Task.Run(() => ReadOutputStreamAsync(process.StandardOutput)),
Task.Run(() => ReadOutputStreamAsync(process.StandardError)),
Expand Down Expand Up @@ -319,16 +334,27 @@ protected async Task UploadArtifactAsync(string path, string? fileName = null)
JobTimeout);
}

private async Task PostAsJsonAsync(string path, object? value)
private async Task PostAsJsonAsync(string path, object? value, int attemptsRemaining = 2)
{
try
{
using var response = await _client.PostAsJsonAsync($"{path}/{_jobId}", value, JobTimeout);
}
catch (Exception ex)
while (true)
{
await LogAsync($"Failed to post resource '{path}': {ex}");
throw;
try
{
using var response = await _client.PostAsJsonAsync($"{path}/{_jobId}", value, JobTimeout);
response.EnsureSuccessStatusCode();
return;
}
catch (Exception ex) when (!JobTimeout.IsCancellationRequested)
{
await LogAsync($"Failed to post resource '{path}': {ex}");

if (--attemptsRemaining == 0)
{
throw;
}

await Task.Delay(1_000, JobTimeout);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions Runner/Runner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
<PackageReference Include="Hardware.Info" Version="100.1.0" />
</ItemGroup>

Expand Down

0 comments on commit 91e22a7

Please sign in to comment.