using System;
using System.Threading;
using System.Threading.Tasks;
namespace Aging.ResourceContracts
{
/// 与现有 OwnerType 数值对齐:Production=0, Maintenance=1。
public enum OwnerTypeV3 { Production = 0, Maintenance = 1 }
/// MVP 相位:Free 可用 / Active 持有 / RecoveryRequired 过期待回收(INV-03)。
public enum LeasePhase { Free = 0, Active = 1, RecoveryRequired = 2 }
/// 每资源一张租约凭证;栅栏=(AuthorityId, Epoch, ResourceKey, LeaseId, Generation)。
public sealed class LeaseGrant
{
public string AuthorityId { get; }
public string ResourceKey { get; }
public string LeaseId { get; }
public string OwnerId { get; }
public OwnerTypeV3 OwnerType { get; }
public long Epoch { get; }
public long Generation { get; }
public long ExpiresUtcMs { get; }
public LeaseGrant(string authorityId, string resourceKey, string leaseId,
string ownerId, OwnerTypeV3 ownerType, long epoch, long generation, long expiresUtcMs)
{
AuthorityId = authorityId; ResourceKey = resourceKey; LeaseId = leaseId;
OwnerId = ownerId; OwnerType = ownerType; Epoch = epoch;
Generation = generation; ExpiresUtcMs = expiresUtcMs;
}
}
public sealed class AcquireRequest
{
public string OwnerId { get; set; } = "";
public OwnerTypeV3 OwnerType { get; set; }
/// boot_id + pid,同机进程区分。
public string ProcessInstanceId { get; set; } = "";
public string MachineName { get; set; } = Environment.MachineName;
public int HostProcessId { get; set; } = System.Diagnostics.Process.GetCurrentProcess().Id;
/// 申请理由(维护会话填操作员与原因,进 lease_history)。
public string Reason { get; set; } = "";
/// Ordinals 升序、去重后申请(组申请 = 单事务全有全无)。
public string[] ResourceKeys { get; set; } = new string[0];
public int WaitTimeoutMs { get; set; } = 1000;
public int TtlSeconds { get; set; } = 30;
}
public enum AcquireResultCode { Acquired, Reused, ConflictHeld, RecoveryBlocked, Timeout }
public sealed class ConflictInfo
{
public string OwnerId { get; set; } = "";
public OwnerTypeV3 OwnerType { get; set; }
public string MachineName { get; set; } = "";
public int HostProcessId { get; set; }
public string Reason { get; set; } = "";
public long ExpiresUtcMs { get; set; }
}
public sealed class AcquireOutcome
{
public AcquireResultCode Code { get; set; }
public LeaseGrant[] Grants { get; set; } = new LeaseGrant[0];
public ConflictInfo? Holder { get; set; }
/// RecoveryBlocked 时指向 recovery_checkpoint 的键。
public string? RecoveryCheckpointKey { get; set; }
}
/// 租约协调器:仲裁域唯一入口。实现方:DbLeaseStore。
public interface ILeaseCoordinator
{
/// 权威域当前 epoch(重启后递增,旧 Grant 自动失效)。
long CurrentEpoch { get; }
AcquireOutcome Acquire(AcquireRequest request);
/// 同 LeaseId+Generation 续期;返回 false=已被回收/超越(本地须熔断)。
bool Renew(LeaseGrant grant, int extendSeconds);
bool Release(LeaseGrant grant, string note);
ConflictInfo? ProbeConflict(string resourceKey);
LeasePhase PhaseOf(string resourceKey);
int SweepExpired();
/// RecoveryRequired → Free:宿主完成读回探测后登记证据并放行。
bool ApproveRecovery(string resourceKey, string readbackJson, string approvedBy);
/// 测试用:强制提升 epoch,使所有活跃 Grant 失效。
void BumpEpochForTest(string reason);
}
}