| File: Tasks\OneDeploy\OneDeployStatusService.cs | Web Access |
| Project: src\sdk\src\WebSdk\Publish\Tasks\Microsoft.NET.Sdk.Publish.Tasks.csproj (Microsoft.NET.Sdk.Publish.Tasks) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Http; using Microsoft.NET.Sdk.Publish.Tasks.Properties; namespace Microsoft.NET.Sdk.Publish.Tasks.OneDeploy; internal class OneDeployStatusService(ITaskLogger? taskLogger = null) : IDeploymentStatusService<DeploymentResponse> { private static readonly TimeSpan s_maximumWaitForResult = TimeSpan.FromMinutes(3); private static readonly TimeSpan s_refreshDelay = TimeSpan.FromSeconds(3); private static readonly TimeSpan s_retryDelay = TimeSpan.FromSeconds(1); private static readonly int s_retryCount = 3; private readonly ITaskLogger? _taskLogger = taskLogger; /// <inheritdoc/> public async Task<DeploymentResponse?> PollDeploymentAsync( IHttpClient httpClient, string? url, string? user, string? password, string userAgent, CancellationToken cancellationToken) { _taskLogger?.LogMessage(Resources.DeploymentStatus_Polling); if (httpClient is null || cancellationToken.IsCancellationRequested) { return DeploymentResponse.s_unknownResponse; } if (!Uri.TryCreate(url, UriKind.Absolute, out var _)) { _taskLogger?.LogError(string.Format(Resources.DeploymentStatus_InvalidPollingUrl, url)); return DeploymentResponse.s_unknownResponse; } var maxWaitForResultTokenSource = new CancellationTokenSource(s_maximumWaitForResult); var retryTokenSource = CancellationTokenSource.CreateLinkedTokenSource(maxWaitForResultTokenSource.Token, cancellationToken); var retryToken = retryTokenSource.Token; DeploymentResponse? deploymentResponse = null; DeploymentStatus deployStatus = DeploymentStatus.Pending; try { retryTokenSource.CancelAfter(s_maximumWaitForResult); while (!retryToken.IsCancellationRequested && !deployStatus.IsTerminatingStatus()) { deploymentResponse = await httpClient.RetryGetRequestAsync<DeploymentResponse>( url, user, password, userAgent, s_retryCount, s_retryDelay, retryToken); // set to 'Unknown' if no response is returned deploymentResponse ??= DeploymentResponse.s_unknownResponse; deployStatus = deploymentResponse is not null && deploymentResponse.Status is not null ? deploymentResponse.Status.Value : DeploymentStatus.Unknown; if (deploymentResponse is not null) { _taskLogger?.LogMessage(deploymentResponse.ToString()); } await System.Threading.Tasks.Task.Delay(s_refreshDelay, retryToken); } } catch (Exception ex) { if (ex is TaskCanceledException) { // 'maxWaitTimeForResult' has passed; no 'terminating' status was obtained } else if (ex is HttpRequestException) { // HTTP GET request threw; return last known response return deploymentResponse; } } return deploymentResponse ?? DeploymentResponse.s_unknownResponse; } }