Skip to content

fix(api): eliminate typingHandlerLock spinlock and main-thread deadlock - #1412

Open
swarnendusahu10-dotcom wants to merge 1 commit into
RocketChat:developfrom
swarnendusahu10-dotcom:fix/issue-1354-typing-handler-deadlock
Open

swarnendusahu10-dotcom wants to merge 1 commit into
RocketChat:developfrom
swarnendusahu10-dotcom:fix/issue-1354-typing-handler-deadlock

Conversation

@swarnendusahu10-dotcom

Copy link
Copy Markdown
Contributor

Description

Closes #1354

Fixes a potential main-thread deadlock in packages/api/src/EmbeddedChatApi.ts.

Previously, handleTypingEvent utilized a module-scoped let typingHandlerLock along with a synchronous while (typingHandlerLock) {} spinlock. Because JavaScript operates on a single-threaded event loop, any unhandled error or asynchronous delay while the lock was held caused the while loop to starve the event loop indefinitely, resulting in 100% CPU utilization and freezing the browser tab.

Changes

  • Removed the module-scoped typingHandlerLock and redundant while (typingHandlerLock) {} spinlock. Since synchronous array modifications in JavaScript run to completion sequentially, the lock is unnecessary.
  • Added defensive validation to verify typingUser exists before updating the internal typingUsers list.
  • Clean Rollup build verified in @embeddedchat/api.

Test Coverage

  • Verified concurrent typing event processing without locks.
  • Verified rapid sequence of start/stop typing events without CPU spikes or dropped callbacks.

Removes the module-scoped typingHandlerLock variable, the synchronous
while (typingHandlerLock) {} spinlock loop, and the 2000ms setTimeout fallback.

In single-threaded JavaScript runtimes, a synchronous while loop blocks
the call stack indefinitely. Because the event loop cannot cycle while the
main thread spins, the setTimeout macrotask can never execute to clear
the lock. If the lock was ever set or an event arrived re-entrantly, the
browser tab entered an unrecoverable freeze with 100% CPU usage.

JavaScript event handlers are already executed sequentially on the event loop,
making the spinlock both completely redundant and actively dangerous. Also added
defensive validation for typingUser to prevent null/empty entries from polluting
the typing status array.

Fixes RocketChat#1354

This branch has not been deployed

No deployments
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.

bug: Potential main-thread deadlock in EmbeddedChatApi.ts when typingHandlerLock remains set

1 participant