Skip to content

regression: fix presence connections not being updated in DDPStreamer#37855

Merged
kodiakhq[bot] merged 5 commits intodevelopfrom
regression/presence-dangling
Dec 18, 2025
Merged

regression: fix presence connections not being updated in DDPStreamer#37855
kodiakhq[bot] merged 5 commits intodevelopfrom
regression/presence-dangling

Conversation

@cardoso
Copy link
Member

@cardoso cardoso commented Dec 17, 2025

Regression from #37551

Proposed changes (including videos or screenshots)

  • Fix a regression in microservice (DDPStreamer) mode where active users could be marked offline while still interacting with the app.
  • Refactor the DDPStreamer Client presence update mechanism to use a throttle-based approach instead of interval-based heartbeat with flag tracking:
    • Replace _seenPacket flag and heartbeatInterval logic with a throttled updatePresence method
    • Use underscore's throttle utility with { leading: true, trailing: false } to ensure presence updates occur at most once per TIMEOUT (30 seconds)
    • The first message after the throttle period triggers an immediate presence update
    • Subsequent messages within the throttle window are ignored automatically
  • Simplify code by removing manual heartbeat interval management and cleanup logic
  • As a result, UsersSessions.connections._updatedAt is periodically refreshed for active DDPStreamer connections, preventing the PresenceReaper from incorrectly pruning them as stale.

Issue(s)

Fixes https://rocketchat.atlassian.net/browse/CORE-1568

Steps to test or reproduce

  1. Run Rocket.Chat in EE microservice mode with DDPStreamer enabled.
  2. Log in with a user through the microservice (WebSocket via DDPStreamer, not the Meteor app server).
  3. In the database, locate the user's document in usersSessions and observe their connections array:
    • Before this fix: while continuously sending messages (no idle > 30s), connections._updatedAt stops changing after the initial login.
    • After ~5 minutes, the PresenceReaper removes that connection and the user appears offline, even though they are active.
  4. With this branch:
    • Keep the same user active (send messages or perform actions frequently).
    • Observe that connections._updatedAt is bumped at most once per 30 seconds while the user is active.
    • Confirm that the user's presence remains online and their connection is no longer reaped as stale.

Further comments

  • This change is intentionally scoped to EE DDPStreamer and does not modify the Meteor app server's presence logic.
  • The throttle-based approach is simpler and more maintainable than the previous interval + flag mechanism, while providing the same functional behavior.
  • Database writes remain bounded: at most one presence update per 30 seconds per active connection.

Summary by CodeRabbit

  • Bug Fixes
    • Improved presence update behavior: presence is now updated in a rate-limited way on incoming activity to reduce noise and improve stability.
    • Presence update failures are handled gracefully and logged without disrupting messaging or connection handling.
    • Removed redundant seen-packet tracking to simplify presence logic.

✏️ Tip: You can customize this high-level summary in your review settings.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 17, 2025

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Dec 17, 2025

⚠️ No Changeset found

Latest commit: 6ce47e6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

Walkthrough

Replaces heartbeat/_seenPacket-based presence coordination with a throttled presence-update approach: incoming messages now invoke a throttled updater that calls the presence update when a userId exists; immediate presence-on-heartbeat and packet-tracking fields were removed, and presence-update errors are logged.

Changes

Cohort / File(s) Summary
Client presence update
ee/apps/ddp-streamer/src/Client.ts
Replaced heartbeat/_seenPacket tracking with a throttled updatePresence thunk (uses throttle import). Invokes this.updatePresence() on incoming messages, removes _seenPacket and immediate heartbeat-triggered presence update logic, retains error-catching/logging for presence updates.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify throttling behavior (frequency, binding) and correct import of throttle.
  • Confirm removed _seenPacket and heartbeat paths don't break other lifecycle logic.
  • Check that presence update failures are handled and logged without impacting message processing.

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • tassoevan

Poem

🐰 I hopped through code with nimble paws,

Throttled my thumps without a cause.
Messages call — I gently delay,
Logging mishaps along the way.
A tidy hop, presence kept at bay.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing a regression where DDPStreamer presence connections were not being updated.
Linked Issues check ✅ Passed The code changes implement throttled presence updates and presence connection tracking that directly address the regression identified in CORE-1568, ensuring active connections are periodically refreshed.
Out of Scope Changes check ✅ Passed All changes are scoped to the DDPStreamer Client presence update mechanism and directly address the regression regression in CORE-1568 without introducing unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch regression/presence-dangling

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.

@cardoso
Copy link
Member Author

cardoso commented Dec 17, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@RocketChat RocketChat deleted a comment from coderabbitai bot Dec 17, 2025
@cardoso cardoso marked this pull request as ready for review December 17, 2025 17:14
@cardoso cardoso added this to the 7.14.0 milestone Dec 17, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 17, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 358MiB 347MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB +12KiB
queue-worker-service 132MiB 132MiB +11KiB
ddp-streamer-service 126MiB 126MiB +8.2KiB
account-service 113MiB 113MiB +9.7KiB
authorization-service 111MiB 110MiB +66KiB
stream-hub-service 110MiB 110MiB +8.8KiB
presence-service 110MiB 110MiB +6.5KiB

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/15 22:28", "11/16 01:28", "11/17 23:50", "11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 21:56", "12/08 20:15", "12/09 22:17", "12/10 23:26", "12/11 21:56", "12/12 22:45", "12/13 01:34", "12/15 22:31", "12/16 22:18", "12/17 21:04", "12/18 01:40", "12/18 17:20 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
  line "queue-worker-service" [0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
  line "rocketchat" [0.36, 0.36, 0.35, 0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.35]
  line "stream-hub-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11]
Loading

Statistics (last 24 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.2GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 1.2GiB
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-37855
  • Baseline: develop
  • Timestamp: 2025-12-18 17:20:11 UTC
  • Historical data points: 24

Updated: Thu, 18 Dec 2025 17:20:11 GMT

@cardoso cardoso changed the title regression: fix connections not being updated regression: fix presence connections not being updated in DDPStreamer Dec 17, 2025
@codecov
Copy link

codecov bot commented Dec 17, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.75%. Comparing base (65214b6) to head (6ce47e6).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop   #37855   +/-   ##
========================================
  Coverage    67.75%   67.75%           
========================================
  Files         3463     3463           
  Lines       113702   113702           
  Branches     20901    20901           
========================================
+ Hits         77034    77038    +4     
+ Misses       34501    34494    -7     
- Partials      2167     2170    +3     
Flag Coverage Δ
e2e 57.23% <ø> (+0.02%) ⬆️
e2e-api 44.01% <ø> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cardoso
Copy link
Member Author

cardoso commented Dec 17, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Member

@sampaiodiego sampaiodiego left a comment

Choose a reason for hiding this comment

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

instead of all this sheninagans with intervals and flags all around, pls change the implementation to a throttle to call Presence.updateConnection

Copy link
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: 0

🧹 Nitpick comments (1)
ee/apps/ddp-streamer/src/Client.ts (1)

78-88: Consider using structured logging instead of console.error.

The throttled presence update implementation looks correct, with appropriate throttle options for periodic updates. However, the error handling uses console.error which may not integrate with the application's logging system.

If the codebase has a structured logging service or logger, consider using it instead of console.error for consistency:

-				void Presence.updateConnection(this.userId, this.connection.id).catch((err) => {
-					console.error('Error updating connection presence:', err);
-				});
+				void Presence.updateConnection(this.userId, this.connection.id).catch((err) => {
+					logger.error('Error updating connection presence:', err);
+				});
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 811cee7 and 86bf4ff.

📒 Files selected for processing (1)
  • ee/apps/ddp-streamer/src/Client.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • ee/apps/ddp-streamer/src/Client.ts
🧬 Code graph analysis (1)
ee/apps/ddp-streamer/src/Client.ts (1)
ee/packages/presence/src/Presence.ts (1)
  • Presence (12-334)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (1)
ee/apps/ddp-streamer/src/Client.ts (1)

217-217: LGTM! Throttled presence update integration is correct.

The placement of this.updatePresence() on every incoming message, combined with the throttle mechanism, ensures that active connections have their presence periodically refreshed without overwhelming the presence service. The throttle's leading: true configuration guarantees that the first message after each throttle period triggers an immediate update, which aligns with the PR objective of preventing active users from being marked offline.

@cardoso cardoso requested a review from sampaiodiego December 17, 2025 18:51
@cardoso cardoso removed the request for review from sampaiodiego December 17, 2025 20:40
@cardoso cardoso added the stat: QA assured Means it has been tested and approved by a company insider label Dec 18, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Dec 18, 2025
@sampaiodiego
Copy link
Member

/bark

@kodiakhq kodiakhq bot merged commit 3b9aab8 into develop Dec 18, 2025
86 of 88 checks passed
@kodiakhq kodiakhq bot deleted the regression/presence-dangling branch December 18, 2025 18:26
@scuciatto
Copy link
Member

/patch

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 19, 2025

Pull request #37887 added to Project: "Patch 7.13.2"

@scuciatto
Copy link
Member

/backport 7.12.3

@scuciatto
Copy link
Member

/backport 7.11.3

@scuciatto
Copy link
Member

/backport 7.10.6

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 19, 2025

Pull request #37888 added to Project: "Patch 7.12.3"

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 19, 2025

Pull request #37889 added to Project: "Patch 7.11.3"

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 19, 2025

Pull request #37890 added to Project: "Patch 7.10.6"

@coderabbitai coderabbitai bot mentioned this pull request Dec 19, 2025
gaolin1 pushed a commit to gaolin1/medsense.webchat that referenced this pull request Jan 6, 2026
@dougfabris dougfabris modified the milestones: 7.14.0, 8.0.0 Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants