Killing push connections on browser close

Using Vaadin 24.3, I have an application that relies heavily on push. The straight @Push annotation is used on the AppShell, no options.

The behavior I suspect is that when users leave the application, the push session does not terminate.

I have set up a playwright application that opens chrome contexts, and if I run it with 10, kill it, run it again with 20, kill it, and finally with 45, I see traces for 45 sessions in my logs. The sessions appear to stay indefinitely, as if there was no timeout.

This is a “watch the scoreboard application” where users are not expected to do anything.

What is the modern way to detect a browser close, one that will work on a phone too when they “close” the browser app? Is the only way out to force an interaction and kill if they don’t reply in 3…2…1…

With Chrome specificly, I think that should work pretty well out of the box. Vaadin these days uses so called Beacon request that we make from page visibility change event to notify the server the tab is closed. In can save a ton of memory on cases like yours. My guess is that the “special chrome” used by Playwright doesn’t work exactly like the real chrome here.

You could check that out manually if it works or not. IIRC, it fails with e.g. Safari (should be investigated, probably a different page visibility state should be used, there are browser differences in these areas).

The beacon request in Vaadin is not bound to Push connection. With Websocket communication, there could indeed be the option to close the session also when the socket is closed (and not opened immediately). Would probably be more stable in certain cases. I don’t remember seeing an issue of that.

Also check that you use the latest Vaadin 24.3.14 release

There was just recently a memory leak spotted when using PreserveOnRefresh and that was fixed some weeks ago.

Not sure exactly what you mean by “session” in this case. Even if the UI instances are cleaned up, the HTTP session will still remain open since there’s technically no guarantee that the user won’t open another browser window and e.g. expect to still be logged in.

I am not using preserveOnRefresh but I will check.
The application presents scoreboards for a large sports competitions (USA National Olympic Weightlifting championships running for 9 days with 1500 athletes), and it crashes with out of memory after a few hours, but by that time several hundred people have logged in and watched.
So I do expect much of the population logging in to be on iPhones/iPads and therefore using Safari.

One partial solution might be to define a short session timeout for the servlet container?

The default session timeouts from the server (jetty, embedded) are not kicking in. I presume that’s because push is used and there is traffic back and forth.
And having the screen up to watch for 2hours is legitimate (without touching anything).

Are you updating Grid periodically with Push and calling refreshAll? Just remembered that there is a corner case related to that. After refreshAll Grid will re-render and report back to server using client callable. This will extend the session and it wont close as long as you keep updating the Grid.

I added a note about this to the documentation

But it seems that in the newest documentation this note has been erased for some reason. That is unfortunate.

As a workaround you could use BeanTable

The page is a dashboard built with two LitTemplate elements, not a Vaadin Grid. It relies on the getElement().setProperty() reactive feature to do its updates