update cicd

This commit is contained in:
2026-04-02 11:01:30 +00:00
parent 863a0ea2f6
commit 5a7f29c116
54 changed files with 4298 additions and 473 deletions

View File

@@ -3,7 +3,9 @@ package redis
import (
"context"
"encoding/json"
"errors"
"fmt"
"strings"
"time"
goredis "github.com/redis/go-redis/v9"
@@ -12,14 +14,24 @@ import (
)
const (
JobQueueKey = "render:jobs:queue"
LogChannel = "render:jobs:logs"
ResourceChannel = "render:agents:resources"
JobUpdateChannel = "render:jobs:updates"
JobQueueKey = "render:jobs:queue:v2"
JobInflightKey = "render:jobs:inflight"
JobInflightMetaKey = "render:jobs:inflight:meta"
JobSequenceKey = "render:jobs:queue:seq"
LogChannel = "render:jobs:logs"
ResourceChannel = "render:agents:resources"
JobUpdateChannel = "render:jobs:updates"
defaultQueuePoll = time.Second
defaultInflightTTL = 15 * time.Minute
)
type RedisAdapter struct{ client *goredis.Client }
type inflightMeta struct {
ReadyScore float64 `json:"ready_score"`
ClaimedAt int64 `json:"claimed_at"`
}
func NewAdapter(addr, password string, db int) (*RedisAdapter, error) {
client := goredis.NewClient(&goredis.Options{Addr: addr, Password: password, DB: db})
if err := client.Ping(context.Background()).Err(); err != nil {
@@ -31,13 +43,26 @@ func NewAdapter(addr, password string, db int) (*RedisAdapter, error) {
func (r *RedisAdapter) Client() *goredis.Client { return r.client }
func (r *RedisAdapter) Enqueue(ctx context.Context, job *model.Job) error {
data, err := json.Marshal(job)
if job == nil || strings.TrimSpace(job.ID) == "" {
return errors.New("job id is required")
}
priority := int64(0)
if job.Priority != nil {
priority = *job.Priority
}
seq, err := r.client.Incr(ctx, JobSequenceKey).Result()
if err != nil {
return err
}
timestamp := time.Now().UnixNano()
score := float64(-(int64(*job.Priority) * 1000000000) - timestamp)
return r.client.ZAdd(ctx, JobQueueKey, goredis.Z{Score: score, Member: data}).Err()
score := float64((-priority * 1_000_000_000_000) + seq)
jobID := strings.TrimSpace(job.ID)
if err := r.client.HDel(ctx, JobInflightMetaKey, jobID).Err(); err != nil {
return err
}
if err := r.client.ZRem(ctx, JobInflightKey, jobID).Err(); err != nil {
return err
}
return r.client.ZAdd(ctx, JobQueueKey, goredis.Z{Score: score, Member: jobID}).Err()
}
func (r *RedisAdapter) Dequeue(ctx context.Context) (*model.Job, error) {
@@ -56,27 +81,57 @@ func (r *RedisAdapter) Dequeue(ctx context.Context) (*model.Job, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(time.Second):
case <-time.After(defaultQueuePoll):
continue
}
}
var raw []byte
switch member := res[0].Member.(type) {
case string:
raw = []byte(member)
case []byte:
raw = member
default:
return nil, fmt.Errorf("unexpected redis queue payload type %T", member)
}
var job model.Job
if err := json.Unmarshal(raw, &job); err != nil {
jobID := fmt.Sprintf("%v", res[0].Member)
meta, err := json.Marshal(inflightMeta{ReadyScore: res[0].Score, ClaimedAt: time.Now().Unix()})
if err != nil {
return nil, err
}
return &job, nil
leaseScore := float64(time.Now().Add(defaultInflightTTL).Unix())
pipe := r.client.TxPipeline()
pipe.ZAdd(ctx, JobInflightKey, goredis.Z{Score: leaseScore, Member: jobID})
pipe.HSet(ctx, JobInflightMetaKey, jobID, meta)
if _, err := pipe.Exec(ctx); err != nil {
return nil, err
}
return &model.Job{ID: jobID}, nil
}
}
func (r *RedisAdapter) Ack(ctx context.Context, jobID string) error {
jobID = strings.TrimSpace(jobID)
if jobID == "" {
return nil
}
pipe := r.client.TxPipeline()
pipe.ZRem(ctx, JobQueueKey, jobID)
pipe.ZRem(ctx, JobInflightKey, jobID)
pipe.HDel(ctx, JobInflightMetaKey, jobID)
_, err := pipe.Exec(ctx)
return err
}
func (r *RedisAdapter) ListExpiredInflight(ctx context.Context, now time.Time, limit int64) ([]string, error) {
if limit <= 0 {
limit = 100
}
return r.client.ZRangeByScore(ctx, JobInflightKey, &goredis.ZRangeBy{Min: "-inf", Max: fmt.Sprintf("%d", now.Unix()), Offset: 0, Count: limit}).Result()
}
func (r *RedisAdapter) TouchInflight(ctx context.Context, jobID string, ttl time.Duration) error {
jobID = strings.TrimSpace(jobID)
if jobID == "" {
return nil
}
if ttl <= 0 {
ttl = defaultInflightTTL
}
return r.client.ZAddXX(ctx, JobInflightKey, goredis.Z{Score: float64(time.Now().Add(ttl).Unix()), Member: jobID}).Err()
}
func (r *RedisAdapter) Publish(ctx context.Context, jobID string, logLine string, progress float64) error {
payload, err := json.Marshal(dto.LogEntry{JobID: jobID, Line: logLine, Progress: progress})
if err != nil {
@@ -173,6 +228,7 @@ func (r *RedisAdapter) SubscribeJobUpdates(ctx context.Context) (<-chan string,
}()
return ch, nil
}
func (c *RedisAdapter) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error {
return c.client.Set(ctx, key, value, expiration).Err()
}