fix(reaper): 认领时重置活跃时钟与预警,回收只复用本次认领后的 reaper 归档

This commit is contained in:
Lemon-miaow committed 2026-09-24 19:31:23 +08:00
1 parent 47890ca913
commit 22becd6859
7 files changed
+187 -8

No files matched your search

+8 -1
View File
@@ -417,6 +417,12 @@ func (p *PGRepo) ServerResources(ctx context.Context, name string) (ResourceSpec
// user for two DIFFERENT ownerless servers serialize instead of both passing the
// gate (audit #4); the row is additionally taken FOR UPDATE so concurrent claims
// of the SAME server still resolve to exactly one winner.
//
// A claim starts the reaper's clock afresh: last_active_at moves to the claim
// and the pre-reap warnings clear. A world reaped before keeps its release time
// as last_active_at, so without the reset a new owner who configures it from
// the panel before anyone joins would lose it on the next reaper run, with no
// warning and no archive of their own.
func (p *PGRepo) ClaimServer(ctx context.Context, name, userID string) (bool, error) {
tx, err := p.db.BeginTx(ctx, nil)
if err != nil {
@@ -470,7 +476,8 @@ func (p *PGRepo) ClaimServer(ctx context.Context, name, userID string) (bool, er
}
res, err := tx.ExecContext(ctx,
`UPDATE servers SET owner_id = $2, claimed_at = now() WHERE name = $1 AND owner_id IS NULL AND deleted_at IS NULL`,
`UPDATE servers SET owner_id = $2, claimed_at = now(), last_active_at = now(), warned_3d_at = NULL, warned_1d_at = NULL
WHERE name = $1 AND owner_id IS NULL AND deleted_at IS NULL`,
name, userID)
if err != nil {
return false, err
+2
View File
@@ -244,6 +244,8 @@ type Repo interface {
// authoritative gate: a claim that would exceed a cap → ErrQuotaExceeded (403),
// and two concurrent claims by one user cannot both pass (audit #4).
// QuotaCheck remains the advisory pre-check for the handler's fast-path 403.
// A successful claim resets last_active_at to now and clears warned_*, so the
// reaper counts idleness from the claim.
ClaimServer(ctx context.Context, name, userID string) (bool, error)
// UserInAllowlist reports whether the user's linked UUID is on the server
// allowlist (spec §9.4).