Skip to content

feat(isotp)!: let IIsoTpChannel.SettleAsync be cancelled with a CancellationToken - #244

Merged
dborgards merged 2 commits into
mainfrom
feat/isotp-settleasync-cancellation
Sep 30, 2026
Merged

dborgards merged 2 commits into
mainfrom
feat/isotp-settleasync-cancellation

Conversation

@dborgards

Copy link
Copy Markdown
Owner

What does this change?

IIsoTpChannel.SettleAsync() waits for the channel's actor to take everything queued so far, and had no way to give up on that wait: a caller whose own deadline had passed, or whose operation was cancelled, stayed behind whatever the actor was busy with. It now takes an optional CancellationToken and passes it to the actor's PostAsync, which since #242 withdraws the wait while it is still queued.

The token ends the wait, not the settling. What the demux had buffered has been handed to the actor by then and is handled as usual, so cancelling never leaves a half-drained subscription behind.

The UDS client's own SettleAsync calls keep the default token on purpose. They settle at a deadline decision ("is a response there, was there a 0x78"), and letting a caller's cancellation abort the settle would change what that decision sees. That is a behaviour question of its own and not part of this change.

This is the second of the two interface members found while going through checklist item 4 of ADR 0001 (API baselines reviewed as a whole before the freeze); the first was PostAsync in #242. The window before the v1.3.0 tag is the last point where an interface member can change without a major version, so the signature is replaced, not overloaded and not shadowed with [Obsolete].

Type of change

  • feat — new behaviour (minor release)
  • fix / perf — bug or performance fix (patch release)
  • docs / test / refactor / chore / ci — no release
  • Breaking change (! in the title, plus a BREAKING CHANGE: footer explaining the migration)

The commit is a feat with ! and a BREAKING CHANGE: footer in its message. While the ADR window is open, breaking maps to minor in .releaserc.json.

Checklist

  • dotnet build CanKit.Pro.sln -c Release succeeds (run with -p:CI=true, 0 warnings)
  • dotnet test CanKit.Pro.sln -c Release passes (run with --framework net10.0: 1385 passed; the net48 leg was not run locally)
  • Public API changes are documented with XML comments
  • New behaviour is covered by a test (three tests in IsoTpChannelIntegrationTests)
  • The requirement or ADR this relates to is referenced (ADR 0001)

Also run locally: dotnet format --verify-no-changes (clean) and dotnet pack with eng/verify-packages.py (9 packages). The IsoTp approval baseline was taken from the generated .received.txt; its diff is exactly the one changed signature line.

The IIsoTpChannel test double in UdsExpiredDeadlineTests, the arc42 class diagram and the IsoTp README follow the new signature.

Mutation check

Not passing the token on to PostAsync (_actor.PostAsync(() => { })) makes both cancellation tests fail: the already-cancelled one fails at once, the one that cancels while the actor is busy fails after its 5-second bound because the settle stays pending until the actor is released. With the token passed on, all four Settle_* tests pass. The third test, a live token behaving like none, is a parity check and is not expected to catch that mutation.

Not covered by a test: the two early returns that ignore the token (channel already disposed, and a call made from the channel's own actor). Both complete at once by design.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UWRpkQzKkNDYz3WiNgWvWU


Generated by Claude Code

…llationToken

SettleAsync waits for the channel's actor to take everything queued so far, and
had no way to give up on that wait: a caller whose own deadline had passed, or
whose operation was cancelled, stayed behind whatever the actor was busy with.
It now takes an optional CancellationToken and hands it to the actor's
PostAsync, which withdraws the wait while it is still queued.

The token ends the wait, not the settling: what the demux had buffered has been
handed to the actor by then and is handled as usual.

The ADR window before 1.3.0 is the last point where an interface member can be
changed without a major version, so the signature is replaced rather than
overloaded next to the old one. The UDS client's own calls keep the default
token: they settle at a deadline decision, and letting a caller's cancellation
abort that would change what it decides.

BREAKING CHANGE: IIsoTpChannel.SettleAsync gained a CancellationToken
parameter. Callers compile unchanged; implementers of IIsoTpChannel and code
compiled against 1.2.x must be rebuilt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWRpkQzKkNDYz3WiNgWvWU
@cursor

cursor Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Breaking public interface change before v1.3.0 API freeze; runtime behavior only affects callers that pass a token, but any IIsoTpChannel implementer must update.

Overview
Breaking change: IIsoTpChannel.SettleAsync now accepts an optional CancellationToken (signature replace, not overload). Callers whose own deadline or cancellation fired can stop waiting for the channel actor to catch up instead of staying queued behind unrelated actor work.

IsoTpChannel still pumps the demux subscription first, then completes via _actor.PostAsync with the token passed through (same cancellable wait as PostAsync from #242). Cancellation ends the wait only: buffered frames are already posted to the actor and continue processing normally.

XML docs, IsoTp README, and arc42 were updated for that contract. Three integration tests cover already-cancelled tokens, cancel while the actor is busy, and parity with a live token. API approval baseline and the UDS test stub were updated; production UDS SettleAsync calls keep the default token so deadline decisions are unchanged.

Reviewed by Cursor Bugbot for commit 0c74981. Bugbot is set up for automated code reviews on this repo. Configure here.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T04:25:45.648957Z 3b9546f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@codecov

codecov Bot commented Sep 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@dborgards
dborgards merged commit 76a030f into main Sep 30, 2026
14 checks passed
@dborgards
dborgards deleted the feat/isotp-settleasync-cancellation branch September 30, 2026 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants