fix: Renew presence on sub/pub
Chart Release / chart (push) Successful in 18s
Server Deploy / deploy (push) Successful in 56s

This commit is contained in:
2026-07-31 16:58:50 +01:00
parent 71240f183c
commit 8699dc5b7e
3 changed files with 57 additions and 3 deletions
+22
View File
@@ -204,6 +204,21 @@ func SetPresence(ctx context.Context, serverID string, ttl time.Duration) error
return rdb.Set(ctx, PresenceKey+serverID, nodeID, ttl).Err()
}
// RenewPresence extends serverID's claim, but only while this node still holds
// it, and reports whether it did.
//
// A blind SET here is wrong, not merely untidy. When an agent reconnects, its
// previous stream can stay half-open on another pod for the length of a
// keepalive cycle, and that pod goes on renewing. Two processes then overwrite
// each other's claim every renewal interval and the key names whichever wrote
// last rather than whichever holds the live stream. A superseded pod must lose
// quietly instead.
func RenewPresence(ctx context.Context, serverID string, ttl time.Duration) bool {
n, err := renewPresenceIfOwner.Run(ctx, rdb,
[]string{PresenceKey + serverID}, nodeID, int64(ttl/time.Millisecond)).Int64()
return err == nil && n == 1
}
// ClearPresence releases serverID, but only if this node still holds it. A
// blind DEL would let a pod whose stream had already been re-established
// elsewhere delete the new owner's claim on its way out.
@@ -274,6 +289,13 @@ end
return ""
`)
var renewPresenceIfOwner = redis.NewScript(`
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("PEXPIRE", KEYS[1], ARGV[2])
end
return 0
`)
var releaseIfOwner = redis.NewScript(`
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])