feat: accept a CancellationToken in EmptyStreamingMarkdownFile - #210
Merged
Ilia Permiashkin (p3rmiashkin) merged 1 commit intoAug 1, 2026
Conversation
Ryan VanderMeulen (rvandermeulen)
force-pushed
the
streaming-cancellation-token
branch
from
July 29, 2026 23:42
cfea908 to
7ea93ee
Compare
Ilia Permiashkin (p3rmiashkin)
left a comment
Contributor
There was a problem hiding this comment.
Please update CHANGELOG.md
`EmptyStreamingMarkdownFile` hardcoded `MarkdownParser(flavour)`, so the streaming parser always ran with `CancellationToken.NonCancellable` and callers had no way to make an `append` abortable. This matters most when a block never closes: an unterminated fence keeps the whole document in `unstableTail`, so every append reparses all of it. The existing flavour-only function is left as-is and delegates to a new two-argument overload, so the change is additive at the ABI level.
Ryan VanderMeulen (rvandermeulen)
force-pushed
the
streaming-cancellation-token
branch
from
July 31, 2026 13:16
7ea93ee to
364487a
Compare
Contributor
Author
|
Dropped
|
Ryan VanderMeulen (rvandermeulen)
requested a review
from Ilia Permiashkin (p3rmiashkin)
July 31, 2026 13:18
Ilia Permiashkin (p3rmiashkin)
merged commit Aug 1, 2026
14e35f1
into
JetBrains:master
3 checks passed
Ryan VanderMeulen (rvandermeulen)
deleted the
streaming-cancellation-token
branch
August 2, 2026 03:04
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.
Problem
EmptyStreamingMarkdownFilehardcodesMarkdownParser(flavour), so a streaming file always parses withCancellationToken.NonCancellableand anappendcannot be aborted. It is the only remaining place incommonMainthat constructs aMarkdownParserwithout a token: cancellation support (#141) and the streaming parser (#185) landed independently, and #203 threaded the token further intoTopLevelBuilder.This matters most when a block never closes. An unterminated fence keeps the whole document in
unstableTail, so everyappendreparses all of it with no way to bail out. That is a common shape for LLM-generated markdown, which is the context this was found in: Firefox for Android renders streamed page summaries through this parser.Approach
It was not clear what the project's policy on ABI compatibility is, beyond the
// To keep the ABI compatibility.comments inMarkdownParser.kt, so the safer route was taken here.Adding a second defaulted parameter to the existing function would drop the
EmptyStreamingMarkdownFile$default(MarkdownFlavourDescriptor, int, Object)synthetic that no-argument Kotlin callers bind to, breaking anything compiled against 0.7.8. Instead the flavour-only function is unchanged and delegates to a new two-argument overload. Diffing compiled method sets against the published 0.7.8 jar confirms nothing removed and one method added.The cost is an extra overload, plus the loss of
EmptyStreamingMarkdownFile(cancellationToken = token), since the default flavour can no longer be combined with a token. Should an ABI break be acceptable, the single-function form seems preferable and can be substituted on request.MarkdownParser,TreeBuilder,TopLevelBuilderandSequentialParserManagerall deprecate their tokenless entry points.EmptyStreamingMarkdownFile(flavour)is left undeprecated here because the no-argument form is used throughout the existing test suite, but the deprecation can be added for consistency if preferred.Tests
Added three new cases: cancellation propagating out of
append, the token being consulted on successive appends while the unstable tail grows, and the flavour-only overload producing output identical to an explicitNonCancellable.