56 lines
1.1 KiB
Go
56 lines
1.1 KiB
Go
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()
|
|
}
|