diff --git a/src/Runner.Common/RunServer.cs b/src/Runner.Common/RunServer.cs index 4f344c0b0..3cc53f3d8 100644 --- a/src/Runner.Common/RunServer.cs +++ b/src/Runner.Common/RunServer.cs @@ -52,7 +52,8 @@ namespace GitHub.Runner.Common { CheckConnection(); return RetryRequest( - async () => await _runServiceHttpClient.GetJobMessageAsync(requestUri, id, cancellationToken), cancellationToken); + async () => await _runServiceHttpClient.GetJobMessageAsync(requestUri, id, cancellationToken), cancellationToken, + shouldRetry: ex => ex is not TaskOrchestrationJobAlreadyAcquiredException); } public Task CompleteJobAsync(Guid planId, Guid jobId, TaskResult result, Dictionary outputs, IList stepResults, CancellationToken cancellationToken) diff --git a/src/Runner.Common/RunnerService.cs b/src/Runner.Common/RunnerService.cs index a0cb96a0e..4694af1ce 100644 --- a/src/Runner.Common/RunnerService.cs +++ b/src/Runner.Common/RunnerService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using System.Threading.Tasks; using GitHub.Runner.Sdk; @@ -80,10 +80,11 @@ namespace GitHub.Runner.Common } await RetryRequest(wrappedFunc, cancellationToken, maxRetryAttemptsCount); } - + protected async Task RetryRequest(Func> func, CancellationToken cancellationToken, - int maxRetryAttemptsCount = 5 + int maxRetryAttemptsCount = 5, + Func shouldRetry = null ) { var retryCount = 0; @@ -96,7 +97,7 @@ namespace GitHub.Runner.Common return await func(); } // TODO: Add handling of non-retriable exceptions: https://github.com/github/actions-broker/issues/122 - catch (Exception ex) when (retryCount < maxRetryAttemptsCount) + catch (Exception ex) when (retryCount < maxRetryAttemptsCount && (shouldRetry == null || shouldRetry(ex))) { Trace.Error("Catch exception during request"); Trace.Error(ex); diff --git a/src/Runner.Listener/Runner.cs b/src/Runner.Listener/Runner.cs index 865c596a9..e71ba9cb5 100644 --- a/src/Runner.Listener/Runner.cs +++ b/src/Runner.Listener/Runner.cs @@ -549,7 +549,17 @@ namespace GitHub.Runner.Listener { var runServer = HostContext.CreateService(); await runServer.ConnectAsync(new Uri(messageRef.RunServiceUrl), creds); - jobRequestMessage = await runServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token); + try + { + jobRequestMessage = + await runServer.GetJobMessageAsync(messageRef.RunnerRequestId, + messageQueueLoopTokenSource.Token); + } + catch (TaskOrchestrationJobAlreadyAcquiredException) + { + Trace.Info("Job is already acquired, skip this message."); + continue; + } } jobDispatcher.Run(jobRequestMessage, runOnce); diff --git a/src/Sdk/DTWebApi/WebApi/Exceptions.cs b/src/Sdk/DTWebApi/WebApi/Exceptions.cs index 3690bbe6b..aed702b7e 100644 --- a/src/Sdk/DTWebApi/WebApi/Exceptions.cs +++ b/src/Sdk/DTWebApi/WebApi/Exceptions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.Serialization; using GitHub.Services.Common; @@ -1519,6 +1519,26 @@ namespace GitHub.DistributedTask.WebApi } } + [Serializable] + [ExceptionMapping("0.0", "3.0", "TaskOrchestrationJobAlreadyAcquiredException", "GitHub.DistributedTask.WebApi.TaskOrchestrationJobAlreadyAcquiredException, GitHub.DistributedTask.WebApi, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] + public sealed class TaskOrchestrationJobAlreadyAcquiredException : DistributedTaskException + { + public TaskOrchestrationJobAlreadyAcquiredException(String message) + : base(message) + { + } + + public TaskOrchestrationJobAlreadyAcquiredException(String message, Exception innerException) + : base(message, innerException) + { + } + + private TaskOrchestrationJobAlreadyAcquiredException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } + [Serializable] [ExceptionMapping("0.0", "3.0", "TaskOrchestrationPlanSecurityException", "GitHub.DistributedTask.WebApi.TaskOrchestrationPlanSecurityException, GitHub.DistributedTask.WebApi, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public sealed class TaskOrchestrationPlanSecurityException : DistributedTaskException diff --git a/src/Sdk/RSWebApi/RunServiceHttpClient.cs b/src/Sdk/RSWebApi/RunServiceHttpClient.cs index 65259c5ba..8ddd1672b 100644 --- a/src/Sdk/RSWebApi/RunServiceHttpClient.cs +++ b/src/Sdk/RSWebApi/RunServiceHttpClient.cs @@ -86,6 +86,8 @@ namespace GitHub.Actions.RunService.WebApi { case HttpStatusCode.NotFound: throw new TaskOrchestrationJobNotFoundException($"Job message not found: {messageId}"); + case HttpStatusCode.Conflict: + throw new TaskOrchestrationJobAlreadyAcquiredException($"Job message already acquired: {messageId}"); default: throw new Exception($"Failed to get job message: {result.Error}"); }