Part of #138. Found while writing the Collaboration Kit to Signals migration guide (vaadin/docs#5888).
Real use case
A support desk where agents work a shared queue. Each ticket view carries a CollaborationAvatarGroup so an agent can see at a glance that a colleague already has the ticket open, and skip it. The avatars are the whole mechanism preventing two agents from working the same ticket.
An agent finishes a shift and closes the browser.
- Today: the beacon fires on unload, the connection deactivates, the
EntryScope.CONNECTION entry is dropped, and the avatar disappears within about a second.
- After migrating to signals: no detach event is delivered, so the entry stays until the session expires. With a 30 minute session timeout, that ticket looks taken for half an hour after everyone went home.
The same shape appears anywhere presence gates behaviour rather than just decorating it: "who is in this room", "who is editing this record", "is anyone looking at this dashboard".
Field highlighting has the matching failure. A user closes the tab with a field focused, and that field stays outlined in their colour, for everyone, indefinitely.
What Collaboration Kit does
EntryScope.CONNECTION removes an entry as soon as the connection that wrote it deactivates. PresenceManager.addLocalUserToTopic uses it for the presence entry, and FormManager.highlight uses it for field editors.
Deactivation is prompt even when the tab is closed, because ComponentConnectionContext installs a beacon request handler (BeaconHandler, reached from ComponentConnectionContext:193), so the unload is reported immediately rather than at session timeout.
What signals have
Nothing. A shared signal entry lives until something removes it. A detach listener covers navigation and an orderly close, but nothing fires when the tab is killed, the network drops, or the server is replaced.
Suggested direction
Some way to tie the lifetime of a shared signal entry to a session or a UI. Roughly in order of how much they change:
- A scope on the write, mirroring
EntryScope.CONNECTION, cleaned up when the owning session ends.
- A framework-side beacon equivalent, so a closed tab is reported promptly.
- Failing both, a documented heartbeat pattern: store a timestamp with each entry and sweep stale ones.
The first two are what would let a migrated application behave as it does today. The third only narrows the window.
Part of #138. Found while writing the Collaboration Kit to Signals migration guide (vaadin/docs#5888).
Real use case
A support desk where agents work a shared queue. Each ticket view carries a
CollaborationAvatarGroupso an agent can see at a glance that a colleague already has the ticket open, and skip it. The avatars are the whole mechanism preventing two agents from working the same ticket.An agent finishes a shift and closes the browser.
EntryScope.CONNECTIONentry is dropped, and the avatar disappears within about a second.The same shape appears anywhere presence gates behaviour rather than just decorating it: "who is in this room", "who is editing this record", "is anyone looking at this dashboard".
Field highlighting has the matching failure. A user closes the tab with a field focused, and that field stays outlined in their colour, for everyone, indefinitely.
What Collaboration Kit does
EntryScope.CONNECTIONremoves an entry as soon as the connection that wrote it deactivates.PresenceManager.addLocalUserToTopicuses it for the presence entry, andFormManager.highlightuses it for field editors.Deactivation is prompt even when the tab is closed, because
ComponentConnectionContextinstalls a beacon request handler (BeaconHandler, reached fromComponentConnectionContext:193), so the unload is reported immediately rather than at session timeout.What signals have
Nothing. A shared signal entry lives until something removes it. A detach listener covers navigation and an orderly close, but nothing fires when the tab is killed, the network drops, or the server is replaced.
Suggested direction
Some way to tie the lifetime of a shared signal entry to a session or a UI. Roughly in order of how much they change:
EntryScope.CONNECTION, cleaned up when the owning session ends.The first two are what would let a migrated application behave as it does today. The third only narrows the window.