private static void AutoRenewLeaseOnBlob(AzureBlobLease instance, Microsoft.Build.Utilities.TaskLoggingHelper log) { TimeSpan maxWait = TimeSpan.FromSeconds(s_MaxWaitDefault); TimeSpan delay = TimeSpan.FromMilliseconds(s_DelayDefault); TimeSpan waitFor = maxWait; CancellationToken token = instance._cancellationTokenSource.Token; while (true) { token.ThrowIfCancellationRequested(); try { log.LogMessage(MessageImportance.Low, $"Requesting lease for container/blob '{instance._containerName}/{instance._blobName}'."); using (HttpClient client = new HttpClient()) { Tuple <string, string> leaseAction = new Tuple <string, string>("x-ms-lease-action", "renew"); Tuple <string, string> headerLeaseId = new Tuple <string, string>("x-ms-lease-id", instance._leaseId); List <Tuple <string, string> > additionalHeaders = new List <Tuple <string, string> >() { leaseAction, headerLeaseId }; var request = AzureHelper.RequestMessage("PUT", instance._leaseUrl, instance._accountName, instance._accountKey, additionalHeaders); using (HttpResponseMessage response = AzureHelper.RequestWithRetry(log, client, request).GetAwaiter().GetResult()) { if (!response.IsSuccessStatusCode) { throw new Exception("Unable to acquire lease."); } } } waitFor = maxWait; } catch (Exception e) { Console.WriteLine($"Rerying lease renewal on {instance._containerName}, {e.Message}"); waitFor = delay; } token.ThrowIfCancellationRequested(); Task.Delay(waitFor, token).Wait(); } }
public override bool Execute() { ParseConnectionString(); if (Log.HasLoggedErrors) { return(false); } string sourceDir = $"{Product}/{ProductVersion}/"; string channelDir = $"{Product}/{Channel}/"; string semaphoreBlob = $"{channelDir}publishSemaphore"; CreateBlobIfNotExists(semaphoreBlob); AzureBlobLease blobLease = new AzureBlobLease( AccountName, AccountKey, ConnectionString, ContainerName, semaphoreBlob, Log); Log.LogMessage($"Acquiring lease on semaphore blob '{semaphoreBlob}'"); blobLease.Acquire(); try { if (EnableVersionHint) { string targetVersionFile = $"{channelDir}{ProductVersion}"; // Check if this build is already finalized. if (IsLatestSpecifiedVersion(targetVersionFile)) { Log.LogMessage( MessageImportance.High, $"Version '{ProductVersion}' is already published. " + $"Skipping finalization. Hint file: '{targetVersionFile}'"); return(true); } // Delete old version files. GetBlobList(channelDir) .Select(s => s.Replace($"/{ContainerName}/", "")) .Where(w => VersionRegex.Replace(Path.GetFileName(w), "") == "") .ToList() .ForEach(f => TryDeleteBlob(f)); // Drop the version file signaling such for any race-condition builds. CreateBlobIfNotExists(targetVersionFile); } CopyBlobs(sourceDir, channelDir); // Generate the latest version text file string versionText = $"{Commit}{Environment.NewLine}" + $"{ProductVersion}{Environment.NewLine}"; if (LatestVersionFilenames?.Any() != true) { LatestVersionFilenames = DefaultLatestVersionFilenames; } foreach (string latestFilename in LatestVersionFilenames) { PublishStringToBlob( ContainerName, $"{channelDir}{latestFilename}", versionText, "text/plain"); } } finally { Log.LogMessage($"Releasing lease on semaphore blob '{semaphoreBlob}'"); blobLease.Release(); } return(!Log.HasLoggedErrors); }