From 381058b0979fad1037bb0bc8192c66df52c5d293 Mon Sep 17 00:00:00 2001 From: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> Date: Tue, 26 May 2026 15:17:42 +0200 Subject: [PATCH] refactor(posixage/flock): tidy tryLock structure and test name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up follow-ups to the ctx-driven lock-wait refactor (#523): - Collapse the two sequential ctx.Err() checks into a single early-return gate before stale recovery. Equivalent behavior with a more linear read; the ctx is also checked again inside retryLock via backoff.Retry so the explicit re-check after recovery was redundant. - Clear fl immediately after calling recoverStaleLock so the outer close-on-error defer does not double-close the file handle (which recoverStaleLock already closes via its own defer). - Rename the test "caller context can wait past former default timeout" to "acquires lock when holder releases before ctx deadline" — the former-default-timeout reference no longer applies. Co-Authored-By: Claude Opus 4.7 (1M context) --- store/posixage/internal/flock/flock.go | 23 +++++++++++---------- store/posixage/internal/flock/flock_test.go | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/store/posixage/internal/flock/flock.go b/store/posixage/internal/flock/flock.go index 19c24403..db995610 100644 --- a/store/posixage/internal/flock/flock.go +++ b/store/posixage/internal/flock/flock.go @@ -77,20 +77,21 @@ func tryLock(ctx context.Context, root *os.Root, exclusive bool) (UnlockFunc, er } err = errors.Join(ErrLockUnsuccessful, err) - if ctx.Err() == nil { - if recoverErr := recoverStaleLock(root, fl); recoverErr != nil && !errors.Is(recoverErr, errRecoverLock) { - return nil, errors.Join(err, recoverErr) - } - fl = nil + if ctx.Err() != nil { + return nil, errors.Join(err, ctx.Err()) + } - fl, err = openFile(root) - if err != nil { - return nil, err - } + // recoverStaleLock always closes fl; clear our reference so the deferred + // close-on-error cleanup does not double-close it. + recoverErr := recoverStaleLock(root, fl) + fl = nil + if recoverErr != nil && !errors.Is(recoverErr, errRecoverLock) { + return nil, errors.Join(err, recoverErr) } - if ctx.Err() != nil { - return nil, errors.Join(err, ctx.Err()) + fl, err = openFile(root) + if err != nil { + return nil, err } err = retryLock(ctx, fl, exclusive) diff --git a/store/posixage/internal/flock/flock_test.go b/store/posixage/internal/flock/flock_test.go index 66239315..789e8252 100644 --- a/store/posixage/internal/flock/flock_test.go +++ b/store/posixage/internal/flock/flock_test.go @@ -122,7 +122,7 @@ func TestFlock(t *testing.T) { require.NoError(t, unlock()) }) - t.Run("caller context can wait past former default timeout", func(t *testing.T) { + t.Run("acquires lock when holder releases before ctx deadline", func(t *testing.T) { root, err := os.OpenRoot(t.TempDir()) require.NoError(t, err) t.Cleanup(func() {