Files
zero/internal/oauth/lock.go
KRATOS 6fe0d1edcd fix(lockutil): use kernel-held advisory locks (#950)
* fix(lockutil): use kernel-held advisory locks

* fix(lockutil): harden cross-platform lock files

* test(lockutil): require one concurrent holder
2026-08-25 21:20:18 +08:00

40 lines
1.0 KiB
Go

package oauth
import (
"errors"
"fmt"
"os"
"path/filepath"
"time"
"github.com/Gitlawb/zero/internal/lockutil"
)
const fileLockTimeout = 5 * time.Second
// acquireFileLock takes a cross-process advisory lock through a stable lock
// file. It retries with a short backoff until a timeout. Kernel lock lifetime
// provides crash recovery, so the path is never renamed or removed.
func acquireFileLock(lockPath string, now func() time.Time) (func(), error) {
if now == nil {
now = time.Now
}
if err := os.MkdirAll(filepath.Dir(lockPath), 0o700); err != nil {
return nil, err
}
deadline := now().Add(fileLockTimeout)
for {
lock, err := lockutil.TryAcquireFileLock(lockPath)
if err == nil {
return func() { _ = lock.Release() }, nil
}
if !errors.Is(err, lockutil.ErrLockHeld) {
return nil, fmt.Errorf("oauth: acquire token lock: %w", err)
}
if now().After(deadline) {
return nil, fmt.Errorf("oauth: timed out acquiring token lock %s", filepath.Base(lockPath))
}
time.Sleep(10 * time.Millisecond)
}
}