Skip to content

chore: simplify, modernize (Go 1.26), update deps#84

Merged
rustatian merged 5 commits into
masterfrom
chore/cleanup-modernize-deps
Jun 4, 2026
Merged

chore: simplify, modernize (Go 1.26), update deps#84
rustatian merged 5 commits into
masterfrom
chore/cleanup-modernize-deps

Conversation

@rustatian

@rustatian rustatian commented May 29, 2026

Copy link
Copy Markdown
Member

Applied fixes (S: 6, M: 1, R: 1)

Simplify (S)

  • Remove dead item.callback field — stored but never read
  • Drop redundant Store(0) on freshly-zeroed atomic.Uint64 fields (two sites in lock()/lockRead())
  • Drop redundant writerCount.Store(0) in the w==0 branch of lockRead
  • Simplify exists() wildcard branch: if A||B{return true};return falsereturn A||B
  • Remove unreachable if !ok block in updateTTL (the guard is always true at that point)
  • Drop redundant lockID param from the callback type (always equals captured id); replace goto loop with for{select{…;continue};break}

Modernize (M)

  • rpc.go: drop misleading stderr "errors" alias — no import conflict exists

Review / bug fix (R)

  • Fix inconsistency guards in lock() and lockRead(): &&|| at three sites (lines 170, 267, 493). The surrounding log message reads "should be zero writers and zero readers", confirming the check must fire when either count is non-zero, not only when both are.

Deps

go get -u all && go mod tidy produced no changes — all dependencies were already current.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed incorrect error handling in the RPC layer
    • Improved lock state consistency validation
  • Refactor

    • Optimized internal lock TTL handling and callback mechanisms
  • Tests

    • Added tests for lock acquisition following TTL expiry
    • Added tests for read-to-write lock promotion
    • Added tests for wildcard lock existence queries

- rpc.go: drop misleading `stderr` alias for stdlib errors (no import conflict)
- locker.go: remove dead `item.callback` field (stored but never read)
- locker.go: drop redundant `Store(0)` on freshly-zeroed atomic.Uint64 fields
- locker.go: drop redundant `writerCount.Store(0)` in w==0 branch of lockRead
- locker.go: fix inconsistency guards: `&&` → `||` (locker.go:170,267,493) — the
  error message "should be zero writers AND zero readers" makes the intent clear;
  the guard must fire when EITHER is non-zero, not only when both are
- locker.go: simplify exists() wildcard branch to `return A || B`
- locker.go: remove unreachable `if !ok` block in updateTTL (ok is always true
  at that point; the early-return on !ok precedes it)
- locker.go: drop redundant `lockID` param from callback type — it always equals
  the captured `id`; use the closure variable directly
- locker.go: replace `goto loop` with `for { select { … ; continue } ; break }`
Copilot AI review requested due to automatic review settings May 29, 2026 12:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR simplifies lock internals and updates a small RPC import alias cleanup while retaining the existing locking API behavior.

Changes:

  • Removes unused callback storage and redundant atomic zero stores.
  • Simplifies TTL callback control flow and wildcard existence checks.
  • Updates inconsistency checks from && to || in several lock acquisition paths.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
locker.go Simplifies lock bookkeeping, callback signatures, TTL update flow, and inconsistency checks.
rpc.go Replaces the aliased errors import with the standard import name.
Comments suppressed due to low confidence (1)

locker.go:171

  • This newly broadened inconsistency check returns without releasing resourceMu in this branch. With ||, a notification that leaves only one of the counters non-zero now takes this path and can leave the resource locked, causing subsequent operations on the resource to block; release the mutex before returning, as the other inconsistency checks do.
			if r.writerCount.Load() != 0 || r.readerCount.Load() != 0 {
				l.log.Error("inconsistent state, should be zero writers and zero readers",
					"resource", res,
					"id", id,
					"writers", r.writerCount.Load(),
					"readers", r.readerCount.Load())
				return false

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@rustatian, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 25 minutes and 29 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fa2f8f1e-2686-4f2c-ac91-9015c0e692ae

📥 Commits

Reviewing files that changed from the base of the PR and between f86a90f and 85ea9db.

📒 Files selected for processing (1)
  • tests/lock_test.go
📝 Walkthrough

Walkthrough

The PR refactors the lock callback contract to remove the lock ID parameter and updates all acquisition paths accordingly. The TTL timeout loop is converted from goto-based to for-select structure. A bug in the errors package import is fixed, and test coverage is added for TTL expiry, read-to-write promotion, and wildcard exists behavior.

Changes

Lock callback refactoring and TTL loop improvements

Layer / File(s) Summary
Callback contract definition and TTL loop refactoring
locker.go
The callback function type removes the id parameter and captures lock context via closure. makeLockCallback refactors the TTL loop from labeled goto to for { select { ... } } with explicit breaks for stop/expiration, while maintaining dynamic TTL updates via updateTTLCh.
Write lock acquisition path updates
locker.go
The lock() function updates all paths to store only stopCh and updateTTLCh in per-lock items and invoke callbacks with (notificationCh, stopCh). Inconsistency guards are updated to treat any non-zero writer or reader count as problematic.
Read lock acquisition and reader-promotion paths
locker.go
The lockRead() function and writer-after-reader code paths adopt the new callback signature and item structure. Inconsistency guards in reader-wait and reader-promotion branches now check for any non-zero counter. Writer acquisition after reader notification invokes callbacks with the updated signature.
Helper method improvements
locker.go
The exists() method simplifies the wildcard case to a single boolean expression checking for any writers or readers.
Error handling fix
rpc.go
The errors standard library import is corrected and errEmptyID initialization is updated to use errors.New(...).
Test coverage for TTL expiry, lock promotion, and wildcard exists
tests/lock_test.go
A startLockContainer() helper initializes the lock plugin container. New tests validate TTL-driven expiry and second-writer acquisition, read-to-write lock promotion, and the wildcard exists(resource, "*") behavior including cleanup.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • roadrunner-server/lock#77: Both PRs modify locker.go to update resource owner ID assignments. PR #77 removes the ptrTo helper while this PR refactors the lock callback contract.

Suggested labels

bug

Suggested reviewers

  • wolfy-j

Poem

A rabbit hops through locks with glee, 🐰
Callbacks now capture, wild and free,
No ID passed, just channels flow,
TTL loops let timeouts go,
Tests ensure promotion's right!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and does not clearly communicate the primary change; it uses generic terms like 'chore: simplify, modernize' that don't convey meaningful information about the specific changeset beyond mentioning Go 1.26 and deps. Provide a more specific title that highlights the main technical change, such as 'refactor: remove dead callback field and simplify lock loop logic' or similar to better describe the core modifications.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/cleanup-modernize-deps

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.41667% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.15%. Comparing base (b448c43) to head (85ea9db).

Files with missing lines Patch % Lines
locker.go 85.41% 3 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #84      +/-   ##
==========================================
+ Coverage   76.98%   77.15%   +0.16%     
==========================================
  Files           4        4              
  Lines         691      674      -17     
==========================================
- Hits          532      520      -12     
+ Misses        136      135       -1     
+ Partials       23       19       -4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rustatian rustatian self-assigned this Jun 3, 2026
rustatian added 2 commits June 4, 2026 12:54
The writer-wait inconsistency check returned without releasing resourceMu, unlike the sibling checks in the promotion arm and lockRead. An inconsistent state would leak the operation+release semaphores and wedge the resource; release the mutex before returning, matching the siblings.
These lock() branches were only reached by the random fuzz test, so their coverage flickered between runs and dropped on this branch. Add three deterministic tests (driven through the RPC client) plus a small container helper, restoring patch/project coverage.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/lock_test.go`:
- Around line 706-712: The goroutine started via wg.Go currently calls
require.NoError(t, e.Error...) which is unsafe; change it to propagate errors to
the main test goroutine (or use testify/assert from the main goroutine) instead
of calling t.FailNow() from a non-test goroutine: e.g., have the goroutine send
any received error on a dedicated error channel (or set a shared
atomic/variable) and then in the main test goroutine after wg.Wait() or via
select on that error channel assert/require the error there; update the code
around wg.Go, the ch receive case, and the stop handling to forward e.Error
rather than invoking require inside the goroutine.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 23162dda-2264-4881-b5f2-c19dac1bd233

📥 Commits

Reviewing files that changed from the base of the PR and between b448c43 and f86a90f.

📒 Files selected for processing (3)
  • locker.go
  • rpc.go
  • tests/lock_test.go

Comment thread tests/lock_test.go
rustatian added 2 commits June 4, 2026 13:45
require.NoError calls t.FailNow()/runtime.Goexit, which is only safe on the test goroutine; from the container error-watch goroutine it can panic or leak. Use assert.NoError, which records the failure without FailNow.
lock() self-bounds to its wait timeout, so the goroutine + buffered channel + 15s select watchdog were redundant; a plain blocking call exercises the same wait-then-acquire arm and matches the file's idiom.
@rustatian rustatian merged commit b8816f6 into master Jun 4, 2026
9 checks passed
@rustatian rustatian deleted the chore/cleanup-modernize-deps branch June 4, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants