feat: send over TCP instead of UDP - #8
Merged
Merged
Conversation
Contributor
Author
|
@coderabbitai pause |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Note Reviews pausedUse the following commands to manage reviews:
Use the checkboxes below for quick actions:
Comment |
✅ Action performedReviews paused. |
DavidCozens
force-pushed
the
stage-07-buffered
branch
from
August 16, 2026 21:48
6f107df to
a32b54b
Compare
A StreamSender over an lwIP TCP stream replaces the UDP sender, and the collector moves to 5601. Records are framed by octet count (RFC 6587), which is what a receiver expects on a stream transport. Flash +7,348 B (+544 on the previous stage) RAM +7,664 B (+180) Log stack +672 B (unchanged) Service +896 B (-56) TCP before TLS is deliberate. It is the smaller step — a stream, a connect and a framing rule, with no certificates in the picture — and it is what a later store-and-forward stage will spool onto. It also completes what the sequenceId started: the transport now detects loss where it happens, while the sequence only reveals it afterwards. The store is still the Null object, so a record whose send fails is reported but not kept. NullStore_Write rejects the record and NullStore_IsTransient says so, which is Service's cue to fall through to a direct send whose result it discards; the delivery-failed event still reaches the handler. The device therefore learns that delivery is failing without yet being able to do anything about it. The flash is small because the baseline already holds a real mTLS session, so lwIP's TCP code was in the image before this stage asked for it. What is charged here is the stream and the sender in front of it, and the 180 bytes of RAM are those two objects in SolidSyslog's static pool. The log stack does not move at all: a task that calls Log is unaffected by the transport underneath it. The service seam's high-water actually fell 56 bytes — this stream's send path measures shallower than the datagram's — but the seam keeps its allocation, so nothing is given back here. The stream takes a Sleep callback because a connect is not instantaneous and the library will not pick a blocking primitive on your behalf; one vTaskDelay is the whole of it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DavidCozens
force-pushed
the
stage-08-tcp
branch
from
August 16, 2026 21:48
4e877a9 to
e6bc53a
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.
UDP to TCP, by putting a
SolidSyslogStreamSenderover an lwIP TCP stream. The networkretransmits rather than dropping, and a send fails when the collector is gone instead of succeeding
into a void. Records are framed by octet count per RFC 6587, which is what a receiver expects on a
stream transport.
Taken with the sequence number, this completes the loss story: the transport detects loss where it
happens, and the sequence reveals afterwards anything the transport could not. It is also what
makes the delivery-failed and delivery-restored events from the error-handler stage meaningful.
The store is still the Null object, so a record whose send fails is reported but not kept. The
device learns that delivery is failing without yet being able to do anything about it; retaining
the record is the store stage's job.
TCP before TLS is deliberate. It is the smaller step — a stream, a connect and a framing rule, with
no certificates in the picture — and it is what a later store-and-forward stage will spool onto.
The stream takes a
Sleepcallback because a connect is not instantaneous and the library will notpick a blocking primitive on your behalf; one
vTaskDelayis the whole of it.When you need it. If the device must know that delivery is failing — to raise an alarm, to fall
back, to start storing. Over UDP it never finds out.