Skip to content

Commit

Permalink
Add retries to client create and GetPipelineCacheArtifactAsync (#3539)
Browse files Browse the repository at this point in the history
  • Loading branch information
carl-tanner authored Sep 22, 2021
1 parent 0299fb6 commit d9928d9
Showing 1 changed file with 33 additions and 5 deletions.
38 changes: 33 additions & 5 deletions src/Agent.Plugins/PipelineCache/PipelineCacheServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal async Task UploadAsync(
VssConnection connection = context.VssConnection;
var (dedupManifestClient, clientTelemetry) = await DedupManifestArtifactClientFactory.Instance
.CreateDedupManifestClientAsync(context.IsSystemDebugTrue(), (str) => context.Output(str), connection, cancellationToken);
PipelineCacheClient pipelineCacheClient = this.CreateClient(clientTelemetry, context, connection);
PipelineCacheClient pipelineCacheClient = await this.CreateClientWithRetryAsync(clientTelemetry, context, connection, cancellationToken);

using (clientTelemetry)
{
Expand Down Expand Up @@ -122,13 +122,23 @@ internal async Task DownloadAsync(
VssConnection connection = context.VssConnection;
var (dedupManifestClient, clientTelemetry) = await DedupManifestArtifactClientFactory.Instance
.CreateDedupManifestClientAsync(context.IsSystemDebugTrue(), (str) => context.Output(str), connection, cancellationToken);
PipelineCacheClient pipelineCacheClient = this.CreateClient(clientTelemetry, context, connection);
PipelineCacheClient pipelineCacheClient = await this.CreateClientWithRetryAsync(clientTelemetry, context, connection, cancellationToken);

using (clientTelemetry)
{
PipelineCacheActionRecord cacheRecord = clientTelemetry.CreateRecord<PipelineCacheActionRecord>((level, uri, type) =>
new PipelineCacheActionRecord(level, uri, type, PipelineArtifactConstants.RestoreCache, context));
PipelineCacheArtifact result = await pipelineCacheClient.GetPipelineCacheArtifactAsync(fingerprints, cancellationToken, cacheRecord);

PipelineCacheArtifact result = await AsyncHttpRetryHelper.InvokeAsync(
async () =>
{
return await pipelineCacheClient.GetPipelineCacheArtifactAsync(fingerprints, cancellationToken, cacheRecord);
},
maxRetries: 3,
tracer: tracer,
canRetryDelegate: e => true, // this isn't great, but failing on upload stinks, so just try a couple of times
cancellationToken: cancellationToken,
continueOnCapturedContext: false);

// Send results to CustomerIntelligence
context.PublishTelemetry(area: PipelineArtifactConstants.AzurePipelinesAgent, feature: PipelineArtifactConstants.PipelineCache, record: cacheRecord);
Expand Down Expand Up @@ -181,14 +191,32 @@ await clientTelemetry.MeasureActionAsync(
}
}

private PipelineCacheClient CreateClient(

private Task<PipelineCacheClient> CreateClientWithRetryAsync(
BlobStoreClientTelemetry blobStoreClientTelemetry,
AgentTaskPluginExecutionContext context,
VssConnection connection,
CancellationToken cancellationToken)
{
// this uses location service so needs http retries.
return AsyncHttpRetryHelper.InvokeAsync(
async () => await this.CreateClientAsync(blobStoreClientTelemetry, context, connection),
maxRetries: 3,
tracer: tracer,
canRetryDelegate: e => true, // this isn't great, but failing on upload stinks, so just try a couple of times
cancellationToken: cancellationToken,
continueOnCapturedContext: false);
}

private async Task<PipelineCacheClient> CreateClientAsync(
BlobStoreClientTelemetry blobStoreClientTelemetry,
AgentTaskPluginExecutionContext context,
VssConnection connection)
{

var tracer = context.CreateArtifactsTracer();
IClock clock = UtcClock.Instance;
var pipelineCacheHttpClient = connection.GetClient<PipelineCacheHttpClient>();
var pipelineCacheHttpClient = await connection.GetClientAsync<PipelineCacheHttpClient>();
var pipelineCacheClient = new PipelineCacheClient(blobStoreClientTelemetry, pipelineCacheHttpClient, clock, tracer);

return pipelineCacheClient;
Expand Down

0 comments on commit d9928d9

Please sign in to comment.