Skip to content

LocalDiscovery sizes its address space at capacity * 4 bytes, yielding capacity / 4 slots #299

Description

@conradbzura

Description

LocalDiscovery(capacity=N) does not cap worker registrations at N. The constructor docstring calls capacity the "Maximum number of workers that can be registered simultaneously. Defaults to 128." — the implementation delivers neither that number nor any stable number: the segment is sized at capacity * 4 bytes against 16-byte slots, and POSIX page rounding then inflates whatever was requested to a full page. The default capacity=128 requests 512 bytes and receives 16 KiB on Apple Silicon macOS — roughly 1024 slots. Any capacity below a page is ignored entirely.

Expected behavior

capacity enforces the documented cap — size the segment at capacity * REF_WIDTH and bound the slot scan to capacity — or the docstring describes the page-granular reality. Pick one; the current state documents a limit the code cannot enforce.

Root cause

Two independent errors compound in src/wool/runtime/discovery/local.py:

  1. The sizing arithmetic uses the wrong width (__enter__, line ~224). Slots are REF_WIDTH = 16 bytes, so the requested size yields capacity / 4 slots:

    size = self._capacity * 4
    
  2. The slot scans are bounded by the mapped buffer, not by capacity (Publisher._add, _drop, _update, and the subscriber scan). Every loop walks the full mapping, so whatever the OS actually maps — always at least a page — becomes the effective capacity:

    for i in range(0, len(address_space.buf), REF_WIDTH):
    

Page rounding makes exhaustion unreachable through the public API; test_publish_to_full_address_space_raises_runtime_error fills the buffer directly and carries a comment referencing this issue — adjust it when fixing the sizing.

Adjacent oddity from the same audit: Publisher._add does not check for an existing registration, so publishing worker-added twice for one UID occupies two slots sharing one block, and a single drop leaves the worker discoverable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions