Repository navigation
Let only the wire write the Tx row: the driver's echo, not the send - #538
Merged
Merged
Conversation
This was referenced Oct 3, 2026
thebhef
force-pushed
the
task121-echo-row
branch
from
October 7, 2026 14:30
847eb28 to
5041e4d
Compare
thebhef
force-pushed
the
fix-plot-marker-refresh
branch
from
October 7, 2026 14:30
5465cd7 to
391ec5a
Compare
This was referenced Oct 8, 2026
thebhef
marked this pull request as ready for review
October 14, 2026 21:09
Owner
Author
thebhef
changed the base branch from
fix-plot-marker-refresh
to
graphite-base/538
October 14, 2026 23:28
A transmit used to append its Tx row the moment the session's channel accepted the frame, an answer that fails only when the channel is closed. Every consumer reads trace rows, so a dead bus (a pulled cable under RBS) kept showing healthy outgoing traffic in the trace, the plots, the per-message counts, fps.tx, the logger and saved captures. Now an accepted send appends nothing. The frame enters the trace when the bus carries it: the driver's post-transmission echo arrives on the ordinary receive path as a DIRECTION_TX frame and is ingested like any other. A frame the bus will not carry leaves no row and is not retried. The enqueue-refused row stays, marked Tx ✗, since there the queue did say no. - Sidecar: every python-can bus is opened with receive_own_messages (off only for listen-only). The shared interface fans the echo out to every session on the adapter as DIRECTION_TX (owner ruling: the sessions on one adapter are one node). The "sent=" tx stat is renamed queued_to_driver, which is what it counts. - cannet-python-wire: message_to_frame read Message.is_tx, which python-can does not have, so every echo would have mapped to Rx; it reads is_rx. - cannet-core SharedBus: the arbitration winner's frame is echoed to its originator as Tx, with the arbitration timestamp, only when it reached at least one recipient (none stays NoAcknowledger). So the in-process vbus and `cannet-server debug vbus` show a participant's own frames as Tx. Bridge ingress drops Tx frames: they are the far side's echo of the bridge's own egress, already carried here, and would otherwise reach every participant twice. - Python client: CannetBus follows python-can's convention. It takes receive_own_messages (default False) and drops the session's own echoes (is_rx False) unless asked for them. - GUI host: append_tx_row becomes append_refused_tx_row, called only on refusal. The manual-send IPC drops tx_confirm_index (its one UI caller ignores the return) and Sent becomes Accepted. The ingest path is unchanged. It already appends frames in their wire direction, and the ADR 0027 verifier already exempts Tx. The bus-health error tally now counts only Rx error frames, so the echo of an error frame we injected is not tallied as a fault, as before. Docs, corrected in place: ADR 0021 (fan-out, bridges, NoAck), ADR 0022 (echo is now normalised; the known unknown is gone), ADR 0027, ADR 0039 (plus a dated amendment; the bus-off premise is left for its own correction), README's transmit and adapter-unavailable passages, the perf README's tx rate, a Tx row entry in CONTEXT.md, and the proto's direction comment. Review: the bridge drop also stops a co-subscriber's transmits on a bridged adapter, and a bridged replay server's recorded Tx frames, from fanning in. fps.tx is now the echo rate, so a backend without echo support reads ~0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
thebhef
force-pushed
the
task121-echo-row
branch
from
October 14, 2026 23:33
5041e4d to
d53a702
Compare
This was referenced Oct 15, 2026
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.
A transmit used to append its Tx row the moment the session's channel
accepted the frame, an answer that fails only when the channel is
closed. Every consumer reads trace rows, so a dead bus (a pulled
cable under RBS) kept showing healthy outgoing traffic in the trace,
the plots, the per-message counts, fps.tx, the logger and saved
captures. Now an accepted send appends nothing. The frame enters the
trace when the bus carries it: the driver's post-transmission echo
arrives on the ordinary receive path as a DIRECTION_TX frame and is
ingested like any other. A frame the bus will not carry leaves no row
and is not retried. The enqueue-refused row stays, marked Tx ✗, since
there the queue did say no.
(off only for listen-only). The shared interface fans the echo out
to every session on the adapter as DIRECTION_TX (owner ruling: the
sessions on one adapter are one node). The "sent=" tx stat is
renamed queued_to_driver, which is what it counts.
python-can does not have, so every echo would have mapped to Rx; it
reads is_rx.
its originator as Tx, with the arbitration timestamp, only when it
reached at least one recipient (none stays NoAcknowledger). So the
in-process vbus and
cannet-server debug vbusshow a participant'sown frames as Tx. Bridge ingress drops Tx frames: they are the far
side's echo of the bridge's own egress, already carried here, and
would otherwise reach every participant twice.
receive_own_messages (default False) and drops the session's own
echoes (is_rx False) unless asked for them.
on refusal. The manual-send IPC drops tx_confirm_index (its one UI
caller ignores the return) and Sent becomes Accepted. The ingest
path is unchanged. It already appends frames in their wire
direction, and the ADR 0027 verifier already exempts Tx. The
bus-health error tally now counts only Rx error frames, so the echo
of an error frame we injected is not tallied as a fault, as before.
Docs, corrected in place: ADR 0021 (fan-out, bridges, NoAck), ADR 0022
(echo is now normalised; the known unknown is gone), ADR 0027, ADR
0039 (plus a dated amendment; the bus-off premise is left for its own
correction), README's transmit and adapter-unavailable passages, the
perf README's tx rate, a Tx row entry in CONTEXT.md, and the proto's
direction comment.
Review: the bridge drop also stops a co-subscriber's transmits on a
bridged adapter, and a bridged replay server's recorded Tx frames,
from fanning in. fps.tx is now the echo rate, so a backend without
echo support reads ~0.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com