wenxiangchao
4 天以前 559890c482f5973f06aafdfec9550fee5ba3c7f2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Threading;
using System.Threading.Tasks;
 
namespace Aging.Infrastructure.Contracts
{
    /// <summary>
    /// 自动化设备门面:为全自动测试程序提供"一次调用/一次作用域"的语义,
    /// 内部封装资源预约、驱动分派、审计。
    /// 
    /// 使用场景对比:
    ///   手动调试(DeviceDebug):需要 UI 逐步控制会话状态(ReadOnly → Maintenance)。
    ///   全自动测试(TestStep):只关心"发命令拿结果",不希望暴露状态机。
    /// 本接口面向后者。
    /// </summary>
    public interface IAutoDeviceFacade
    {
        /// <summary>
        /// 一次性执行:内部自动完成 申请租约 → 打开会话 → 执行 → 关闭会话 → 释放租约。
        /// 适合单条命令调用。多条命令建议使用 AcquireAsync 复用租约。
        /// </summary>
        Task<DeviceCommandResult> ExecuteAsync(
            string deviceId, string command, CancellationToken ct = default);
 
        /// <summary>
        /// 一次性查询:内部自动完成完整生命周期。
        /// </summary>
        Task<DeviceCommandResult> QueryAsync(
            string deviceId, string query, CancellationToken ct = default);
 
        /// <summary>
        /// 申请作用域租约:占用设备,返回 lease 句柄。
        /// using 结束时(Dispose)自动关会话 + 释放租约。
        /// 同一 lease 内的多次调用共享同一份资源占用,保证原子性。
        /// </summary>
        /// <param name="deviceId">设备标识</param>
        /// <param name="stepName">测试步骤名称(用于日志/审计标识)</param>
        /// <param name="ct">取消令牌;申请超时视为失败</param>
        Task<IAutoDeviceLease> AcquireAsync(
            string deviceId, string stepName, CancellationToken ct = default);
 
        /// <summary>
        /// 默认租约超时(秒)。可申请更短的 per-call 超时。
        /// </summary>
        int DefaultLeaseTimeoutSeconds { get; set; }
    }
 
    /// <summary>
    /// 自动化设备作用域租约。
    /// 一次申请,多次调用;Dispose 时自动释放。
    /// </summary>
    public interface IAutoDeviceLease : IDisposable
    {
        /// <summary>本次租约关联的设备 ID</summary>
        string DeviceId { get; }
 
        /// <summary>本次租约的内部会话标识(用于审计关联)</summary>
        string SessionId { get; }
 
        /// <summary>测试步骤名称</summary>
        string StepName { get; }
 
        /// <summary>申请时刻</summary>
        DateTime AcquiredAt { get; }
 
        /// <summary>租约是否已被释放</summary>
        bool IsReleased { get; }
 
        /// <summary>
        /// 在租约作用域内发送命令。
        /// </summary>
        Task<DeviceCommandResult> ExecuteAsync(string command, CancellationToken ct = default);
 
        /// <summary>
        /// 在租约作用域内查询。
        /// </summary>
        Task<DeviceCommandResult> QueryAsync(string query, CancellationToken ct = default);
 
        /// <summary>V3.0:租约失效(续期连续失败/被回收)时触发;订阅者应停止下发。</summary>
        event EventHandler LeaseLost;
 
        /// <summary>V3.0:显式异步释放。</summary>
        Task ReleaseAsync(CancellationToken ct = default);
 
        /// <summary>V3.0:维护让渡请求(Draining 预留,MVP 恒 false)。</summary>
        bool HandoverRequested { get; }
    }
}