Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
const leaderLockKeyPrefix = "leader:lock:"
|
||||
|
||||
// leaderLockReleaseScript releases a leader lock only when the caller still owns
|
||||
// it (compare-and-delete by owner token). This prevents a previous holder whose
|
||||
// lock already expired — and was re-acquired by another instance — from deleting
|
||||
// the new owner's lock.
|
||||
var leaderLockReleaseScript = redis.NewScript(`
|
||||
if redis.call("GET", KEYS[1]) == ARGV[1] then
|
||||
return redis.call("DEL", KEYS[1])
|
||||
end
|
||||
return 0
|
||||
`)
|
||||
|
||||
type leaderLockCache struct {
|
||||
rdb *redis.Client
|
||||
}
|
||||
|
||||
// NewLeaderLockCache returns a Redis-backed implementation of
|
||||
// service.LeaderLockCache used by periodic background jobs to elect a single
|
||||
// runner across instances.
|
||||
func NewLeaderLockCache(rdb *redis.Client) service.LeaderLockCache {
|
||||
return &leaderLockCache{rdb: rdb}
|
||||
}
|
||||
|
||||
func (c *leaderLockCache) TryAcquireLeaderLock(ctx context.Context, key, owner string, ttl time.Duration) (bool, error) {
|
||||
return c.rdb.SetNX(ctx, leaderLockKeyPrefix+key, owner, ttl).Result()
|
||||
}
|
||||
|
||||
func (c *leaderLockCache) ReleaseLeaderLock(ctx context.Context, key, owner string) error {
|
||||
return leaderLockReleaseScript.Run(ctx, c.rdb, []string{leaderLockKeyPrefix + key}, owner).Err()
|
||||
}
|
||||
Reference in New Issue
Block a user