using Aging.Infrastructure.Contracts;
|
|
namespace Aging.Infrastructure.Core
|
{
|
/// <summary>
|
/// 操作租约实现。
|
/// 提供短期资源占用保证,支持同步和异步释放。
|
/// 释放时通过回调通知 ResourceManager。
|
/// </summary>
|
public sealed class OperationLease : IOperationLease
|
{
|
private readonly Action? _onRelease;
|
private bool _disposed;
|
|
/// <inheritdoc/>
|
public string LeaseId { get; }
|
|
/// <inheritdoc/>
|
public ResourceKey Resource { get; }
|
|
/// <inheritdoc/>
|
public ResourceOwnerToken Owner { get; }
|
|
/// <inheritdoc/>
|
public DateTime AcquiredAt { get; }
|
|
/// <inheritdoc/>
|
public DateTime? ExpiresAt { get; }
|
|
/// <inheritdoc/>
|
public bool IsValid => !_disposed && !IsExpired();
|
|
/// <summary>
|
/// 初始化操作租约实例
|
/// </summary>
|
/// <param name="resource">资源键</param>
|
/// <param name="owner">所有者令牌</param>
|
/// <param name="onRelease">释放时的回调通知</param>
|
/// <param name="leaseDurationSeconds">租约有效期(秒),默认30秒</param>
|
public OperationLease(
|
ResourceKey resource,
|
ResourceOwnerToken owner,
|
Action? onRelease = null,
|
int leaseDurationSeconds = 30)
|
{
|
LeaseId = Guid.NewGuid().ToString();
|
Resource = resource ?? throw new ArgumentNullException(nameof(resource));
|
Owner = owner ?? throw new ArgumentNullException(nameof(owner));
|
AcquiredAt = DateTime.UtcNow;
|
ExpiresAt = leaseDurationSeconds > 0
|
? AcquiredAt.AddSeconds(leaseDurationSeconds)
|
: null;
|
_onRelease = onRelease;
|
_disposed = false;
|
}
|
|
/// <summary>
|
/// 检查租约是否已过期
|
/// </summary>
|
private bool IsExpired()
|
{
|
if (!ExpiresAt.HasValue)
|
return false;
|
return DateTime.UtcNow > ExpiresAt.Value;
|
}
|
|
/// <inheritdoc/>
|
public void Dispose()
|
{
|
if (_disposed) return;
|
_disposed = true;
|
_onRelease?.Invoke();
|
}
|
|
/// <inheritdoc/>
|
public ValueTask DisposeAsync()
|
{
|
Dispose();
|
return default;
|
}
|
}
|
}
|