Repository navigation
Conversation
zbus can't write several messages to a socket in one go yet, so busd writes each message that it forwards to a client with a system call of its own. z-galaxy/zbus#2078 asks for `Connection::send_all`, which does that, and the `ccr-fd1ce738-0xtuf0` branch of zeenix/zbus adds it, so build on its commit until a release has it. As for zruntime, the commit takes the place of the release through a patch of crates.io's zbus, so that the tests, which depend on zbus too, build on it as well. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
The task that serves a peer forwarded its messages one at a time, and the send of each to a client wrote it to the client's socket with a system call of its own, however many messages of the peer were there already for the bus to forward. The task now takes the messages that the peer sent after the one that it waits for, as far as they are there already, up to 16 of them, and ending with the one that brings them to 16 KiB, and forwards them as a batch: it picks the recipients of all of them under one hold of the locks, and sends each recipient its messages of the batch in one go, with `Connection::send_all`, which writes several small messages with each system call, and a big one on its own. It does the same with the messages of the bus itself. A peer that waits for each reply sends batches of one message, which the bus still forwards for little more than before. It looks for more messages by polling the stream of the peer with the waker of its task, which the stream keeps for the wait for the next batch if it has none. And it lends each recipient its messages out of the batch where they are a run of it, as those of a batch of one message are, and only looks recipients up once a second message comes. Where a connection calls itself through the bus 1000 times, then 20 connections do at once, the bus runs 1.4% more instructions than before, as callgrind counts them. As before, the task sends to all the recipients at once, each recipient gets the messages of a peer in the order that the peer sent them, and the task goes on to the next batch once each recipient has taken its messages, or been disconnected. A recipient may now get a message of a batch before another recipient gets an earlier one, which the order of the messages of each peer to each recipient never ruled out. The time limit of a client now covers the messages that it gets in one go, rather than each message. It covers the wait for the other messages on their way to the client as well, so the bound on the bytes of a batch is low: a client has to take less than 16 KiB more within it than the last of those messages alone. A client that didn't negotiate passing file descriptors still gets the messages without any: zbus turns the messages down before it writes any of them, and the bus sends them again without those that carry file descriptors. A new test has a client that takes no file descriptors get a message with one between two without, in one batch, and checks that it gets the two. The measurements of it are in dbus-bench's results/2026-10-24-busd-batched-sends-xeon-4vcpu.md. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
The bus forwards the messages of each peer in batches, which end with the message that brings them to 16 KiB or more, and the commit of zbus that it built on wrote up to 16 messages with each system call, but ended each write before the message that would take it past 16 KiB. A batch that went past 16 KiB took two writes to a recipient that got all of it, the last message on its own, however small: the signals of 1,172 bytes of dbus-bench went 14 to a batch, and 13 and then 1 to a write. The commit of the ccr-fd1ce738-0xtuf0 branch of zeenix/zbus that this builds on ends a write with the message that brings it to 16 KiB or more instead, as the bus ends a batch, so that a recipient gets the messages of a batch with one write, unless one of them after the first carries file descriptors. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
This was referenced Oct 25, 2026
The branch of z-galaxy/zbus#2079, which adds `Connection::send_all`, and which the bus builds on until a release of zbus has it, is now rebased onto zbus's main branch. That brings in fixes to the arguments that `#[interface]` takes, and to the book, which the bus does not depend on. This builds on the new head of the branch, and names the pull request in the comment on the patch, rather than the branch. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
`stalled_subscribers` checks that clients that stop reading, which the same signals go to, hold those signals up for the time limit of the bus all together, rather than for the time limit each. It timed them from the start of a flood of 512 signals of 4 KiB until it saw the last of them go, which it only looked for once all of the flood was sent. So it counted the rest of the flood as well, which the bus forwards after the stalled clients are gone, and which took over 300 ms on CI, where every test logs all that it does. Besides, the bus can wait twice: the sockets of the stalled clients that connected first hold a few more of the bus's signals from before the flood, about the clients after them, so they stop taking it a signal or so sooner than the others, which the bus then waits on for a time limit of their own. With both, the test took 853 and 879 ms on CI on busd's main branch, beyond the 800 ms that it allows: four time limits of 200 ms. Locally, with trace logs and the other tests of the file running alongside, it failed 3 times in 12. Time the stalled clients as they go, while the flood goes on. Under the same conditions, the test passed 50 times in 50, taking 537 to 599 ms. Assisted-by: Claude Opus 5.5 (claude-opus-5-5)
zeenix
force-pushed
the
ccr-fd1ce738-0xtuf0
branch
from
October 25, 2026 00:54
01d5ed5 to
c087d05
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bus forwards the messages of each peer one at a time, and writes each of them to a client's socket with a system call of its own, however many messages of the peer are there already. This forwards them in batches instead, with zbus's new
Connection::send_all(z-galaxy/zbus#2079):SEND_TIMEOUT, now covers the messages that a client gets in one go, as well as the wait for those on their way to it, so a batch ends at 16 KiB: a client has to take less than 16 KiB more within it than the last of those messages alone.send_all. The earlier 📌 commits pinned the commits of that branch that the measurements below were made with.stalled_subscribers, which fails on CI on the main branch too, times the disconnections of the stalled clients while the flood goes on, rather than once all of it is sent. On CI, where every test logs all that it does, the rest of the flood took over 300 ms, and the test 853 ms on the main branch, beyond the 800 ms that it allows.Measurements
On a 4-vCPU Xeon VM, against busd's main branch, its queue for each client before it, dbus-broker and dbus-daemon, with dbus-bench's clients of the signals and of the latencies' fan-out running each subscriber on a thread of its own, as processes of their own would (results):
On a Ryzen 7 7840U, with dbus-bench's earlier clients, which ran all subscribers on one thread (results), the burst and the broadcast were 6.9% and 6.7% faster than with busd's main branch, with 31.7% less CPU time of the bus on the signals, and 48.3% less system time. A run with the threaded clients there is to come.
Costs
Generated by Claude Opus 5.5.