package httpserver import ( "context" "crypto/sha256" "encoding/json" "time" "git.yuntuo.hk/k2safe/orbit/internal/fault" core "git.yuntuo.hk/k2safe/orbit/model" "git.yuntuo.hk/k2safe/orbit/platform/auth" "git.yuntuo.hk/k2safe/orbit/pulse/worker" ) type claimResult struct { assignment *worker.Assignment err error } func workerPollKey(ns core.ID, in worker.ConnectInput) [32]byte { // 正式注册已校验;再次规范化仅取得稳定能力集合,不包含任何秘密。 in, _ = worker.NormalizeConnect(in) raw, _ := json.Marshal(struct { Namespace, Queue core.ID Capabilities []worker.Capability Keys bool }{ns, in.QueueID, in.Capabilities, in.ConcurrencyKeys}) return sha256.Sum256(raw) } func (h *WorkerHub) claimFair(ctx context.Context, t auth.Token, b worker.Binding, key [32]byte) (out claimResult) { // HTTP handler 原本具有 panic 隔离;异步领取同样不能因一次异常杀死其他连接。 defer func() { if recover() != nil { out = claimResult{err: fault.Unavailable} } }() h.mu.Lock() until := h.emptyPolls[key] h.mu.Unlock() if until.After(time.Now()) { return out } call, stop := context.WithTimeout(ctx, 8*time.Second) defer stop() out.assignment, out.err = h.service.Claim(call, t, b) if out.assignment == nil && out.err == nil { h.mu.Lock() now := time.Now() for k, v := range h.emptyPolls { if !v.After(now) { delete(h.emptyPolls, k) } } if len(h.emptyPolls) < 128 { h.emptyPolls[key] = now.Add(h.poll) } h.mu.Unlock() } return out }