Skip to content

perf(swarm): let a runtime create its services without resolving the image - #552

Open
antoinegg1 wants to merge 2 commits into
mainfrom
perf/swarm-no-resolve-image
Open

antoinegg1 wants to merge 2 commits into
mainfrom
perf/swarm-no-resolve-image

Conversation

@antoinegg1

Copy link
Copy Markdown
Contributor

Why

docker service create asks the image's registry for the image's digest before the manager
schedules the task. On a busy manager that is about 2.2 s per service; with
--no-resolve-image it is 0.03 s (measured on our swarm manager, the same command with and
without the flag). A runtime whose image every node already holds, or one pinned by digest,
gains nothing from the round trip. Our LOT trees create thousands of single-task services per
run (one manager resolved the tag 2,700 times in 11 h).

What

  • SwarmConfig.resolve_image: bool = True (hmz.coganchor.machines.swarm): False adds
    --no-resolve-image to docker service create; nothing else changes.
  • SwarmRuntime.resolve_image: bool = True (hmz.coganchor.machines.store): a swarm
    runtime's setting, passed on by the swarm driver (environing_swarm).
  • The settings loader (_typed) takes a boolean field as true or false only (it refused
    every boolean before; no runtime had one).
  • _fields leaves resolve_image out while it is True, so a runtime that keeps docker's
    way is written down byte for byte as before and an older Humanize still reads the file.
  • Docs: the swarm runtime's table (docs/reference/machines.md) and settings.md.

Behaviour

Default unchanged: the manager resolves the tag and pins the digest for every node. With
resolve_image: false each node runs the image it holds under that name and pulls it only
where it holds none, so nodes that hold different images under the same tag may run different
ones. That is the caller's choice; the docs say when it is safe (an image pinned by digest, or
the same image on every node).

Tests

  • tests/unit/coganchor/machines/test_swarm.py: the flag only when asked, before the image,
    and the command otherwise identical.
  • tests/unit/coganchor/machines/test_runtimes.py: default True and left out of held();
    false kept and read back; 0 and "no" refused.
  • tests/unit/runtime/flowing/test_environing_swarm.py: the runtime's setting reaches the
    service's config (both ways).

pytest tests/unit/coganchor/machines/test_swarm.py tests/unit/coganchor/machines/test_runtimes.py tests/unit/runtime/flowing/test_environing_swarm.py: 264 passed. ruff check and ruff format --check on the changed files and pyright on the whole project (as pre-commit runs it): clean.

🤖 Generated with Claude Code

…image

`docker service create` asks the image's registry for its digest before the
manager schedules the task: about 2.2 s a service on a busy manager (0.03 s
with `--no-resolve-image`), every time, for a tag every node already holds.

A swarm runtime may now say `resolve_image: false`: its services are created
with `--no-resolve-image`, each node running the image it holds under that
name and pulling it only where it holds none. The default stays docker's way
(the manager pins the digest), and a runtime that leaves the setting at its
default is written down exactly as before, so an older Humanize still reads
the settings file.

- SwarmConfig.resolve_image and SwarmRuntime.resolve_image (default True);
  the swarm driver passes the runtime's on.
- The settings loader takes a boolean field as true or false only.
- Docs: the swarm runtime's table and settings.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinegg1
antoinegg1 requested a review from futrime as a code owner November 2, 2026 12:10
The form has no row for it, and a runtime is made again from the form's rows, so
correcting a swarm saved with `resolve_image: false` wrote it back as true, and its
services were created resolving their image again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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