/// <summary> /// The <see cref="Acquire"/> operation acquires a lease on /// the path or file system. The lease <paramref name="duration"/> must /// be between 15 to 60 seconds, or infinite (-1). /// /// If the file system does not have an active lease, the Data Lake service /// creates a lease on the path or file system and returns it. If the /// file system has an active lease, you can only request a new lease /// using the active lease ID as <see cref="LeaseId"/>, but you can /// specify a new <paramref name="duration"/>. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="duration"> /// Specifies the duration of the lease, in seconds, or specify /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires. /// A non-infinite lease can be between 15 and 60 seconds. /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on acquiring a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual Response <DataLakeLease> Acquire( TimeSpan duration, RequestConditions conditions = default, CancellationToken cancellationToken = default) { DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(Azure)}.{nameof(Storage)}.{nameof(Files)}.{nameof(DataLake)}.{nameof(DataLakeLeaseClient)}.{nameof(Acquire)}"); try { scope.Start(); Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Acquire( duration, conditions, cancellationToken); return(Response.FromValue( response.Value.ToDataLakeLease(), response.GetRawResponse())); } catch (Exception ex) { scope.Failed(ex); throw; } finally { scope.Dispose(); } }
/// <summary> /// The <see cref="ReleaseAsync"/> operation releases the /// file system or path's previously-acquired lease. /// /// The lease may be released if the <see cref="LeaseId"/> /// matches that associated with the file system or path. Releasing the /// lease allows another client to immediately acquire the lease for the /// file system or path as soon as the release is complete. /// /// For more information, see /// <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container"> /// Lease Container</see>. /// </summary> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on acquiring a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{ReleasedObjectInfo}"/> describing the /// updated path or file system. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <ReleasedObjectInfo> > ReleaseAsync( RequestConditions conditions = default, CancellationToken cancellationToken = default) { DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(DataLakeLeaseClient)}.{nameof(Release)}"); try { scope.Start(); Response <Blobs.Models.ReleasedObjectInfo> response = await _blobLeaseClient.ReleaseAsync( conditions, cancellationToken) .ConfigureAwait(false); return(Response.FromValue( new ReleasedObjectInfo(response.Value.ETag, response.Value.LastModified), response.GetRawResponse())); } catch (Exception ex) { scope.Failed(ex); throw; } finally { scope.Dispose(); } }
/// <summary> /// The <see cref="Change"/> operation changes the lease /// of an active lease. A change must include the current /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>. /// /// For more information, see /// <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container"> /// Lease Container</see>. /// </summary> /// <param name="proposedId"> /// An optional proposed lease ID, in a GUID string format. A /// <see cref="RequestFailedException"/> will be thrown if the /// proposed lease ID is not in the correct format. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on acquiring a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual Response <DataLakeLease> Change( string proposedId, RequestConditions conditions = default, CancellationToken cancellationToken = default) { DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(DataLakeLeaseClient)}.{nameof(Change)}"); try { scope.Start(); Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Change( proposedId, conditions, cancellationToken); return(Response.FromValue( response.Value.ToDataLakeLease(), response.GetRawResponse())); } catch (Exception ex) { scope.Failed(ex); throw; } finally { scope.Dispose(); } }
/// <summary> /// The <see cref="BreakAsync"/> operation breaks the path or /// file system's previously-acquired lease (if it exists). /// /// Once a lease is broken, it cannot be renewed. Any authorized /// request can break the lease; the request is not required to /// specify a matching lease ID. When a lease is broken, the lease /// break <paramref name="breakPeriod"/> is allowed to elapse, /// during which time no lease operation except /// <see cref="BreakAsync"/> and <see cref="ReleaseAsync"/> can be /// performed on the path or file system. When a lease is successfully /// broken, the response indicates the interval in seconds until a new /// lease can be acquired. /// /// A lease that has been broken can also be released. A client can /// immediately acquire a path or file system lease that has been /// released. /// /// For more information, see /// <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container"> /// Lease Container</see>. /// </summary> /// <param name="breakPeriod"> /// Specifies the proposed duration the lease should continue before /// it is broken, in seconds, between 0 and 60. This break period is /// only used if it is shorter than the time remaining on the lease. /// If longer, the time remaining on the lease is used. A new lease /// will not be available before the break period has expired, but the /// lease may be held for longer than the break period. If this value /// is not provided, a fixed-duration lease breaks after the remaining /// lease period elapses, and an infinite lease breaks immediately. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on acquiring a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the broken lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <DataLakeLease> > BreakAsync( TimeSpan?breakPeriod = default, RequestConditions conditions = default, CancellationToken cancellationToken = default) { DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(DataLakeLeaseClient)}.{nameof(Break)}"); try { scope.Start(); Response <Blobs.Models.BlobLease> response = await _blobLeaseClient.BreakAsync( breakPeriod, conditions, cancellationToken).ConfigureAwait(false); return(Response.FromValue( response.Value.ToDataLakeLease(), response.GetRawResponse())); } catch (Exception ex) { scope.Failed(ex); throw; } finally { scope.Dispose(); } }
/// <summary> /// The <see cref="Release"/> operation releases the /// container or blob's previously-acquired lease. /// /// The lease may be released if the <see cref="LeaseId"/> /// matches that associated with the container or blob. Releasing the /// lease allows another client to immediately acquire the lease for the /// container or blob as soon as the release is complete. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on releasing a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{ReleaseObjectLeaseInfo}"/> describing the /// updated blob or container. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual Response <ReleasedObjectInfo> Release( RequestConditions conditions = default, CancellationToken cancellationToken = default) => ReleaseInternal( conditions, false, // async cancellationToken) .EnsureCompleted();
/// <summary> /// The <see cref="ReleaseAsync"/> operation releases the /// container or blob's previously-acquired lease. /// /// The lease may be released if the <see cref="LeaseId"/> /// matches that associated with the container or blob. Releasing the /// lease allows another client to immediately acquire the lease for the /// container or blob as soon as the release is complete. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on releasing a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{ReleasedObjectInfo}"/> describing the /// updated blob or container. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <ReleasedObjectInfo> > ReleaseAsync( RequestConditions conditions = default, CancellationToken cancellationToken = default) => await ReleaseInternal( conditions, true, // async cancellationToken) .ConfigureAwait(false);
/// <summary> /// The <see cref="RenewAsync"/> operation renews the blob or /// container's previously-acquired lease. /// /// The lease can be renewed if the leaseId /// matches that associated with the blob or container. Note that the] /// lease may be renewed even if it has expired as long as the blob or /// container has not been leased again since the expiration of that /// lease. When you renew a lease, the lease duration clock resets. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on renewing a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <BlobLease> > RenewAsync( RequestConditions conditions = default, CancellationToken cancellationToken = default) => await RenewInternal( conditions, true, // async cancellationToken) .ConfigureAwait(false);
/// <summary> /// The <see cref="Renew"/> operation renews the blob or /// container's previously-acquired lease. /// /// The lease can be renewed if the leaseId /// matches that associated with the blob or container. Note that the] /// lease may be renewed even if it has expired as long as the blob or /// container has not been leased again since the expiration of that /// lease. When you renew a lease, the lease duration clock resets. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on renewing a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual Response <BlobLease> Renew( RequestConditions conditions = default, CancellationToken cancellationToken = default) => RenewInternal( conditions, false, // async cancellationToken) .EnsureCompleted();
/// <summary> /// Convert a base RequestConditions to BlobRequestConditions. /// </summary> /// <param name="conditions">The <see cref="RequestConditions"/>.</param> /// <returns>The <see cref="BlobRequestConditions"/>.</returns> public static BlobRequestConditions ToBlobRequestConditions(this RequestConditions conditions) => conditions == null ? null : new BlobRequestConditions { IfMatch = conditions.IfMatch, IfNoneMatch = conditions.IfNoneMatch, IfModifiedSince = conditions.IfModifiedSince, IfUnmodifiedSince = conditions.IfUnmodifiedSince };
/// <summary> /// The <see cref="ChangeAsync"/> operation changes the lease /// of an active lease. A change must include the current /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="proposedId"> /// An optional proposed lease ID, in a GUID string format. A /// <see cref="RequestFailedException"/> will be thrown if the /// proposed lease ID is not in the correct format. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on changing a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <BlobLease> > ChangeAsync( string proposedId, RequestConditions conditions = default, CancellationToken cancellationToken = default) => await ChangeInternal( proposedId, conditions, true, // async cancellationToken) .ConfigureAwait(false);
/// <summary> /// The <see cref="Break"/> operation breaks the blob or /// container's previously-acquired lease (if it exists). /// /// Once a lease is broken, it cannot be renewed. Any authorized /// request can break the lease; the request is not required to /// specify a matching lease ID. When a lease is broken, the lease /// break <paramref name="breakPeriod"/> is allowed to elapse, /// during which time no lease operation except /// <see cref="Break"/> and <see cref="Release"/> can be /// performed on the blob or container. When a lease is successfully /// broken, the response indicates the interval in seconds until a new /// lease can be acquired. /// /// A lease that has been broken can also be released. A client can /// immediately acquire a blob or container lease that has been /// released. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="breakPeriod"> /// Specifies the proposed duration the lease should continue before /// it is broken, in seconds, between 0 and 60. This break period is /// only used if it is shorter than the time remaining on the lease. /// If longer, the time remaining on the lease is used. A new lease /// will not be available before the break period has expired, but the /// lease may be held for longer than the break period. If this value /// is not provided, a fixed-duration lease breaks after the remaining /// lease period elapses, and an infinite lease breaks immediately. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on breaking a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the broken lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual Response <BlobLease> Break( TimeSpan?breakPeriod = default, RequestConditions conditions = default, CancellationToken cancellationToken = default) => BreakInternal( breakPeriod, conditions, false, // async cancellationToken) .EnsureCompleted();
/// <summary> /// The <see cref="BreakAsync"/> operation breaks the blob or /// container's previously-acquired lease (if it exists). /// /// Once a lease is broken, it cannot be renewed. Any authorized /// request can break the lease; the request is not required to /// specify a matching lease ID. When a lease is broken, the lease /// break <paramref name="breakPeriod"/> is allowed to elapse, /// during which time no lease operation except /// <see cref="BreakAsync"/> and <see cref="ReleaseAsync"/> can be /// performed on the blob or container. When a lease is successfully /// broken, the response indicates the interval in seconds until a new /// lease can be acquired. /// /// A lease that has been broken can also be released. A client can /// immediately acquire a blob or container lease that has been /// released. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="breakPeriod"> /// Specifies the proposed duration the lease should continue before /// it is broken, in seconds, between 0 and 60. This break period is /// only used if it is shorter than the time remaining on the lease. /// If longer, the time remaining on the lease is used. A new lease /// will not be available before the break period has expired, but the /// lease may be held for longer than the break period. If this value /// is not provided, a fixed-duration lease breaks after the remaining /// lease period elapses, and an infinite lease breaks immediately. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on breaking a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the broken lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <BlobLease> > BreakAsync( TimeSpan?breakPeriod = default, RequestConditions conditions = default, CancellationToken cancellationToken = default) => await BreakInternal( breakPeriod, conditions, true, // async cancellationToken) .ConfigureAwait(false);
/// <summary> /// The <see cref="AcquireAsync"/> operation acquires a lease on /// the blob or container. The lease <paramref name="duration"/> must /// be between 15 to 60 seconds, or infinite (-1). /// /// If the container does not have an active lease, the Blob service /// creates a lease on the blob or container and returns it. If the /// container has an active lease, you can only request a new lease /// using the active lease ID as <see cref="LeaseId"/>, but you can /// specify a new <paramref name="duration"/>. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="duration"> /// Specifies the duration of the lease, in seconds, or specify /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires. /// A non-infinite lease can be between 15 and 60 seconds. /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on acquiring a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <BlobLease> > AcquireAsync( TimeSpan duration, RequestConditions conditions = default, CancellationToken cancellationToken = default) => await AcquireInternal( duration, conditions, true, // async cancellationToken) .ConfigureAwait(false);
/// <summary> /// The <see cref="Acquire"/> operation acquires a lease on /// the blob or container. The lease <paramref name="duration"/> must /// be between 15 to 60 seconds, or infinite (-1). /// /// If the container does not have an active lease, the Blob service /// creates a lease on the blob or container and returns it. If the /// container has an active lease, you can only request a new lease /// using the active lease ID as <see cref="LeaseId"/>, but you can /// specify a new <paramref name="duration"/>. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="duration"> /// Specifies the duration of the lease, in seconds, or specify /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires. /// A non-infinite lease can be between 15 and 60 seconds. /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on acquiring a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual Response <BlobLease> Acquire( TimeSpan duration, RequestConditions conditions = default, CancellationToken cancellationToken = default) => AcquireInternal( duration, conditions, false, // async cancellationToken) .EnsureCompleted();
/// <summary> /// The <see cref="Change"/> operation changes the lease /// of an active lease. A change must include the current /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="proposedId"> /// An optional proposed lease ID, in a GUID string format. A /// <see cref="RequestFailedException"/> will be thrown if the /// proposed lease ID is not in the correct format. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on changing a lease. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual Response <BlobLease> Change( string proposedId, RequestConditions conditions = default, CancellationToken cancellationToken = default) => ChangeInternal( proposedId, conditions, false, // async cancellationToken) .EnsureCompleted();
public virtual Response <DataLakeLease> Renew( RequestConditions conditions = default, CancellationToken cancellationToken = default) { Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Renew( conditions, cancellationToken); return(Response.FromValue( response.Value.ToDataLakeLease(), response.GetRawResponse())); }
public virtual Response <ReleasedObjectInfo> Release( RequestConditions conditions = default, CancellationToken cancellationToken = default) { Response <Blobs.Models.ReleasedObjectInfo> response = _blobLeaseClient.Release( conditions, cancellationToken); return(Response.FromValue( new ReleasedObjectInfo(response.Value.ETag, response.Value.LastModified), response.GetRawResponse())); }
public virtual async Task <Response <DataLakeLease> > RenewAsync( RequestConditions conditions = default, CancellationToken cancellationToken = default) { Response <Blobs.Models.BlobLease> response = await _blobLeaseClient.RenewAsync( conditions, cancellationToken) .ConfigureAwait(false); return(Response.FromValue( response.Value.ToDataLakeLease(), response.GetRawResponse())); }
public virtual async Task <Response <ReleasedObjectInfo> > ReleaseAsync( RequestConditions conditions = default, CancellationToken cancellationToken = default) { Response <Blobs.Models.ReleasedObjectInfo> response = await _blobLeaseClient.ReleaseAsync( conditions, cancellationToken) .ConfigureAwait(false); return(Response.FromValue( new ReleasedObjectInfo(response.Value.ETag, response.Value.LastModified), response.GetRawResponse())); }
public virtual Response <DataLakeLease> Change( string proposedId, RequestConditions conditions = default, CancellationToken cancellationToken = default) { Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Change( proposedId, conditions, cancellationToken); return(Response.FromValue( response.Value.ToDataLakeLease(), response.GetRawResponse())); }
public virtual Response <DataLakeLease> Break( TimeSpan?breakPeriod = default, RequestConditions conditions = default, CancellationToken cancellationToken = default) { Response <Blobs.Models.BlobLease> response = _blobLeaseClient.Break( breakPeriod, conditions, cancellationToken); return(Response.FromValue( response.Value.ToDataLakeLease(), response.GetRawResponse())); }
/// <summary> /// Renew the lease, getting more time to get a work done. /// </summary> /// <param name="renewInterval">required time</param> /// <returns></returns> public async Task <bool> RenewLease(TimeSpan renewInterval) { var renewRequestOptions = new RequestConditions(); var lease = _currentLease; if (lease == null) { return(false); } try { await lease.Blob.GetBlobLeaseClient(lease.Token).RenewAsync(renewRequestOptions).ConfigureAwait(false); } catch (RequestFailedException) { return(false); } return(true); }
/// <summary> /// The <see cref="BreakInternal"/> operation breaks the blob or /// container's previously-acquired lease (if it exists). /// /// Once a lease is broken, it cannot be renewed. Any authorized /// request can break the lease; the request is not required to /// specify a matching lease ID. When a lease is broken, the lease /// break <paramref name="breakPeriod"/> is allowed to elapse, /// during which time no lease operation except /// <see cref="BreakAsync"/> and <see cref="ReleaseAsync"/> can be /// performed on the blob or container. When a lease is successfully /// broken, the response indicates the interval in seconds until a new /// lease can be acquired. /// /// A lease that has been broken can also be released. A client can /// immediately acquire a blob or container lease that has been /// released. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="breakPeriod"> /// Specifies the proposed duration the lease should continue before /// it is broken, in seconds, between 0 and 60. This break period is /// only used if it is shorter than the time remaining on the lease. /// If longer, the time remaining on the lease is used. A new lease /// will not be available before the break period has expired, but the /// lease may be held for longer than the break period. If this value /// is not provided, a fixed-duration lease breaks after the remaining /// lease period elapses, and an infinite lease breaks immediately. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on breaking a lease. /// </param> /// <param name="async"> /// Whether to invoke the operation asynchronously. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the broken lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <BlobLease> > BreakInternal( TimeSpan?breakPeriod, RequestConditions conditions, bool async, CancellationToken cancellationToken) { EnsureClient(); long?serviceBreakPeriod = breakPeriod != null?Convert.ToInt64(breakPeriod.Value.TotalSeconds) : (long?)null; using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient))) { Pipeline.LogMethodEnter( nameof(BlobLeaseClient), message: $"{nameof(Uri)}: {Uri}\n" + $"{nameof(breakPeriod)}: {breakPeriod}\n" + $"{nameof(conditions)}: {conditions}"); try { if (BlobClient != null) { return((await BlobRestClient.Blob.BreakLeaseAsync( ClientDiagnostics, Pipeline, Uri, breakPeriod: serviceBreakPeriod, ifModifiedSince: conditions?.IfModifiedSince, ifUnmodifiedSince: conditions?.IfUnmodifiedSince, ifMatch: conditions?.IfMatch, ifNoneMatch: conditions?.IfNoneMatch, async: async, operationName: Constants.Blob.Lease.BreakOperationName, cancellationToken: cancellationToken) .ConfigureAwait(false)) .ToLease()); } else { if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(conditions.IfMatch), nameof(conditions.IfNoneMatch)); } return((await BlobRestClient.Container.BreakLeaseAsync( ClientDiagnostics, Pipeline, Uri, breakPeriod: serviceBreakPeriod, ifModifiedSince: conditions?.IfModifiedSince, ifUnmodifiedSince: conditions?.IfUnmodifiedSince, async: async, operationName: Constants.Blob.Lease.BreakOperationName, cancellationToken: cancellationToken) .ConfigureAwait(false)) .ToLease()); } } catch (Exception ex) { Pipeline.LogException(ex); throw; } finally { Pipeline.LogMethodExit(nameof(BlobLeaseClient)); } } }
/// <summary> /// The <see cref="AcquireInternal"/> operation acquires a lease on /// the blob or container. The lease <paramref name="duration"/> must /// be between 15 to 60 seconds, or infinite (-1). /// /// If the container does not have an active lease, the Blob service /// creates a lease on the blob or container and returns it. If the /// container has an active lease, you can only request a new lease /// using the active lease ID as <see cref="LeaseId"/>, but you can /// specify a new <paramref name="duration"/>. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="duration"> /// Specifies the duration of the lease, in seconds, or specify /// <see cref="InfiniteLeaseDuration"/> for a lease that never expires. /// A non-infinite lease can be between 15 and 60 seconds. /// A lease duration cannot be changed using <see cref="RenewAsync"/> or <see cref="ChangeAsync"/>. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on acquiring a lease. /// </param> /// <param name="async"> /// Whether to invoke the operation asynchronously. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <BlobLease> > AcquireInternal( TimeSpan duration, RequestConditions conditions, bool async, CancellationToken cancellationToken) { EnsureClient(); // Int64 is an overflow safe cast relative to TimeSpan.MaxValue var serviceDuration = duration < TimeSpan.Zero ? Constants.Blob.Lease.InfiniteLeaseDuration : Convert.ToInt64(duration.TotalSeconds); using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient))) { Pipeline.LogMethodEnter( nameof(BlobLeaseClient), message: $"{nameof(Uri)}: {Uri}\n" + $"{nameof(LeaseId)}: {LeaseId}\n" + $"{nameof(duration)}: {duration}"); try { if (BlobClient != null) { return(await BlobRestClient.Blob.AcquireLeaseAsync( ClientDiagnostics, Pipeline, Uri, duration : serviceDuration, proposedLeaseId : LeaseId, ifModifiedSince : conditions?.IfModifiedSince, ifUnmodifiedSince : conditions?.IfUnmodifiedSince, ifMatch : conditions?.IfMatch, ifNoneMatch : conditions?.IfNoneMatch, async : async, operationName : Constants.Blob.Lease.AcquireOperationName, cancellationToken : cancellationToken) .ConfigureAwait(false)); } else { if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(conditions.IfMatch), nameof(conditions.IfNoneMatch)); } return(await BlobRestClient.Container.AcquireLeaseAsync( ClientDiagnostics, Pipeline, Uri, duration : serviceDuration, proposedLeaseId : LeaseId, ifModifiedSince : conditions?.IfModifiedSince, ifUnmodifiedSince : conditions?.IfUnmodifiedSince, async : async, operationName : Constants.Blob.Lease.AcquireOperationName, cancellationToken : cancellationToken) .ConfigureAwait(false)); } } catch (Exception ex) { Pipeline.LogException(ex); throw; } finally { Pipeline.LogMethodExit(nameof(BlobLeaseClient)); } } }
/// <summary> /// The <see cref="ChangeInternal"/> operation changes the lease /// of an active lease. A change must include the current /// <see cref="LeaseId"/> and a new <paramref name="proposedId"/>. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="proposedId"> /// An optional proposed lease ID, in a GUID string format. A /// <see cref="RequestFailedException"/> will be thrown if the /// proposed lease ID is not in the correct format. /// </param> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on changing a lease. /// </param> /// <param name="async"> /// Whether to invoke the operation asynchronously. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{Lease}"/> describing the lease. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> private async Task <Response <BlobLease> > ChangeInternal( string proposedId, RequestConditions conditions, bool async, CancellationToken cancellationToken) { EnsureClient(); using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient))) { Pipeline.LogMethodEnter( nameof(BlobLeaseClient), message: $"{nameof(Uri)}: {Uri}\n" + $"{nameof(LeaseId)}: {LeaseId}\n" + $"{nameof(proposedId)}: {proposedId}\n" + $"{nameof(conditions)}: {conditions}"); try { if (BlobClient != null) { return(await BlobRestClient.Blob.ChangeLeaseAsync( ClientDiagnostics, Pipeline, Uri, leaseId : LeaseId, proposedLeaseId : proposedId, ifModifiedSince : conditions?.IfModifiedSince, ifUnmodifiedSince : conditions?.IfUnmodifiedSince, ifMatch : conditions?.IfMatch, ifNoneMatch : conditions?.IfNoneMatch, async : async, operationName : Constants.Blob.Lease.ChangeOperationName, cancellationToken : cancellationToken) .ConfigureAwait(false)); } else { if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(conditions.IfMatch), nameof(conditions.IfNoneMatch)); } return(await BlobRestClient.Container.ChangeLeaseAsync( ClientDiagnostics, Pipeline, Uri, leaseId : LeaseId, proposedLeaseId : proposedId, ifModifiedSince : conditions?.IfModifiedSince, ifUnmodifiedSince : conditions?.IfUnmodifiedSince, async : async, operationName : Constants.Blob.Lease.ChangeOperationName, cancellationToken : cancellationToken) .ConfigureAwait(false)); } } catch (Exception ex) { Pipeline.LogException(ex); throw; } finally { Pipeline.LogMethodExit(nameof(BlobLeaseClient)); } } }
public AzureBlobsLogWriter(BlobContainerClient blobsContainerClient, string fileName, bool appendOpen = false) { fileName = AzureBlobsLogsInterface.PathFixer(fileName); _blobsContainerClient = blobsContainerClient; _logClient = _blobsContainerClient.GetAppendBlobClient(fileName); ETag currentETag; if (_previousOpenAttempts.ContainsKey(fileName) && appendOpen) { // We've opened this blob before and want to be non-destructive. We don't need to CreateIfNotExists, which could be VERY slow. currentETag = _logClient.GetProperties().Value.ETag; } else { try { // Create the file non-destructively if needed, guaranteeing write continuity on creation by grabbing the etag of the create, if needed if (appendOpen) { var response = _logClient.CreateIfNotExists(); if (response != null) { currentETag = response.Value.ETag; } else { currentETag = _logClient.GetProperties().Value.ETag; } } else { currentETag = _logClient.Create().Value.ETag; } } catch { currentETag = _logClient.GetProperties().Value.ETag; } } // Try to grab the blob lease _leaseClient = _logClient.GetBlobLeaseClient(); // The blob hasn't be touched since the last time. This is a candidate for breaking the lease. if (_previousOpenAttempts.ContainsKey(fileName) && (_previousOpenAttempts[fileName].ToString().Equals(currentETag.ToString()))) { _previousOpenAttempts[fileName] = currentETag; // The blob hasn't been updated. Try to break the lease and reacquire var requestConditions = new BlobRequestConditions(); requestConditions = new BlobRequestConditions(); requestConditions.IfMatch = currentETag; // If the condition fails in the break, it's because someone else managed to touch the file, so give up ETag newETag; try { newETag = _leaseClient.Break(null, requestConditions).Value.ETag; } catch (Exception e) { newETag = currentETag; } var etagCondition = new RequestConditions(); etagCondition.IfMatch = newETag; // If the condition fails, someone snuck in and grabbed the lock before we could. Give up. _curLease = _leaseClient.Acquire(TimeSpan.FromSeconds(-1), etagCondition).Value; } else { // Not a candidate for breaking the lease. Just try to acquire. _previousOpenAttempts[fileName] = currentETag; _curLease = _leaseClient.Acquire(TimeSpan.FromSeconds(-1)).Value; } _leaseCondition = new AppendBlobRequestConditions(); _leaseCondition.LeaseId = _curLease.LeaseId; // We got the lease! Set up thread to periodically touch the blob to prevent others from breaking the lease. _blobMetadata = _logClient.GetProperties().Value.Metadata; _stopRelockThread = false; _relockThreadStopped = false; _leaseRenewThread = new Thread(() => { while (!_stopRelockThread) { Thread.Sleep(100); var response = _logClient.SetMetadata(_blobMetadata, _leaseCondition); } _relockThreadStopped = true; }) { IsBackground = true }; _leaseRenewThread.Start(); _bytesToSend = new MemoryStream(); Debug.Assert(_logClient.Exists()); }
/// <summary> /// The <see cref="ReleaseInternal"/> operation releases the /// container or blob's previously-acquired lease. /// /// The lease may be released if the <see cref="LeaseId"/> /// matches that associated with the container or blob. Releasing the /// lease allows another client to immediately acquire the lease for the /// container or blob as soon as the release is complete. /// /// For more information, see <see href="https://docs.microsoft.com/rest/api/storageservices/lease-container" />. /// </summary> /// <param name="conditions"> /// Optional <see cref="RequestConditions"/> to add /// conditions on releasing a lease. /// </param> /// <param name="async"> /// Whether to invoke the operation asynchronously. /// </param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <returns> /// A <see cref="Response{ReleasedObjectInfo}"/> describing the /// updated blob or container. /// </returns> /// <remarks> /// A <see cref="RequestFailedException"/> will be thrown if /// a failure occurs. /// </remarks> public virtual async Task <Response <ReleasedObjectInfo> > ReleaseInternal( RequestConditions conditions, bool async, CancellationToken cancellationToken) { EnsureClient(); using (Pipeline.BeginLoggingScope(nameof(BlobLeaseClient))) { Pipeline.LogMethodEnter( nameof(BlobLeaseClient), message: $"{nameof(Uri)}: {Uri}\n" + $"{nameof(LeaseId)}: {LeaseId}\n" + $"{nameof(conditions)}: {conditions}"); try { if (BlobClient != null) { Response <BlobInfo> response = await BlobRestClient.Blob.ReleaseLeaseAsync( ClientDiagnostics, Pipeline, Uri, leaseId : LeaseId, ifModifiedSince : conditions?.IfModifiedSince, ifUnmodifiedSince : conditions?.IfUnmodifiedSince, ifMatch : conditions?.IfMatch, ifNoneMatch : conditions?.IfNoneMatch, async : async, operationName : Constants.Blob.Lease.ReleaseOperationName, cancellationToken : cancellationToken) .ConfigureAwait(false); return(Response.FromValue(new ReleasedObjectInfo(response.Value), response.GetRawResponse())); } else { if (conditions?.IfMatch != default || conditions?.IfNoneMatch != default) { throw BlobErrors.BlobConditionsMustBeDefault( nameof(RequestConditions.IfMatch), nameof(RequestConditions.IfNoneMatch)); } Response <BlobContainerInfo> response = await BlobRestClient.Container.ReleaseLeaseAsync( ClientDiagnostics, Pipeline, Uri, leaseId : LeaseId, ifModifiedSince : conditions?.IfModifiedSince, ifUnmodifiedSince : conditions?.IfUnmodifiedSince, async : async, operationName : Constants.Blob.Lease.ReleaseOperationName, cancellationToken : cancellationToken) .ConfigureAwait(false); return(Response.FromValue(new ReleasedObjectInfo(response.Value), response.GetRawResponse())); } } catch (Exception ex) { Pipeline.LogException(ex); throw; } finally { Pipeline.LogMethodExit(nameof(BlobLeaseClient)); } } }