visionA/docs/autoflow/04-architecture/adr/adr-001-two-binaries.md
jim800121chen fb7da5d180 chore(autoflow): migrate .autoflow/ 共享層文件至 docs/autoflow/
依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類
共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git),
讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等
per-branch 筆記。

- 02-prd/        21 個檔(PRD、features、market-analysis 等)
- 03-design/     18 個檔(design-spec、wireframes、flows 等)
- 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等)
- 07-delivery/   3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup)

合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv,
但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
2026-05-04 16:55:55 +08:00

97 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ADR-001visionA-backend 採用單一 Go 專案 / 雙 binary 結構
## 狀態
Accepted — 2026-04-21
## 背景 (Context)
visionA Cloud 後端需同時提供兩種完全不同性質的服務:
1. **API Server**(對 visionA-frontend
- 面向瀏覽器,提供 REST + WebSocket 介面
- **無狀態**:水平擴展容易,可放在無狀態的容器 / Serverless 執行環境
- 流量特性:一般 request/response延遲敏感< 200ms
- 負載模式可預測 DAU 成長線性增加
2. **Remote Proxy**對使用者端的 local-tool local agent
- 面向 local agent提供 WebSocket 長連線 + yamux 多工
- **有狀態**每個 local agent 開一條 tunnelsession 綁在該 proxy 節點
- 流量特性長連線小時)、資料量差異大控制指令 vs MJPEG / 推論串流
- 負載模式長連線 cost 主要在記憶體和 file descriptor不是 CPU
POCedge-ai-platform已經將 `edge-ai-server` `relay-server` 分拆成兩個 binary但兩者位於不同的 module / 不同的 cmd 路徑共用程式碼是透過 import 來達成
## 決策 (Decision)
visionA-backend 採用**一個 Go module兩個 binary**的結構
```
visionA-backend/
├── go.mod # module "visiona-backend"
├── cmd/
│ ├── api-server/main.go # 對前端的 REST + WebSocket API
│ └── remote-proxy/main.go # 對 local agent 的 tunnel server
└── internal/ # 兩個 binary 共用
├── api/
├── session/
├── relay/
├── tunnel/
├── storage/
└── ...
```
- 兩個 binary 使用**同一個 go.mod**可直接共用 `internal/` 下的套件
- 各自有獨立的 `cmd/xxx/main.go`選擇要載入哪些模組
- 共享狀態session metadata抽象為 `internal/session` interface
- `remote-proxy` 端用 `InMemoryStore`真正持有 `*yamux.Session`
- `api-server` 端用 `ProxyClientStore`透過 internal HTTP `remote-proxy`無本地 state
- **雛形 Phase 0 就採雙 binary + internal HTTP**2026-04-22 Q1 裁決)—— 不做 all-in-one 單進程版本因為那會讓 `api-server` 有狀態無法驗證真正的部署拓撲
- **不引入 Redis**POC 也沒用過 ADR-006
## 考慮過的替代方案
| 方案 | 優點 | 缺點 | 排除原因 |
|------|------|------|---------|
| **單 binaryAPI + Proxy 同一進程)** | 最簡單session 直接記憶體共用 | 無狀態 API 被迫與有狀態 Proxy 綁死API 無法獨立水平擴展擴容成本與 tunnel 連線耦合 | 無法水平擴展 APIProduction 不可行 |
| **雙 module兩個獨立 Go 專案)** | 完全隔離 | 共用程式碼typesprotocolsession interface要拆到第三個 module 或手動複製 | 維護兩倍 go.mod共用改動成本高POC 已走過這條路 |
| **三 binaryAPI + Proxy + Worker** | 關注點更分離 | 雛形階段沒有 worker workload過度設計 | 雛形用不到 |
| **單 binary + feature flag 決定角色** | 部署單一 image啟動時決定角色 | `-mode=api` vs `-mode=proxy` 會讓 main 變成 if/else 分派binary 含不必要依賴 | 編譯時分開更乾淨 |
| **雙 module + 共用 shared module** | 完全隔離 + 有共用 | 三個 Git repo / module 要同步版本CI 複雜 | 雛形階段不需要 |
## 後果 (Consequences)
### 正面影響
- **部署獨立**API Server 可放在無狀態的容器集群 ECS Fargate / Cloud RunRemote Proxy 放在支援長連線的 stateful 環境
- **擴展獨立**API 隨流量 auto-scaleProxy tunnel 連線數 scale兩者擴容邏輯不同
- **Release 獨立**API 新功能不需要重啟 Proxy 進程保持 tunnel 不中斷
- **共用方便**typesprotocolsession interface 直接放 `internal/`編譯時檢查
- **CI / Docker 簡單**兩個 Dockerfile同一個 go.mod依賴管理單一
### 負面影響(接受的取捨)
- **雛形就有 internal HTTP hop**`api-server → remote-proxy` 多一次 HTTP 呼叫localhost ~0.1ms跨機 LAN ~1-5ms接受此成本換取雛形部署拓撲 = Production 部署拓撲
- **觀測稍複雜**兩個 binary metrics / logs 要分別收集後 join
- **本機開發要開兩個進程** `docker-compose` `Makefile dev` target 同時啟動兩者
### 風險
- **session 查詢延遲**雛形 localhost internal HTTP 呼叫~0.1ms可忽略Phase 1 跨機 LAN ~1-5ms/
- **remote-proxy 是雛形有狀態單點**`remote-proxy` process 重啟 所有 tunnel session 遺失使用者需重新 pair ADR-006
- **多節點路由複雜度Phase 1**當有 N remote-proxy 節點時api-server 需要能找到某個 token tunnel 在哪個 proxy」——`tunnel.md` §5.4 已列出候選方案屆時新增 ADR
- **Phase 1 session metadata 共享機制未定****雛形不預先決定** Redis / Consul / Gossip避免過早最佳化 ADR-006
## 合規性
- [x] Architect 評估確認
- [x] PM 確認對業務的影響部署形態
- [x] 使用者 Q1 裁決 C雛形就用雙 binary + internal HTTP2026-04-22
- [ ] 成本影響已評估Phase 1 多節點時 session metadata 共享方案定案後再估
## 相關文件
- Design Doc §2系統邊界與組件
- Design Doc §4水平擴展策略
- TDD §1專案骨架)、§2.3session 模組)、§7雛形啟動
- ADR-006雛形不引入 Redis
- `api/api-internal.md`internal HTTP API 規格