单二进制三角色 + Dock 适配器 + Swarm stack 达到可部署态;mgr1 实测订阅经 central-proxy bootstrap,探活 alive=41/52。 Co-authored-by: Cursor <cursoragent@cursor.com>
79 lines
2.2 KiB
Go
79 lines
2.2 KiB
Go
// results.go:任务结果缓存 + /result 查询支撑。
|
||
//
|
||
// 契约(A3.1):GET /result/{request_id}:done → Envelope;queued/running →
|
||
// 202 + {status};无 → 404。done 信封写进程内 bounded LRU(50 条,与 gateway
|
||
// 缓存同量级);schema 禁改(W1 纪律)→ 信封不另立列,进程内缓存为权威读面,
|
||
// 缓存淘汰后由 gateway 按 202 轮询引导重查。
|
||
package scheduler
|
||
|
||
import (
|
||
"encoding/json"
|
||
"sync"
|
||
"time"
|
||
|
||
"onesvm.com/onesvm/browser-server/internal/contract"
|
||
)
|
||
|
||
// resultEntry 结果条目。
|
||
type resultEntry struct {
|
||
env *contract.Envelope
|
||
setAt time.Time
|
||
}
|
||
|
||
// resultCache 进程内 done 信封缓存(bounded LRU)。
|
||
type resultCache struct {
|
||
mu sync.Mutex
|
||
cap int
|
||
items map[string]*resultEntry
|
||
order []string // LRU 序(头部最旧)
|
||
}
|
||
|
||
func newResultCache() *resultCache {
|
||
return &resultCache{cap: 50, items: map[string]*resultEntry{}}
|
||
}
|
||
|
||
// put 写入(超 cap 淘汰最旧)。
|
||
func (c *resultCache) put(reqID string, env *contract.Envelope) {
|
||
if reqID == "" || env == nil {
|
||
return
|
||
}
|
||
c.mu.Lock()
|
||
defer c.mu.Unlock()
|
||
if _, exists := c.items[reqID]; !exists {
|
||
c.order = append(c.order, reqID)
|
||
}
|
||
c.items[reqID] = &resultEntry{env: env, setAt: time.Now()}
|
||
for len(c.order) > c.cap {
|
||
oldest := c.order[0]
|
||
c.order = c.order[1:]
|
||
delete(c.items, oldest)
|
||
}
|
||
}
|
||
|
||
// get 读(命中提升 LRU 位)。
|
||
func (c *resultCache) get(reqID string) (*contract.Envelope, bool) {
|
||
c.mu.Lock()
|
||
defer c.mu.Unlock()
|
||
e, ok := c.items[reqID]
|
||
if !ok {
|
||
return nil, false
|
||
}
|
||
return e.env, true
|
||
}
|
||
|
||
// buildResultEnvelope 适配器执行结果 → Envelope(模版层 Build 的调用包装)。
|
||
func buildResultEnvelope(t *Template, in TemplateInput) *contract.Envelope {
|
||
return t.Build(TemplateInput{
|
||
Job: in.Job, Adapter: in.Adapter, ProxyExit: in.ProxyExit,
|
||
Cached: in.Cached, Raw: in.Raw, Warnings: in.Warnings, TookMs: in.TookMs,
|
||
})
|
||
}
|
||
|
||
// jsonRaw 信封序列化(/result 内嵌用)。
|
||
func jsonRaw(e *contract.Envelope) json.RawMessage {
|
||
b, err := json.Marshal(e)
|
||
if err != nil {
|
||
return json.RawMessage(`{"ok":false,"error":{"code":"upstream","message":"信封序列化失败"}}`)
|
||
}
|
||
return b
|
||
}
|