Skip to content

#5518 Add eventProvider to Heartbeat for dynamic SSE events#5572

Merged
bjhham merged 2 commits intoktorio:mainfrom
fru1tworld:feat/5518-sse-heartbeat-provider
May 5, 2026
Merged

#5518 Add eventProvider to Heartbeat for dynamic SSE events#5572
bjhham merged 2 commits intoktorio:mainfrom
fru1tworld:feat/5518-sse-heartbeat-provider

Conversation

@fru1tworld
Copy link
Copy Markdown
Contributor

Subsystem
Server, ktor-server-sse

Motivation
Fixes #5518. Heartbeat.event is captured at config time, so every tick emits the same payload — no way to embed a fresh timestamp or counter without abandoning the built-in heartbeat() helper.

Solution
Add Heartbeat.eventProvider: (suspend () -> ServerSentEvent)?. When set, the heartbeat loop invokes it on each tick; otherwise falls back to event (existing behavior).

heartbeat {
    period = 30.seconds
    eventProvider = { ServerSentEvent(data = "ts=${Clock.System.now()}") }
}

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 34a083a6-719a-494e-8516-95c96e0a6603

📥 Commits

Reviewing files that changed from the base of the PR and between 9f6d1f3 and e760508.

📒 Files selected for processing (4)
  • ktor-server/ktor-server-plugins/ktor-server-sse/api/ktor-server-sse.api
  • ktor-server/ktor-server-plugins/ktor-server-sse/api/ktor-server-sse.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/ServerSSESession.kt
  • ktor-server/ktor-server-plugins/ktor-server-sse/common/test/io/ktor/server/sse/ServerSentEventsTest.kt
🚧 Files skipped from review as they are similar to previous changes (4)
  • ktor-server/ktor-server-plugins/ktor-server-sse/api/ktor-server-sse.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-sse/api/ktor-server-sse.api
  • ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/ServerSSESession.kt
  • ktor-server/ktor-server-plugins/ktor-server-sse/common/test/io/ktor/server/sse/ServerSentEventsTest.kt

📝 Walkthrough

Walkthrough

The PR adds dynamic event generation to SSE heartbeats by introducing a new eventProvider property to the Heartbeat class. The heartbeat loop now invokes the provider on each tick (if set) instead of repeatedly sending a static event, with the provider taking precedence over the static event. Documentation and tests are updated accordingly.

Changes

Heartbeat Event Provider

Layer / File(s) Summary
Data Model
ktor-server-sse/.../ServerSSESession.kt
Heartbeat class gains nullable eventProvider: (suspend () -> ServerSentEvent)? property.
Core Implementation
ktor-server-sse/.../ServerSSESession.kt
Heartbeat loop now invokes eventProvider?.invoke() ?: heartbeat.event on each tick, allowing dynamic event generation; eventProvider takes precedence over static event.
Public API & Documentation
ktor-server-sse/api/ktor-server-sse.api, ktor-server-sse/api/ktor-server-sse.klib.api, ktor-server-sse/.../ServerSSESession.kt
Public getter/setter methods exposed for the new property; ServerSSESession.heartbeat KDoc updated to describe conditional static or dynamic event behavior.
Tests
ktor-server-sse/.../ServerSentEventsTest.kt
Two test cases verify eventProvider generates unique events on every tick and that provider takes precedence over static event when both are configured.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding an eventProvider feature to Heartbeat for dynamic SSE event generation.
Description check ✅ Passed The description includes all required template sections (Subsystem, Motivation, Solution) with clear explanations and a usage example.
Linked Issues check ✅ Passed The implementation directly addresses issue #5518 by adding eventProvider property that allows runtime-generated event values with dynamic data like timestamps.
Out of Scope Changes check ✅ Passed All changes are directly related to the PR objective: adding eventProvider support to Heartbeat with API declarations, implementation, and tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get your free trial and get 200 agent minutes per Slack user (a $50 value).


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt (1)

139-157: 💤 Low value

KDoc style: consider simplifying to match ktor’s minimal public API KDoc conventions.

The implementation/behavior looks consistent with the documented semantics (anonymous sign rejects via check, unknown hash throws TLSException, unknown signature returns null). However, the added KDoc uses @param, @return, and @throws tags; in ktor this project appears to follow a minimal KDoc style for documented public API extension functions (brief description + a [Report a problem] link, without requiring explicit param/return/throws tags). citeturn0search0

If there’s no tooling enforcing the minimal format, this is just style/nit; otherwise, align the KDoc to the project convention to reduce review churn later.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt`
around lines 139 - 157, Simplify the KDoc for HashAndSign.Companion.byCode to
match the project's minimal public API style: replace the verbose tags (`@param`,
`@return`, `@throws`) with a concise one-line description followed by the existing
"[Report a problem]" link, keeping the note that the function finds or creates a
HashAndSign by numeric codes and maintaining mention of anonymous-sign rejection
where relevant; ensure the signature and behavior remain unchanged and that the
brief KDoc references HashAndSign.Companion.byCode and SignatureAlgorithm.ANON
for context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@ktor-server/ktor-server-plugins/ktor-server-sse/common/test/io/ktor/server/sse/ServerSentEventsTest.kt`:
- Line 339: The test method name testHeartbeatEventProvider should be renamed to
a descriptive backtick-style name to follow the project's test naming
convention; locate the function declaration testHeartbeatEventProvider (and the
other similar method at the mention around line 382) in ServerSentEventsTest.kt
and change the method name to a backtick string describing what the test
verifies (for example, `heartbeat events are provided at the configured
interval`), leaving the body and call sites unchanged.

---

Nitpick comments:
In
`@ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt`:
- Around line 139-157: Simplify the KDoc for HashAndSign.Companion.byCode to
match the project's minimal public API style: replace the verbose tags (`@param`,
`@return`, `@throws`) with a concise one-line description followed by the existing
"[Report a problem]" link, keeping the note that the function finds or creates a
HashAndSign by numeric codes and maintaining mention of anonymous-sign rejection
where relevant; ensure the signature and behavior remain unchanged and that the
brief KDoc references HashAndSign.Companion.byCode and SignatureAlgorithm.ANON
for context.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 58a57cef-7366-478a-8623-d3b7ac1693f9

📥 Commits

Reviewing files that changed from the base of the PR and between 295e688 and 57a5f3d.

📒 Files selected for processing (8)
  • ktor-network/common/src/io/ktor/network/selector/Selectable.kt
  • ktor-network/jvm/src/io/ktor/network/selector/InterestSuspensionsMap.kt
  • ktor-network/jvm/src/io/ktor/network/sockets/JavaSocketAddressUtils.kt
  • ktor-network/ktor-network-tls/common/src/io/ktor/network/tls/extensions/SignatureAlgorithm.kt
  • ktor-server/ktor-server-plugins/ktor-server-sse/api/ktor-server-sse.api
  • ktor-server/ktor-server-plugins/ktor-server-sse/api/ktor-server-sse.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-sse/common/src/io/ktor/server/sse/ServerSSESession.kt
  • ktor-server/ktor-server-plugins/ktor-server-sse/common/test/io/ktor/server/sse/ServerSentEventsTest.kt

Copy link
Copy Markdown
Contributor

@bjhham bjhham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution 👍

Nice to see some documentation filled in too.

Comment on lines +388 to +391
event = ServerSentEvent(data = "static")
eventProvider = {
ServerSentEvent(data = "dynamic")
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little confusing, but I can see why it's necessary to preserve backwards compatibility.

@bjhham
Copy link
Copy Markdown
Contributor

bjhham commented May 5, 2026

Oh, looks like there's a conflict with main now. Would you mind resolving this?

@fru1tworld fru1tworld force-pushed the feat/5518-sse-heartbeat-provider branch from 9f6d1f3 to e760508 Compare May 5, 2026 07:02
@fru1tworld
Copy link
Copy Markdown
Contributor Author

Thanks for the review — fixed!

@bjhham bjhham merged commit a695551 into ktorio:main May 5, 2026
15 of 17 checks passed
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.

Can Ktor SSE heartbeat support a function to get the value instead of a fixed one? I want to include a timestamp when sending heartbeats.

2 participants