Finish landing ioxide.timer: pack it, and give it a Playground sample - #216
Merged
Conversation
The pack steps are one per project and hand-written, so a new package is not picked up by adding it to the solution - ioxide.slnx builds it and the release then shipped everything except it. Which is what happened to 0.7.211: the SubmitTimeout in core went out, the client over it did not. Checked the rest against the tree while here; every project carrying a PackageId now has a pack step.
ioxide.timer shipped without one. Every other package has a Playground sample that is a complete server, is a row in bench/samples.tsv, and is a pane on the site generated from that same file - so a package without one is a package a reader has to learn from its doc comments. Clients/Timer answers GET /<ms> after that many milliseconds. It holds ONE RingTimer for the connection and re-arms it per request, which is the shape a caller is meant to copy and the one constraint worth knowing: a timer carries a single wait at a time, so something waiting on several deadlines at once wants a timer each. It also shows what a caller would otherwise get wrong - an expired timeout completes with -ETIME, so the check is RingTimer.Expired and not result >= 0. The useTaskDelay knob runs the same server with Task.Delay in place of the ring, so the hop that costs is measurable rather than asserted, the way Tcp/Hop is runnable next to Tcp/Raw. The delay comes from the request, so it is clamped; an unbounded one would let a client hold a connection all day. Registered as h1 on :8080 with PLAYGROUND_DELAY_MS=0, which prices the wait itself against Tcp/Raw rather than measuring a sleep. Also here: README's client package table was missing ioxide.timer entirely, and the site's example panes are regenerated - only the new one changed, the rest were already in sync. Verified against the running sample: / waits the default 25ms, /50 waits 50ms, a non-numeric path falls back, the ceiling holds at 60s, and three keep-alive requests on one connection each wait their own 40ms.
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.
ioxide.timerlanded in #213 but did not land completely: CI never packed it, and it has no Playground sample. Both here.ci: pack ioxide.timerThe pack steps in the release workflow are one per project and hand-written, so adding a project to
ioxide.slnxbuilds it but does not ship it. That is what happened to 0.7.211 — theSubmitTimeoutin core went out, the client over it did not. Checked the rest against the tree while there; every project carrying aPackageIdnow has a pack step.No version change is needed:
ioxide.timer0.7.211 was never published, so the next release picks it up at the version its siblings already carry.Playground/Clients/TimerEvery other package has a sample that is a complete server, a row in
bench/samples.tsv, and a pane on the site generated from that same file. A package without one is a package a reader has to learn from its doc comments.GET /<ms>answers after that many milliseconds:It holds one
RingTimerfor the connection and re-arms it per request. That is the shape a caller is meant to copy, and it carries the one constraint worth knowing: a timer holds a singleRingOpSource, so it carries one wait at a time — something waiting on several deadlines at once wants a timer each.It also shows the thing a caller would otherwise get wrong. An expired timeout completes with -ETIME, which is io_uring reporting success, so the check is
RingTimer.Expired(result)and notresult >= 0. The sample writeserrno Ninto the body when it is anything else, so a mistake there would be visible rather than silent.The
useTaskDelayknob runs the same server withTask.Delayin place of the ring — same response, only the wait changes — so the off-reactor hop it costs is measurable rather than asserted, the wayTcp/Hopis runnable next toTcp/Raw. The delay comes from the request, so it is clamped; an unbounded one would let a client hold a connection all day.Registered as
h1on:8080withPLAYGROUND_DELAY_MS=0, which prices the wait itself againstTcp/Rawrather than measuring a sleep.bench/any.sh --listreports it runnable.Also here
README.md's client package table was missingioxide.timerentirely. Added.The site's example panes are regenerated from the samples, so
scripts/gen-docs-panes.pygains thetimerentry anddocs/index.htmlgains the tab, the pane and its three CSS rules. Only the new pane changed — the rest were already in sync, and both generators report "already up to date" on a second run.Verified
Against the running sample:
/waits the default 25ms,/50waits 50ms,/200waits 200ms, a non-numeric path falls back, the ceiling holds at 60s, and three keep-alive requests on one connection each wait their own 40ms rather than sharing a deadline. ThePLAYGROUND_TASK_DELAY=1arm serves identically. Full solution builds clean, 0 warnings.