/// <summary> /// Attempts to acquire a lease based on the provided lease policy. /// </summary> /// <param name="leasePolicy">The configuration details for the lease.</param> /// <param name="leaseId">The id of the currently acquired lease.</param> /// <returns>A task for the async operation.</returns> public async Task <string> AcquireAsync(ILeasePolicy leasePolicy, string leaseId) { this.LeasePolicy = leasePolicy; await this.InitialiseAsync(); if (!this.blob.Exists()) { await Retriable.RetryAsync(async() => { using (var ms = new MemoryStream()) { await this.blob.UploadFromStreamAsync(ms); } }); } try { return(await Retriable.RetryAsync( () => this.blob.AcquireLeaseAsync(leasePolicy.Duration, leaseId), new CancellationToken(), new Count(10), new DoNotRetryOnConflictPolicy())); } catch (StorageException exception) { if (exception.RequestInformation.HttpStatusCode == 409) { throw new LeaseAcquisitionUnsuccessfulException(this.LeasePolicy, exception); } throw; } }
/// <summary> /// Attempts to extend the lease based on the lease policy provided to initially acquire it. /// </summary> /// <param name="leaseId">The id of the lease to attempt to extend.</param> /// <remarks>A valid lease and lease policy must exist for this operation to execute. An InvalidOperationException will be thrown otherwise.</remarks> /// <returns>A task for the async operation.</returns> public async Task ExtendAsync(string leaseId) { await this.InitialiseAsync(); await Retriable.RetryAsync(() => this.blob.RenewLeaseAsync(new AccessCondition { LeaseId = leaseId })); }
public async Task ThenAfterSecondsAtMostThereShouldBeAWorkflowInstanceWithTheIdInTheWorkflowInstanceStore(string instanceId, int maximumWaitTime) { var tokenSource = new CancellationTokenSource(); tokenSource.CancelAfter(TimeSpan.FromSeconds(maximumWaitTime)); await Retriable.RetryAsync( () => this.GetWorkflowInstance(instanceId, false), tokenSource.Token, new Linear(TimeSpan.FromSeconds(1), int.MaxValue), new AnyExceptionPolicy(), false).ConfigureAwait(false); }
private async Task InitialiseAsync() { if (!this.isInitialised) { var storageAccount = CloudStorageAccount.Parse(Configuration.GetSettingFor(this.connectionStringProvider.ConnectionStringKey)); var client = storageAccount.CreateCloudBlobClient(); var container = client.GetContainerReference("endjin-leasing-leases"); await Retriable.RetryAsync(container.CreateIfNotExistsAsync); this.blob = container.GetBlockBlobReference(this.LeasePolicy.Name.ToLowerInvariant()); this.isInitialised = true; } }
private async Task PublishWithRetryAsync <T>(string source, string subject, T cloudEvent, WorkflowEventSubscription destination) { try { await Retriable.RetryAsync(() => this.PublishAsync(source, subject, cloudEvent, destination)).ConfigureAwait(false); } catch (Exception ex) { // In this "v1" solution to event publishing, we don't want exceptions to propagate outside the // publisher because we don't want failure in event publishing to break anything. this.logger.LogError( ex, "Unexpected exception when trying to a CloudEvent with source '{source}', '{subject}' and destinationUrl '{destinationUrl}' with authentication resource '{msiAuthenticationResource}'.", source, subject, destination?.ExternalUrl, destination?.MsiAuthenticationResource); } }