3D Plugin / 多設備單元邊界分析

本頁整理平台化擴充、Plugin DLL、多設備單元、Resource Lock 與 Command Queue 的責任邊界。

返回 docs

3D Plugin / 多設備單元邊界分析

1. 文件定位

本文件是第三階段 3D「平台化擴充」的第一份邊界分析,用來釐清未來外部 Plugin DLL、多設備單元、資源鎖、命令佇列、設定版本與回滾之間的責任分工。

本文件只做分析與確認準備,不代表已同意新增 Plugin Loader、載入外部 DLL、修改 IDeviceAdapter public contract、導入外部 plugin framework、建立背景服務、修改設定檔格式、接真實硬體或把案場客製邏輯寫入 Core。

2. 3D 目標

3D 的目標不是立即讓系統動態載入外部 DLL,而是先把平台化擴充的邊界固定好,避免後續把設備單元、硬體 driver、資源排程、任務佇列、設定版本與案場客製流程混在同一層。

目標說明
固定多設備單元模型釐清 ControlUnitIdStationIdDeviceId、Adapter instance 與實體設備之間的關係。
固定 Plugin 邊界決定未來外部 DLL 應提供什麼資訊、如何失敗隔離、如何映射到既有 Adapter contract。
固定 Resource Lock 邊界避免多任務、多設備單元或多命令同時搶同一實體資源。
固定 Command Queue 邊界讓命令排程與任務生命週期可追蹤,不在 Controller、Host 或 Adapter 內各自排隊。
固定設定版本與回滾方向未來 JSON / plugin / 設備設定變更需可審核、追蹤與回復。
建立停止線未確認前不載入 DLL、不改 public contract、不導入套件、不改啟動方式。

3. 既有前置能力

前置能力狀態對 3D 的意義
IDeviceAdapter已存在未來 plugin adapter 應先映射回既有 Adapter contract,不讓 Core 認識 DLL 載入細節。
DeviceId已存在目前已可由設定、WorkflowNode、DeviceCommand 與 Log 串接設備識別。
DeviceAdapterDispatcher已存在已具備依 DeviceId 分派 adapter 的基礎,但尚未處理多設備單元與資源鎖。
Adapter Connect rollback已完成多設備啟動中途失敗時,已成功連線的 adapter 會補償斷線,可作為未來 ControlUnit 啟動失敗策略基礎。
TaskEngine / WorkflowEngine已存在Resource Lock / Command Queue 不應讓 Workflow node 自行散落管理。
HS.DeviceControl.Application3C 已完成第一版未來可承接任務控制、設備狀態、健康檢查與平台化協調,但 3D 本文件不修改程式。
Log / Trace / TaskStore第二階段與 3A 已完成基礎未來 lock、queue、plugin 載入與設備命令需可追蹤,不只回傳 bool。

4. 名詞邊界

名詞建議語意不應混淆的內容
ControlUnitId一組可被系統共同管理的設備單元,例如一台調劑台、一組藥櫃、一個控制盒或一組產線 station。不等於單一 adapter,也不一定等於一台 PC。
StationIdControl Unit 底下可被操作或辨識的位置,例如站點、格位、通道、藥槽或工作區。不應拿來取代 DeviceId
DeviceId系統內對單一設備或 adapter instance 的穩定識別。不應包含連線密碼、IP、Port 等敏感資訊。
Adapter instance程式執行時實際負責 ConnectDisconnectGetStatusExecute 的物件。不應知道 WebApi route 或 UI 控制項。
Plugin package未來可能由外部 DLL、manifest、版本資訊與相依檔案組成的設備擴充包。本階段不載入、不掃描、不執行。
Resource實體或邏輯上不能被同時占用的資源,例如設備、COM port、TCP endpoint、機械手臂、門鎖、秤重平台。不只等於 DeviceId,也可能跨多個 device。

5. 多設備單元模型邊界

第一版分析建議先把多設備單元視為「設定與執行協調模型」,不要直接改既有 config schema。未來若要實作,需另行確認是否新增 ControlUnitId / StationId 欄位,以及它們如何映射到既有 DeviceId

層級候選責任第一版邊界
Control Unit管理一組設備、共享資源與啟停生命週期。先分析,不新增設定欄位。
Station表示 Control Unit 內的一個操作位置或槽位。先定義語意,不綁定特定藥局設備。
Device既有 adapter 操作單位。沿用 DeviceId,不改 Adapter contract。
Workflow Node宣告要操作的 DeviceId 與命令。不在 node 內寫死連線資訊或資源鎖實作。
Task / Command任務與命令需可追蹤 lock / queue 狀態。未確認前不新增資料表或 DB 欄位。

建議原則:

6. Plugin Loader 邊界

Plugin Loader 未來應是「Infrastructure / Host 端能力」,不應進入 Core。Core 只需要知道 IDeviceAdapter 與標準 Result / Error,不能知道 DLL 路徑、AssemblyLoadContext、manifest、檔案雜湊或外部套件相依。

項目邊界說明
Plugin 掃描未來可由 Host / Infrastructure 掃描指定目錄,但本階段不掃描。
DLL 載入未來需有 allowlist、版本、相依套件與失敗隔離策略,但本階段不載入。
Adapter 建立Plugin 最終應產生或註冊 IDeviceAdapter 相容物件,不讓 WorkflowEngine 依賴 plugin 型別。
Manifest可候選記錄 plugin id、版本、支援 device type、capability 與 checksum,但本階段不定 schema。
失敗隔離載入失敗、版本不符、建構失敗、Connect 失敗需轉為標準 ErrorInfo / ExecuteResult。
安全不保存密碼、Token、正式路徑或連線資訊到 repo;不從任意路徑載入 DLL。

Plugin Loader 不應負責:

7. Resource Lock 邊界

Resource Lock 的目的,是保護不能同時被多個任務或命令占用的實體資源。它應該是任務執行協調層的能力,不應散落在每個 Adapter 或 Workflow node 內。

候選資源鎖定原因第一版建議
DeviceId同一設備同時下多個命令可能造成狀態錯亂。預設可視為 exclusive resource。
通訊通道多個設備共用同一 COM port、TCP endpoint 或 gateway。需允許跨 device 的 shared resource key。
機械動作區馬達、門、輸送帶、秤重平台等實體動作不可重疊。不寫死藥局語意,以 resource key 表示。
Control Unit整組設備啟停、維護或急停時需整體鎖定。未來可支援 unit-level lock。
Schema Apply / PreviewPreview 可 read-only;Apply 屬高風險獨占操作。3D 不處理正式 Apply。

Resource Lock 第一版候選欄位:

欄位用途
ResourceKey資源穩定識別,例如 device:light-01channel:com3
ModeExclusive / SharedRead 等候選模式,需另行確認。
OwnerTaskId鎖的任務擁有者。
OwnerNodeId鎖的節點來源。
CommandName觸發鎖的命令。
AcquiredAtUtc取得時間。
ExpiresAtUtc超時保護,避免永久卡住。
ReleaseReason正常完成、失敗、取消、timeout 或補償釋放。

8. Command Queue 邊界

Command Queue 的目的,是讓命令進入可觀察、可取消、可追蹤的排程流程,而不是讓 HTTP request、Host loop、Adapter 或 Thread.Sleep 各自形成隱性佇列。

面向邊界說明
Queue 所在層建議放在 Application / ServiceHost 協調層,不放 Core,不放 WebApi controller。
Queue 單位可依 DeviceIdResourceKeyControlUnitId 或 Task scope 決定。
排序策略第一版建議先分析 FIFO;Priority、deadline、preemption 需另行確認。
狀態至少需能區分 queued、running、completed、failed、cancelled、timeout。
錯誤queue 滿、lock timeout、device offline、adapter exception 需有標準錯誤碼。
DB未確認前不新增 queue table,也不改 TaskStore schema。

Command Queue 不應負責:

9. 設定版本與回滾邊界

多設備與 plugin 會讓設定變更風險升高,因此後續需要可追蹤的設定版本策略。但本文件不修改 devices.jsonworkflows.jsonappsettings.json 格式。

項目候選方向本次邊界
設定版本版本號、異動時間、作者、摘要、hash。只分析,不改 schema。
Plugin 版本plugin id、version、capabilities、checksum。只分析,不建立 manifest。
相容性min core/app version、adapter contract version。不改 public contract。
回滾保留上一版設定與安全回復策略。不建立儲存機制。
審核正式變更前需人工確認與驗證節點。不導入權限系統。

10. 與 3C Application Contract 的關係

3C 已建立 Application contract 第一版,但 3D 不應直接把 plugin 與 queue 塞進既有 contract。比較安全的順序是先完成 3D 邊界決策,再判斷是否需要新增 Application 層 contract。

既有 3C 能力3D 可能承接方式是否本次實作
DeviceStatusService未來可查 Control Unit / Plugin adapter 狀態。
TaskControlService未來可把命令排入 queue 或取得 lock 後執行。
HealthService未來可回報 plugin、queue、resource lock 健康狀態。
SchemaPreviewService與 plugin 無直接關係;仍只 preview、不 apply。

11. 候選程式影響範圍

以下只是後續取得明確授權後可能進入的候選範圍;本次不修改程式 repo。

類型候選路徑 / 名稱用途是否已授權
新增文件docs/plugin-multi-device-boundary-analysis.md本次 3D 邊界分析已授權進入文件整理
新增 contractHS.DeviceControl.Application.Resources/*Resource Lock request / result / service contract尚未
新增 contractHS.DeviceControl.Application.Commands/*Command Queue request / result / service contract尚未
新增模型ControlUnitId / StationId DTO多設備單元識別尚未
新增 Plugin contractHS.DeviceControl.Plugins 或 Application plugin namespacePlugin metadata / factory 候選尚未
新增 InfrastructurePlugin Loader / manifest reader掃描與載入外部 DLL尚未,且需再次確認
修改 Adapter contractIDeviceAdapter若需 capability / metadata 擴充尚未,且目前不建議先改
修改設定 schemadevices / workflows / appsettingsControl Unit、Station、resource key、plugin mapping尚未

12. 驗證節點候選

驗證節點驗證目的前置條件
多設備單元模型確認確認 ControlUnitId / StationId / DeviceId 不混淆,且不寫案場客製語意。完成 3D 決策確認。
Resource Lock dry-run 驗證確認同一 resource 被第二個任務占用時會被擋下,且逾時可釋放。需另行同意 contract / fake 實作。
Command Queue fake 驗證確認命令可排隊、狀態可查、取消可追蹤,不直接操作硬體。需另行同意 queue contract。
Plugin metadata 驗證確認 manifest / metadata 可讀,但不載入 DLL。需另行同意 metadata schema。
Plugin Loader 隔離驗證確認載入失敗會回標準錯誤且不影響 Host。需另行同意載入外部 DLL,非本階段預設。

13. 尚待決策

決策影響
是否採用 ControlUnitId / StationId 作為標準命名會影響設定格式、DTO、Log、Trace 與 UI 顯示。
Resource Lock 放在 Application 層、ServiceHost 層或 Infrastructure 層會影響 public contract、測試與未來 DB 保存方式。
Command Queue 是否先做 in-memory fake contract會影響 TaskControlService 與任務生命週期。
Plugin 第一版是否只做 metadata / manifest,不載入 DLL可降低安全與相依套件風險。
是否維持 IDeviceAdapter 不變,先用 wrapper / factory 映射 plugin會影響 Adapter contract 穩定性。
是否需要設定版本與回滾文件先行會影響 JSON schema 與管理流程。
是否將 3D 第一版限制為文件與決策確認可避免過早導入外部 DLL、queue 套件或背景服務。

14. 停止線

本文件完成後,以下項目仍不得自動執行:

15. 建議下一步

建議下一步先整理「3D 決策確認表」,讓使用者逐項確認:

  1. 是否同意 3D 第一版先做邊界與 contract 草案,不載入外部 DLL。
  2. 是否同意多設備單元命名先採 ControlUnitId / StationId / DeviceId 三層語意。
  3. 是否同意 Resource Lock 第一版先做 Application 層 contract 候選,不新增 DB table。
  4. 是否同意 Command Queue 第一版先做 fake / in-memory contract 候選,不導入 queue 套件。
  5. 是否同意 Plugin 第一版先做 metadata / manifest 邊界,不建立 Loader。
  6. 是否同意維持 IDeviceAdapter public contract 不變,後續用 wrapper / factory 承接 plugin。
  7. 是否同意未確認前不改 config schema、不改啟動方式、不新增 ServiceHost / WebApi、不保存敏感資訊。