using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using GitHub.Actions.RunService.WebApi; using GitHub.DistributedTask.Pipelines; using GitHub.DistributedTask.WebApi; using GitHub.Runner.Common.Util; using GitHub.Runner.Sdk; using GitHub.Services.Common; using Sdk.RSWebApi.Contracts; using Sdk.WebApi.WebApi.RawClient; namespace GitHub.Runner.Common { [ServiceLocator(Default = typeof(RunServer))] public interface IRunServer : IRunnerService { Task ConnectAsync(Uri serverUrl, VssCredentials credentials); Task GetJobMessageAsync(string id, CancellationToken token); Task CompleteJobAsync( Guid planId, Guid jobId, TaskResult result, Dictionary outputs, IList stepResults, IList jobAnnotations, string environmentUrl, CancellationToken token); Task RenewJobAsync(Guid planId, Guid jobId, CancellationToken token); } public sealed class RunServer : RunnerService, IRunServer { private bool _hasConnection; private Uri requestUri; private RawConnection _connection; private RunServiceHttpClient _runServiceHttpClient; public async Task ConnectAsync(Uri serverUri, VssCredentials credentials) { requestUri = serverUri; _connection = VssUtil.CreateRawConnection(serverUri, credentials); _runServiceHttpClient = await _connection.GetClientAsync(); _hasConnection = true; } private void CheckConnection() { if (!_hasConnection) { throw new InvalidOperationException($"SetConnection"); } } public Task GetJobMessageAsync(string id, CancellationToken cancellationToken) { CheckConnection(); return RetryRequest( async () => await _runServiceHttpClient.GetJobMessageAsync(requestUri, id, VarUtil.OS, cancellationToken), cancellationToken, shouldRetry: ex => ex is not TaskOrchestrationJobAlreadyAcquiredException); } public Task CompleteJobAsync( Guid planId, Guid jobId, TaskResult result, Dictionary outputs, IList stepResults, IList jobAnnotations, string environmentUrl, CancellationToken cancellationToken) { CheckConnection(); return RetryRequest( async () => await _runServiceHttpClient.CompleteJobAsync(requestUri, planId, jobId, result, outputs, stepResults, jobAnnotations, environmentUrl, cancellationToken), cancellationToken); } public Task RenewJobAsync(Guid planId, Guid jobId, CancellationToken cancellationToken) { CheckConnection(); return RetryRequest( async () => await _runServiceHttpClient.RenewJobAsync(requestUri, planId, jobId, cancellationToken), cancellationToken); } } }