What prompted this
Building a large graph on the streamlib-doom demo hit three separate walls that all trace back to one fact: an iceoryx2 service's participant counts are fixed when the service is created and verified on every reopen, and our services are created by whatever link happens to open first.
- A destination cannot hold more than 8 inbound links.
MAX_INBOUND_LINKS_PER_DESTINATION is the max_notifiers the destination-keyed notify service is created with. The console pane compositor hit this twice; the second time it changed the design, because an event feed had to poll HTTP rather than take a link that had nowhere to go.
tap cannot attach to an output nothing consumes. Tap is a reopen of an existing service onto a reserved subscriber slot, by design — runtime/streamlib-engine/src/core/runtime/tap.rs says so in its module doc. An output port with no destinations has no service in existence, so there is nothing to reopen. Proving a processor was alive cost a four-minute timeout in a setup script until it was special-cased to use that processor's own HTTP endpoint instead.
- Connection order decides the sizing, so which links are possible later depends on what attached first.
The owner's expectation, stated plainly, is that a tap should work on any channel at any time.
Upstream does not solve it
We are on iceoryx2 0.8.1; 0.9.3 is current. The 0.9.0 release notes contain no change to max_subscribers, max_notifiers, service resizing, dynamic participant counts, or reopening with a different configuration. The "resizable data segments" work in that release is payload memory, not participant slots, and will read like the answer without being it.
Separately: the 0.8.1 → 0.9.x bump looks unusually cheap for us. Of its ten breaking changes we use none — UnableToDeliverStrategy, DegradationCallback, service_id, NodeId, creation_timeout and iceoryx2_tunnel have zero occurrences in our tree; only allocation_strategy appears, twice. Two deadlock fixes and a chunk-leak fix ride along. That is hygiene, not a fix for this, and belongs in its own ticket.
The candidate answer, and why it needs a decision first
Open a source's output channel at setup with the full reserved sizing, rather than sizing it from the destinations that exist when the first link compiles. Tap then works on any port at any time, and the cap stops depending on connection order.
This is a change to how the engine sizes every channel, so it is docs/plan/ARCHITECTURE.md's call and not a ticket's. Filing as research to establish the facts a decision needs.
What to establish
- What a reserved slot actually costs. Measure it, do not reason about it.
open_or_create_service asks for max_publishers(1), max_subscribers(N) and subscriber_max_buffer_size(RING_DEPTH = 16). Establish the shared-memory delta per additional subscriber slot and per notifier slot, and whether the publisher's data segment grows with the subscriber count. Our bags are [u8] slices carrying surface descriptors rather than pixels, so the payload is small, but that should be measured rather than assumed.
- Whether pre-sizing every channel at the maximum is affordable for a graph the size of the doom console — 25 to 29 processors, roughly 38 links — and for a plausibly larger one.
- Whether the cap should rise at the same time. 8 predates how much live splicing the graph now does. If a slot is cheap, the question is what number is right, not whether to keep 8.
- What breaks if a service is created before any link exists. In particular whether a later link's open still validates, and what happens to a source whose output nobody ever consumes.
- Whether iceoryx2 offers any escape hatch we are not using — a second service, a re-create path that does not disturb attached participants, or a different messaging pattern for the notify service.
Not in scope
Implementation. This ticket ends in a recommendation with numbers behind it, for an /align decision.
Found while building github.com/tatolab/streamlib-doom.
What prompted this
Building a large graph on the streamlib-doom demo hit three separate walls that all trace back to one fact: an iceoryx2 service's participant counts are fixed when the service is created and verified on every reopen, and our services are created by whatever link happens to open first.
MAX_INBOUND_LINKS_PER_DESTINATIONis themax_notifiersthe destination-keyed notify service is created with. The console pane compositor hit this twice; the second time it changed the design, because an event feed had to poll HTTP rather than take a link that had nowhere to go.tapcannot attach to an output nothing consumes. Tap is a reopen of an existing service onto a reserved subscriber slot, by design —runtime/streamlib-engine/src/core/runtime/tap.rssays so in its module doc. An output port with no destinations has no service in existence, so there is nothing to reopen. Proving a processor was alive cost a four-minute timeout in a setup script until it was special-cased to use that processor's own HTTP endpoint instead.The owner's expectation, stated plainly, is that a tap should work on any channel at any time.
Upstream does not solve it
We are on iceoryx2 0.8.1; 0.9.3 is current. The 0.9.0 release notes contain no change to
max_subscribers,max_notifiers, service resizing, dynamic participant counts, or reopening with a different configuration. The "resizable data segments" work in that release is payload memory, not participant slots, and will read like the answer without being it.Separately: the 0.8.1 → 0.9.x bump looks unusually cheap for us. Of its ten breaking changes we use none —
UnableToDeliverStrategy,DegradationCallback,service_id,NodeId,creation_timeoutandiceoryx2_tunnelhave zero occurrences in our tree; onlyallocation_strategyappears, twice. Two deadlock fixes and a chunk-leak fix ride along. That is hygiene, not a fix for this, and belongs in its own ticket.The candidate answer, and why it needs a decision first
Open a source's output channel at
setupwith the full reserved sizing, rather than sizing it from the destinations that exist when the first link compiles. Tap then works on any port at any time, and the cap stops depending on connection order.This is a change to how the engine sizes every channel, so it is
docs/plan/ARCHITECTURE.md's call and not a ticket's. Filing as research to establish the facts a decision needs.What to establish
open_or_create_serviceasks formax_publishers(1),max_subscribers(N)andsubscriber_max_buffer_size(RING_DEPTH = 16). Establish the shared-memory delta per additional subscriber slot and per notifier slot, and whether the publisher's data segment grows with the subscriber count. Our bags are[u8]slices carrying surface descriptors rather than pixels, so the payload is small, but that should be measured rather than assumed.Not in scope
Implementation. This ticket ends in a recommendation with numbers behind it, for an
/aligndecision.Found while building github.com/tatolab/streamlib-doom.