using System; using System.Threading; using System.Threading.Tasks; namespace Aging.Infrastructure.Contracts { /// /// 自动化设备门面:为全自动测试程序提供"一次调用/一次作用域"的语义, /// 内部封装资源预约、驱动分派、审计。 /// /// 使用场景对比: /// 手动调试(DeviceDebug):需要 UI 逐步控制会话状态(ReadOnly → Maintenance)。 /// 全自动测试(TestStep):只关心"发命令拿结果",不希望暴露状态机。 /// 本接口面向后者。 /// public interface IAutoDeviceFacade { /// /// 一次性执行:内部自动完成 申请租约 → 打开会话 → 执行 → 关闭会话 → 释放租约。 /// 适合单条命令调用。多条命令建议使用 AcquireAsync 复用租约。 /// Task ExecuteAsync( string deviceId, string command, CancellationToken ct = default); /// /// 一次性查询:内部自动完成完整生命周期。 /// Task QueryAsync( string deviceId, string query, CancellationToken ct = default); /// /// 申请作用域租约:占用设备,返回 lease 句柄。 /// using 结束时(Dispose)自动关会话 + 释放租约。 /// 同一 lease 内的多次调用共享同一份资源占用,保证原子性。 /// /// 设备标识 /// 测试步骤名称(用于日志/审计标识) /// 取消令牌;申请超时视为失败 Task AcquireAsync( string deviceId, string stepName, CancellationToken ct = default); /// /// 默认租约超时(秒)。可申请更短的 per-call 超时。 /// int DefaultLeaseTimeoutSeconds { get; set; } } /// /// 自动化设备作用域租约。 /// 一次申请,多次调用;Dispose 时自动释放。 /// public interface IAutoDeviceLease : IDisposable { /// 本次租约关联的设备 ID string DeviceId { get; } /// 本次租约的内部会话标识(用于审计关联) string SessionId { get; } /// 测试步骤名称 string StepName { get; } /// 申请时刻 DateTime AcquiredAt { get; } /// 租约是否已被释放 bool IsReleased { get; } /// /// 在租约作用域内发送命令。 /// Task ExecuteAsync(string command, CancellationToken ct = default); /// /// 在租约作用域内查询。 /// Task QueryAsync(string query, CancellationToken ct = default); /// V3.0:租约失效(续期连续失败/被回收)时触发;订阅者应停止下发。 event EventHandler LeaseLost; /// V3.0:显式异步释放。 Task ReleaseAsync(CancellationToken ct = default); /// V3.0:维护让渡请求(Draining 预留,MVP 恒 false)。 bool HandoverRequested { get; } } }