thread-master/backend/internal/library/copymission/matrix_lock.go

56 lines
1.1 KiB
Go
Raw Permalink Normal View History

2026-06-28 08:28:42 +00:00
package copymission
import (
"context"
"errors"
"fmt"
"strings"
"time"
goredis "github.com/redis/go-redis/v9"
)
const matrixReplaceLockTTL = 10 * time.Minute
// WithMatrixReplaceLock serializes matrix draft replacement for one copy mission.
func WithMatrixReplaceLock(
ctx context.Context,
redis *goredis.Client,
tenantID, missionID, holder string,
fn func() error,
) error {
if fn == nil {
return nil
}
tenantID = strings.TrimSpace(tenantID)
missionID = strings.TrimSpace(missionID)
holder = strings.TrimSpace(holder)
if tenantID == "" || missionID == "" {
return fn()
}
if redis == nil {
return fn()
}
key := fmt.Sprintf("haixun:copy_matrix:%s:%s", tenantID, missionID)
if holder == "" {
holder = "matrix-replace"
}
ok, err := redis.SetNX(ctx, key, holder, matrixReplaceLockTTL).Result()
if err != nil {
return err
}
if !ok {
return errors.New("copy matrix replacement already in progress")
}
defer func() {
script := `
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
end
return 0
`
_ = redis.Eval(ctx, script, []string{key}, holder).Err()
}()
return fn()
}