Skip to content

Memoize Connection#rootless? correctly - #608

Open
tas50 wants to merge 1 commit into
upserve:masterfrom
tas50:fix-rootless-memoization
Open

Memoize Connection#rootless? correctly#608
tas50 wants to merge 1 commit into
upserve:masterfrom
tas50:fix-rootless-memoization

Conversation

@tas50

@tas50 tas50 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

@rootless ||= (info["Rootless"] == true) cannot cache a false result — ||= re-evaluates whenever the memo is false or nil. #info is not memoized either, so every call against a non-rootless daemon issued a fresh /info request.

Measured against a real daemon before the fix:

5x Docker.rootless? -> 5 /info requests

After:

5x Docker.rootless? -> 1 /info request

The fix

Test for the ivar with defined? rather than relying on truthiness.

Also

Adds a guard spec for #podman?. It uses the same ||= idiom, but is backed by the memoized #version, so it already makes only one /version request. The spec pins that so it cannot regress into the same trap. No behaviour change there.

Verification

The new only queries /info once spec was confirmed to fail before the change:

expected: 1 time with arguments: ("/info")
received: 2 times with arguments: ("/info")

connection_spec goes from 13 examples to 17, with no new failures.

Note on CI

The one failing example on this branch (its(:resource)) is pre-existing on master — I confirmed master alone reports 13 examples, 1 failure for the same spec. It is fixed by #605, and CI here will stay red until that lands.

`@rootless ||= (info['Rootless'] == true)` cannot cache a false result, and
#info is not memoized, so every call against a non-rootless daemon issued a
fresh /info request:

    5x Docker.rootless? -> 5 /info requests

Test for the ivar with defined? instead. Every daemon that is not rootless is
now one request rather than one per call:

    5x Docker.rootless? -> 1 /info request

Also adds a guard for #podman?, which uses the same `||=` idiom but is already
backed by the memoized #version, so it makes a single /version request. The spec
pins that behaviour so it does not regress into the same trap.
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.

1 participant