refactor(task-7): integrate all layers and fix type mismatches
- Merge all branches (domain, infrastructure, repository, provider, adapter, usecase, cli)
- Update ServiceContext to inject dependencies
- Fix Message.Content type mismatch (string vs interface{})
- Update AccountStat to use entity.AccountStat
- Add helper functions for content conversion
This commit is contained in:
parent
8f1b7159ed
commit
7e0b7a970c
|
|
@ -0,0 +1,462 @@
|
|||
# REFACTOR TASKS
|
||||
|
||||
重構任務拆分,支援 git worktree 並行開發。
|
||||
|
||||
---
|
||||
|
||||
## Task Overview
|
||||
|
||||
### 並行策略
|
||||
|
||||
```
|
||||
時間軸 ──────────────────────────────────────────────────────────────►
|
||||
|
||||
Task 0: Init (必須先完成)
|
||||
│
|
||||
├── Task 1: Domain Layer ─────────────────────────┐
|
||||
│ │
|
||||
│ ┌── Task 2: Infrastructure Layer ────────────┤── 並行
|
||||
│ │ │
|
||||
│ └── Task 3: Repository Layer ────────────────┘
|
||||
│ (依賴 Task 1)
|
||||
│
|
||||
├── Task 4: Provider Layer ──────────────────────┐
|
||||
│ (依賴 Task 1) │
|
||||
│ │── 可並行
|
||||
├── Task 5: Usecase Layer ───────────────────────┤
|
||||
│ (依賴 Task 3) │
|
||||
│ │
|
||||
├── Task 6: Adapter Layer ───────────────────────┘
|
||||
│ (依賴 Task 1)
|
||||
│
|
||||
├── Task 7: Internal Layer ──────────────────────┐
|
||||
│ (整合所有,必須最後) │
|
||||
│ │── 序列
|
||||
├── Task 8: CLI Tools │
|
||||
│ │
|
||||
└── Task 9: Cleanup & Tests ────────────────────┘
|
||||
```
|
||||
|
||||
### Worktree 分支規劃
|
||||
|
||||
| 分支名稱 | 基於 | 任務 | 可並行 |
|
||||
|---------|------|------|--------|
|
||||
| `refactor/init` | `master` | Task 0 | ❌ |
|
||||
| `refactor/domain` | `refactor/init` | Task 1 | ✅ |
|
||||
| `refactor/infrastructure` | `refactor/init` | Task 2 | ✅ |
|
||||
| `refactor/repository` | `refactor/domain` | Task 3 | ✅ |
|
||||
| `refactor/provider` | `refactor/domain` | Task 4 | ✅ |
|
||||
| `refactor/usecase` | `refactor/repository` | Task 5 | ✅ |
|
||||
| `refactor/adapter` | `refactor/domain` | Task 6 | ✅ |
|
||||
| `refactor/internal` | 合併所有 | Task 7 | ❌ |
|
||||
| `refactor/cli` | `refactor/init` | Task 8 | ✅ |
|
||||
| `refactor/cleanup` | 合併所有 | Task 9 | ❌ |
|
||||
|
||||
---
|
||||
|
||||
## Task 0: 初始化
|
||||
|
||||
### 分支
|
||||
`refactor/init`
|
||||
|
||||
### 依賴
|
||||
無(必須先完成)
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **0.1** 更新 go.mod (5min)
|
||||
- `go get github.com/zeromicro/go-zero@latest`
|
||||
- `go mod tidy`
|
||||
|
||||
- [ ] **0.2** 建立目錄 (1min)
|
||||
- `mkdir -p api etc`
|
||||
|
||||
- [ ] **0.3** 建立 `api/chat.api` (15min)
|
||||
- 定義 API types
|
||||
- 定義 routes
|
||||
|
||||
- [ ] **0.4** 建立 `etc/chat.yaml` (5min)
|
||||
- 配置參數
|
||||
|
||||
- [ ] **0.5** 更新 Makefile (10min)
|
||||
- 新增 goctl 命令
|
||||
|
||||
- [ ] **0.6** 提交 (2min)
|
||||
|
||||
**預估時間**: ~30min
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Domain Layer
|
||||
|
||||
### 分支
|
||||
`refactor/domain`
|
||||
|
||||
### 依賴
|
||||
Task 0 完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **1.1** 建立目錄結構 (1min)
|
||||
- `pkg/domain/entity`
|
||||
- `pkg/domain/repository`
|
||||
- `pkg/domain/usecase`
|
||||
- `pkg/domain/const`
|
||||
|
||||
- [ ] **1.2** `entity/message.go` (10min)
|
||||
- Message, Tool, ToolFunction, ToolCall
|
||||
|
||||
- [ ] **1.3** `entity/chunk.go` (5min)
|
||||
- StreamChunk, ChunkType
|
||||
|
||||
- [ ] **1.4** `entity/account.go` (5min)
|
||||
- Account, AccountStat
|
||||
|
||||
- [ ] **1.5** `repository/account.go` (10min)
|
||||
- AccountPool interface
|
||||
|
||||
- [ ] **1.6** `repository/provider.go` (5min)
|
||||
- Provider interface
|
||||
|
||||
- [ ] **1.7** `usecase/chat.go` (15min)
|
||||
- ChatUsecase interface
|
||||
|
||||
- [ ] **1.8** `usecase/agent.go` (5min)
|
||||
- AgentRunner interface
|
||||
|
||||
- [ ] **1.9** `const/models.go` (10min)
|
||||
- Model 常數
|
||||
|
||||
- [ ] **1.10** `const/errors.go` (5min)
|
||||
- 錯誤定義
|
||||
|
||||
- [ ] **1.11** 提交 (2min)
|
||||
|
||||
**預估時間**: ~2h
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Infrastructure Layer
|
||||
|
||||
### 分支
|
||||
`refactor/infrastructure`
|
||||
|
||||
### 依賴
|
||||
Task 0 完成(可與 Task 1 並行)
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **2.1** 建立目錄 (2min)
|
||||
- `pkg/infrastructure/{process,parser,httputil,logger,env,workspace,winlimit}`
|
||||
|
||||
- [ ] **2.2** 遷移 process (10min)
|
||||
- runner.go, kill_unix.go, kill_windows.go, process_test.go
|
||||
|
||||
- [ ] **2.3** 遷移 parser (5min)
|
||||
- stream.go, stream_test.go
|
||||
|
||||
- [ ] **2.4** 遷移 httputil (5min)
|
||||
- httputil.go, httputil_test.go
|
||||
|
||||
- [ ] **2.5** 遷移 logger (5min)
|
||||
- logger.go
|
||||
|
||||
- [ ] **2.6** 遷移 env (5min)
|
||||
- env.go, env_test.go
|
||||
|
||||
- [ ] **2.7** 遷移 workspace (5min)
|
||||
- workspace.go
|
||||
|
||||
- [ ] **2.8** 遷移 winlimit (5min)
|
||||
- winlimit.go, winlimit_test.go
|
||||
|
||||
- [ ] **2.9** 驗證編譯 (5min)
|
||||
|
||||
- [ ] **2.10** 提交 (2min)
|
||||
|
||||
**預估時間**: ~1h
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Repository Layer
|
||||
|
||||
### 分支
|
||||
`refactor/repository`
|
||||
|
||||
### 依賴
|
||||
Task 1 完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **3.1** 建立目錄 (1min)
|
||||
|
||||
- [ ] **3.2** 遷移 account.go (20min)
|
||||
- AccountPool 實作
|
||||
- 移除全局變數
|
||||
|
||||
- [ ] **3.3** 遷移 provider.go (10min)
|
||||
- Provider 工廠
|
||||
|
||||
- [ ] **3.4** 遷移測試 (5min)
|
||||
|
||||
- [ ] **3.5** 驗證編譯 (5min)
|
||||
|
||||
- [ ] **3.6** 提交 (2min)
|
||||
|
||||
**預估時間**: ~1h
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Provider Layer
|
||||
|
||||
### 分支
|
||||
`refactor/provider`
|
||||
|
||||
### 依賴
|
||||
Task 1 完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **4.1** 建立目錄 (1min)
|
||||
- `pkg/provider/cursor`
|
||||
- `pkg/provider/geminiweb`
|
||||
|
||||
- [ ] **4.2** 遷移 cursor provider (5min)
|
||||
|
||||
- [ ] **4.3** 遷移 geminiweb provider (10min)
|
||||
|
||||
- [ ] **4.4** 更新 import (5min)
|
||||
|
||||
- [ ] **4.5** 驗證編譯 (5min)
|
||||
|
||||
- [ ] **4.6** 提交 (2min)
|
||||
|
||||
**預估時間**: ~30min
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Usecase Layer
|
||||
|
||||
### 分支
|
||||
`refactor/usecase`
|
||||
|
||||
### 依賴
|
||||
Task 3 完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **5.1** 建立目錄 (1min)
|
||||
|
||||
- [ ] **5.2** 建立 chat.go (30min)
|
||||
- 核心聊天邏輯
|
||||
|
||||
- [ ] **5.3** 遷移 agent.go (20min)
|
||||
- runner, token, cmdargs, maxmode
|
||||
|
||||
- [ ] **5.4** 遷移 sanitizer (10min)
|
||||
|
||||
- [ ] **5.5** 遷移 toolcall (10min)
|
||||
|
||||
- [ ] **5.6** 驗證編譯 (5min)
|
||||
|
||||
- [ ] **5.7** 提交 (2min)
|
||||
|
||||
**預估時間**: ~2h
|
||||
|
||||
---
|
||||
|
||||
## Task 6: Adapter Layer
|
||||
|
||||
### 分支
|
||||
`refactor/adapter`
|
||||
|
||||
### 依賴
|
||||
Task 1 完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **6.1** 建立目錄 (1min)
|
||||
|
||||
- [ ] **6.2** 遷移 openai adapter (10min)
|
||||
|
||||
- [ ] **6.3** 遷移 anthropic adapter (10min)
|
||||
|
||||
- [ ] **6.4** 更新 import (5min)
|
||||
|
||||
- [ ] **6.5** 驗證編譯 (5min)
|
||||
|
||||
- [ ] **6.6** 提交 (2min)
|
||||
|
||||
**預估時間**: ~30min
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Internal Layer
|
||||
|
||||
### 分支
|
||||
`refactor/internal`
|
||||
|
||||
### 依賴
|
||||
Task 1-6 全部完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **7.1** 合併所有分支 (5min)
|
||||
|
||||
- [ ] **7.2** 更新 config/config.go (15min)
|
||||
- 使用 rest.RestConf
|
||||
|
||||
- [ ] **7.3** 建立 svc/servicecontext.go (30min)
|
||||
- DI 容器
|
||||
|
||||
- [ ] **7.4** 建立 logic/ (1h)
|
||||
- chatcompletionlogic.go
|
||||
- geminichatlogic.go
|
||||
- anthropiclogic.go
|
||||
- healthlogic.go
|
||||
- modelslogic.go
|
||||
|
||||
- [ ] **7.5** 建立 handler/ (1h)
|
||||
- 自訂 SSE handler
|
||||
|
||||
- [ ] **7.6** 建立 middleware/ (20min)
|
||||
- auth.go
|
||||
- recovery.go
|
||||
|
||||
- [ ] **7.7** 建立 types/ (5min)
|
||||
- goctl 生成
|
||||
|
||||
- [ ] **7.8** 更新 import (30min)
|
||||
- 批量更新
|
||||
|
||||
- [ ] **7.9** 驗證編譯 (10min)
|
||||
|
||||
- [ ] **7.10** 提交 (2min)
|
||||
|
||||
**預估時間**: ~4h
|
||||
|
||||
---
|
||||
|
||||
## Task 8: CLI Tools
|
||||
|
||||
### 分支
|
||||
`refactor/cli`
|
||||
|
||||
### 依賴
|
||||
Task 0 完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **8.1** 建立目錄 (1min)
|
||||
|
||||
- [ ] **8.2** 遷移 CLI 工具 (10min)
|
||||
|
||||
- [ ] **8.3** 遷移 gemini-login (5min)
|
||||
|
||||
- [ ] **8.4** 更新 import (5min)
|
||||
|
||||
- [ ] **8.5** 提交 (2min)
|
||||
|
||||
**預估時間**: ~30min
|
||||
|
||||
---
|
||||
|
||||
## Task 9: Cleanup & Tests
|
||||
|
||||
### 分支
|
||||
`refactor/cleanup`
|
||||
|
||||
### 依賴
|
||||
Task 7 完成
|
||||
|
||||
### 小任務
|
||||
|
||||
- [ ] **9.1** 移除舊目錄 (5min)
|
||||
|
||||
- [ ] **9.2** 更新 import (30min)
|
||||
- 批量 sed
|
||||
|
||||
- [ ] **9.3** 建立 cmd/chat/chat.go (10min)
|
||||
|
||||
- [ ] **9.4** SSE 整合測試 (2h)
|
||||
|
||||
- [ ] **9.5** 回歸測試 (1h)
|
||||
|
||||
- [ ] **9.6** 更新 README (15min)
|
||||
|
||||
- [ ] **9.7** 提交 (2min)
|
||||
|
||||
**預估時間**: ~4h
|
||||
|
||||
---
|
||||
|
||||
## 並行執行計劃
|
||||
|
||||
### Wave 1 (可完全並行)
|
||||
```
|
||||
Terminal 1: Task 0 (init) → 30min
|
||||
Terminal 2: (等待 Task 0)
|
||||
```
|
||||
|
||||
### Wave 2 (可完全並行)
|
||||
```
|
||||
Terminal 1: Task 1 (domain) → 2h
|
||||
Terminal 2: Task 2 (infrastructure) → 1h
|
||||
Terminal 3: Task 8 (cli) → 30min
|
||||
```
|
||||
|
||||
### Wave 3 (可部分並行)
|
||||
```
|
||||
Terminal 1: Task 3 (repository) → 1h (依賴 Task 1)
|
||||
Terminal 2: Task 4 (provider) → 30min (依賴 Task 1)
|
||||
Terminal 3: Task 6 (adapter) → 30min (依賴 Task 1)
|
||||
Terminal 4: (等待 Task 3)
|
||||
```
|
||||
|
||||
### Wave 4 (可部分並行)
|
||||
```
|
||||
Terminal 1: Task 5 (usecase) → 2h (依賴 Task 3)
|
||||
Terminal 2: (等待 Task 5)
|
||||
```
|
||||
|
||||
### Wave 5 (序列)
|
||||
```
|
||||
Task 7 (internal) → 4h
|
||||
Task 9 (cleanup) → 4h
|
||||
```
|
||||
|
||||
**總時間估計**:
|
||||
- 完全序列: ~15h
|
||||
- 並行執行: ~9h
|
||||
- 節省: ~40%
|
||||
|
||||
---
|
||||
|
||||
## Git Worktree 指令
|
||||
|
||||
```bash
|
||||
# 創建 worktrees
|
||||
git worktree add ../worktrees/init -b refactor/init
|
||||
git worktree add ../worktrees/domain -b refactor/domain
|
||||
git worktree add ../worktrees/infrastructure -b refactor/infrastructure
|
||||
git worktree add ../worktrees/repository -b refactor/repository
|
||||
git worktree add ../worktrees/provider -b refactor/provider
|
||||
git worktree add ../worktrees/usecase -b refactor/usecase
|
||||
git worktree add ../worktrees/adapter -b refactor/adapter
|
||||
git worktree add ../worktrees/cli -b refactor/cli
|
||||
|
||||
# 並行工作
|
||||
cd ../worktrees/domain && # Terminal 1
|
||||
cd ../worktrees/infrastructure && # Terminal 2
|
||||
cd ../worktrees/cli && # Terminal 3
|
||||
|
||||
# 清理 worktrees
|
||||
git worktree remove ../worktrees/init
|
||||
git worktree remove ../worktrees/domain
|
||||
# ... 等等
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**文件版本**: v1.0
|
||||
**建立日期**: 2026-04-03
|
||||
|
|
@ -1,18 +1,23 @@
|
|||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package svc
|
||||
|
||||
import (
|
||||
"cursor-api-proxy/internal/config"
|
||||
domainrepo "cursor-api-proxy/pkg/domain/repository"
|
||||
"cursor-api-proxy/pkg/repository"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
|
||||
// Domain services
|
||||
AccountPool domainrepo.AccountPool
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
accountPool := repository.NewAccountPool(c.ConfigDirs)
|
||||
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
Config: c,
|
||||
AccountPool: accountPool,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package geminiweb
|
|||
|
||||
import (
|
||||
"context"
|
||||
"cursor-api-proxy/pkg/domain/entity"
|
||||
"cursor-api-proxy/internal/config"
|
||||
"cursor-api-proxy/pkg/domain/entity"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -624,18 +624,39 @@ func (p *PlaywrightProvider) selectModel(model string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// buildPromptFromMessages 從訊息列表建構提示詞
|
||||
// buildPromptFromMessagesPlaywright 從訊息列表建構提示詞
|
||||
func buildPromptFromMessagesPlaywright(messages []entity.Message) string {
|
||||
var prompt string
|
||||
for _, m := range messages {
|
||||
content := messageContentToStringPlaywright(m.Content)
|
||||
switch m.Role {
|
||||
case "system":
|
||||
prompt += "System: " + m.Content + "\n\n"
|
||||
prompt += "System: " + content + "\n\n"
|
||||
case "user":
|
||||
prompt += m.Content + "\n\n"
|
||||
prompt += content + "\n\n"
|
||||
case "assistant":
|
||||
prompt += "Assistant: " + m.Content + "\n\n"
|
||||
prompt += "Assistant: " + content + "\n\n"
|
||||
}
|
||||
}
|
||||
return prompt
|
||||
}
|
||||
|
||||
// messageContentToStringPlaywright converts Message.Content to string
|
||||
func messageContentToStringPlaywright(content interface{}) string {
|
||||
switch v := content.(type) {
|
||||
case string:
|
||||
return v
|
||||
case []interface{}:
|
||||
var result string
|
||||
for _, item := range v {
|
||||
if m, ok := item.(map[string]interface{}); ok {
|
||||
if text, ok := m["text"].(string); ok {
|
||||
result += text
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package geminiweb
|
|||
|
||||
import (
|
||||
"context"
|
||||
"cursor-api-proxy/pkg/domain/entity"
|
||||
"cursor-api-proxy/internal/config"
|
||||
"cursor-api-proxy/pkg/domain/entity"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -142,18 +142,40 @@ func (p *Provider) Generate(ctx context.Context, model string, messages []entity
|
|||
func buildPromptFromMessages(messages []entity.Message) string {
|
||||
var prompt string
|
||||
for _, m := range messages {
|
||||
content := messageContentToString(m.Content)
|
||||
switch m.Role {
|
||||
case "system":
|
||||
prompt += "System: " + m.Content + "\n\n"
|
||||
prompt += "System: " + content + "\n\n"
|
||||
case "user":
|
||||
prompt += m.Content + "\n\n"
|
||||
prompt += content + "\n\n"
|
||||
case "assistant":
|
||||
prompt += "Assistant: " + m.Content + "\n\n"
|
||||
prompt += "Assistant: " + content + "\n\n"
|
||||
}
|
||||
}
|
||||
return prompt
|
||||
}
|
||||
|
||||
// messageContentToString converts Message.Content to string
|
||||
func messageContentToString(content interface{}) string {
|
||||
switch v := content.(type) {
|
||||
case string:
|
||||
return v
|
||||
case []interface{}:
|
||||
// Handle array content (multimodal)
|
||||
var result string
|
||||
for _, item := range v {
|
||||
if m, ok := item.(map[string]interface{}); ok {
|
||||
if text, ok := m["text"].(string); ok {
|
||||
result += text
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// RunLogin 執行登入流程(供 gemini-login 命令使用)
|
||||
func RunLogin(cfg config.BridgeConfig, sessionName string) error {
|
||||
if sessionName == "" {
|
||||
|
|
|
|||
|
|
@ -3,30 +3,20 @@ package repository
|
|||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"cursor-api-proxy/pkg/domain/entity"
|
||||
)
|
||||
|
||||
type accountStatus struct {
|
||||
configDir string
|
||||
activeRequests int
|
||||
lastUsed int64
|
||||
rateLimitUntil int64
|
||||
totalRequests int
|
||||
totalSuccess int
|
||||
totalErrors int
|
||||
totalRateLimits int
|
||||
totalLatencyMs int64
|
||||
}
|
||||
|
||||
type AccountStat struct {
|
||||
ConfigDir string
|
||||
ActiveRequests int
|
||||
TotalRequests int
|
||||
TotalSuccess int
|
||||
TotalErrors int
|
||||
TotalRateLimits int
|
||||
TotalLatencyMs int64
|
||||
IsRateLimited bool
|
||||
RateLimitUntil int64
|
||||
configDir string
|
||||
activeRequests int
|
||||
lastUsed int64
|
||||
rateLimitUntil int64
|
||||
totalRequests int
|
||||
totalSuccess int
|
||||
totalErrors int
|
||||
totalRateLimits int
|
||||
totalLatencyMs int64
|
||||
}
|
||||
|
||||
type AccountPool struct {
|
||||
|
|
@ -155,13 +145,13 @@ func (p *AccountPool) ReportRateLimit(configDir string, penaltyMs int64) {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *AccountPool) GetStats() []AccountStat {
|
||||
func (p *AccountPool) GetStats() []entity.AccountStat {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
now := time.Now().UnixMilli()
|
||||
stats := make([]AccountStat, len(p.accounts))
|
||||
stats := make([]entity.AccountStat, len(p.accounts))
|
||||
for i, a := range p.accounts {
|
||||
stats[i] = AccountStat{
|
||||
stats[i] = entity.AccountStat{
|
||||
ConfigDir: a.configDir,
|
||||
ActiveRequests: a.activeRequests,
|
||||
TotalRequests: a.totalRequests,
|
||||
|
|
@ -180,7 +170,6 @@ func (p *AccountPool) Count() int {
|
|||
return len(p.accounts)
|
||||
}
|
||||
|
||||
|
||||
// ─── PoolHandle interface ──────────────────────────────────────────────────
|
||||
// PoolHandle 讓 handler 可以注入獨立的 pool 實例,避免多 port 模式共用全域 pool。
|
||||
|
||||
|
|
@ -191,19 +180,19 @@ type PoolHandle interface {
|
|||
ReportRequestSuccess(configDir string, latencyMs int64)
|
||||
ReportRequestError(configDir string, latencyMs int64)
|
||||
ReportRateLimit(configDir string, penaltyMs int64)
|
||||
GetStats() []AccountStat
|
||||
GetStats() []entity.AccountStat
|
||||
}
|
||||
|
||||
// GlobalPoolHandle 包裝全域函式以實作 PoolHandle 介面(單 port 模式使用)
|
||||
type GlobalPoolHandle struct{}
|
||||
|
||||
func (GlobalPoolHandle) GetNextConfigDir() string { return GetNextAccountConfigDir() }
|
||||
func (GlobalPoolHandle) ReportRequestStart(d string) { ReportRequestStart(d) }
|
||||
func (GlobalPoolHandle) ReportRequestEnd(d string) { ReportRequestEnd(d) }
|
||||
func (GlobalPoolHandle) GetNextConfigDir() string { return GetNextAccountConfigDir() }
|
||||
func (GlobalPoolHandle) ReportRequestStart(d string) { ReportRequestStart(d) }
|
||||
func (GlobalPoolHandle) ReportRequestEnd(d string) { ReportRequestEnd(d) }
|
||||
func (GlobalPoolHandle) ReportRequestSuccess(d string, l int64) { ReportRequestSuccess(d, l) }
|
||||
func (GlobalPoolHandle) ReportRequestError(d string, l int64) { ReportRequestError(d, l) }
|
||||
func (GlobalPoolHandle) ReportRateLimit(d string, p int64) { ReportRateLimit(d, p) }
|
||||
func (GlobalPoolHandle) GetStats() []AccountStat { return GetAccountStats() }
|
||||
func (GlobalPoolHandle) GetStats() []entity.AccountStat { return GetAccountStats() }
|
||||
|
||||
// ─── Global pool ───────────────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -273,7 +262,7 @@ func ReportRateLimit(configDir string, penaltyMs int64) {
|
|||
}
|
||||
}
|
||||
|
||||
func GetAccountStats() []AccountStat {
|
||||
func GetAccountStats() []entity.AccountStat {
|
||||
globalMu.Lock()
|
||||
p := globalPool
|
||||
globalMu.Unlock()
|
||||
|
|
|
|||
Loading…
Reference in New Issue