Add support for SSE comments - #478
Open
magdzikk wants to merge 20 commits into
Open
Conversation
`ServerSentEvent` now carries a `comments` field, so that comment lines (those starting with `:`) can be both parsed and serialised. Per the WhatWG specification such lines are ignored by clients, which makes them the idiomatic keep-alive: they stop proxies from dropping an idle connection without dispatching an event to the application. Binary compatibility with 1.7.18 is preserved in the same way as for `ContentTypeRange`: the old-arity constructor, `copy` and `apply` are kept alongside the new ones. Closes #379 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
magdzikk
marked this pull request as ready for review
August 28, 2026 14:44
adamw
reviewed
Aug 31, 2026
adamw
reviewed
Aug 31, 2026
adamw
reviewed
Aug 31, 2026
adamw
reviewed
Sep 1, 2026
adamw
reviewed
Sep 1, 2026
adamw
reviewed
Sep 1, 2026
adamw
reviewed
Sep 1, 2026
# Conflicts: # core/src/main/scala/sttp/model/sse/ServerSentEvent.scala # core/src/test/scala/sttp/model/sse/ServerSentEventTest.scala
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.
Fixes #379.
ServerSentEventgains acomments: List[String]field, so comment lines (those starting with:) round-trip through bothparseandtoString.ServerSentEvent.comment("ping")builds the keep-alive frame the WhatWG specification recommends sending every 15 seconds or so, to stop legacy proxies from dropping an idle connection.Design notes
List[String]rather thanOption[String], because a single event block may carry several comment lines.There is deliberately no assertion that a comment and data aren't both set (as considered in the issue discussion). The specification ignores comments per line, not per event, so a block such as
is valid and still dispatches
abc. A guard would reject valid streams.Binary compatibility
Preserved with the same approach already used for
ContentTypeRange: the old-arity constructor,copyandapplyare kept alongside the new ones, andmimaReportBinaryIssuesis green.MiMa does not see everything, though. The source-level and runtime-shape changes it cannot report are listed under Migration below.
Migration
Everything here follows from
ServerSentEventgaining a field. Recompiling against the new version is the general fix; the two behaviour changes need a code change as well.Comment-only events are no longer empty. A
: pingblock used to parse toServerSentEvent(), and now parses to an event withcommentsset, so code that dropped keep-alives by comparing against an empty event stops dropping them:hasNoFieldsis true when an event carries no data, event type, id or retry, so it drops exactly the set that the old comparison dropped — keep-alives, empty blocks, and blocks of unknown fields alike.Events parsed from a stream containing comments no longer equal hand-built events. Streams often open with a
:handshake comment, so expected values need updating, or the comments dropped before comparing:Patterns over the four original fields no longer compile. Add a fifth
_, or use the accessors:Code compiled against an earlier version has to be recompiled. The changes below leave the erased signatures intact, so such code links and then fails at runtime, and MiMa cannot report it:
ServerSentEvent.unapplynow returns aTuple5. A caller compiled earlier fails withClassCastException: scala.Tuple5 cannot be cast to scala.Tuple4. Compiled patterns are unaffected — they lower to accessor calls rather than tounapply.Mirrorread a fifth element. One compiled earlier fails withIndexOutOfBoundsException: 4.Serialised forms change.
serialVersionUIDchanges from5877847238202557287to-2395116303002558390, so Java-serialised events do not cross the version boundary.commentsfield. circe and play-json ignore Scala default arguments, so their derived decoders reject JSON that lacks it; jsoniter-scala and zio-json read the default and are unaffected.