package redisactivity import ( "context" "errors" "strconv" "time" ownershipDomain "proxy-pool/internal/domain/ownership" proxyDomain "proxy-pool/internal/domain/proxy" ) var _ ownershipDomain.SnapshotReader = (*Adapter)(nil) // ReadWorkerSnapshot returns every currently assignable proxy owned by one // Worker. The Lua script rejects an oversized view rather than returning a // partial snapshot that could silently withdraw still-owned proxies. func (a *Adapter) ReadWorkerSnapshot( ctx context.Context, workerID string, limit int, ) ([]ownershipDomain.SnapshotProxy, error) { if ctx == nil || a == nil || !runtimeClean(workerID) || limit <= 0 { return nil, ownershipDomain.ErrInvalidOwnership } if err := ctx.Err(); err != nil { return nil, err } result, err := runScript(ctx, a.client, workerSnapshotScript, []string{ a.keys.records, a.keys.owners, a.keys.workerOwned(workerID), }, workerID, limit) if err != nil { return nil, err } var reply workerSnapshotScriptReply if err := decodeScriptResult(result, &reply); err != nil { return nil, err } switch reply.Status { case scriptOK: case scriptInvalid: return nil, ownershipDomain.ErrInvalidOwnership case scriptUnavailable: return nil, errors.Join(ownershipDomain.ErrOwnershipUnavailable, errors.New("worker snapshot limit exceeded")) default: return nil, invalidScriptReply("unexpected worker snapshot reply") } proxies := make([]ownershipDomain.SnapshotProxy, 0, len(reply.Proxies)) for _, item := range reply.Proxies { record, err := decodeProxyRecord(item.Record) if err != nil { return nil, invalidScriptReply("worker snapshot contained invalid proxy record") } epoch, err := strconv.ParseUint(item.OwnershipEpoch, 10, 64) if err != nil || epoch == 0 || item.LeaseExpiresAtMS <= 0 { return nil, invalidScriptReply("worker snapshot contained invalid ownership") } proxy := proxyRecordEntry(record).Proxy if proxy.State != proxyDomain.StateAvailable || proxy.MaxConcurrency <= 0 || proxy.ExpiresAt == nil || proxy.UsableUntil == nil { return nil, invalidScriptReply("worker snapshot contained unavailable proxy") } proxies = append(proxies, ownershipDomain.SnapshotProxy{ Proxy: proxy, OwnershipEpoch: epoch, LeaseExpiresAt: time.UnixMilli(item.LeaseExpiresAtMS).UTC(), }) } return proxies, nil }