flow: closeIdleSessions=true does not allow HTTP session to expire

Vaadin 14.0.10 Configuration

vaadin.heartbeatInterval=10
server.servlet.session.timeout=90
vaadin.closeIdleSessions=true
vaadin.compatibilityMode = false 

After 90 seconds there is a new VaadinSession, but the HTTP session id is the same. Tried with

vaadin.heartbeatInterval=120
server.servlet.session.timeout=90
vaadin.closeIdleSessions=true
vaadin.compatibilityMode = false 

After 90 seconds there is a new VaadinSession, and the HTTP session id changes. Sample application:

public MainView() {
    add(new Span(VaadinSession.getCurrent().getSession().getId()+" "+VaadinSession.getCurrent()));
}

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 19 (10 by maintainers)

Commits related to this issue

Most upvoted comments

What is the value of only destroying Vaadin Session but not Servlet session?

With these settings:

vaadin.heartbeatInterval=10
server.servlet.session.timeout=90
vaadin.closeIdleSessions=true

I’d expect the HTTP session to be closed eventually; perhaps not after 90 seconds but after 90s+3*heartbeats; I’d expect Vaadin to close+detach+disconnect UIs after three missed heartbeats.

The current status and documentation is creating a lot of confusion. Would it be possible to create a list of concrete cases and how Vaadin would react?

It would be really great if someone could link to some working code to achieve what the original posted actually wanted. i have been trying for years to get this right and there is just a lot of misinformation out there now.

What do I need to do to expire a vaadin session (together with its http session) after say 30 minutes of the user staring at the screen not touching a thing? That way the http session can be released, load balancers can start to work, the users session will automatically log out during lunch times making the system data safer.

Just saying that the code is working as designed doesn’t help any reader of this issue on how to solve the actual issue the posted asked.

Please help.

This triggers the sessionDestroy listener, however at this point the session is null and there is no way to either find the http session to invalidate it, or to do any other actions.

Is there a listener that can be called before the actual session is nulled?

You can get the session from the event object which is passed to your SessionDestroyListener:

service.addSessionDestroyListener(event -> {
  VaadinSession session = event.getSession();  // Use this rather than VaadinSession.getCurrent()
  // ... your logic
});

@fschon We have the following working for us really well:

  • custom heartbeat-interval of 60 seconds (instead of the default 5min)
  • close idle sessions = true
  • custom HeartBeatHandler that triggers “resetTimer” on our UIs / Components
  • custom Timer (component that shows the current session timeout time to the user; which is updated by PUSH if the reset comes from the Heartbeat -> cause user already afk and no “real” interaction)

This Timer has special cases for:

  • '> 2 min left? Only update “XYZ min left”
  • ==2min left? Auto-Save the current open view (input fields)
  • <= 1min left? Logout

So overall this reduced the 30min + (3*5min) to 33min (which was okay for us).

Looks like the title of the ticket doesn’t match the ticket description and it’s not clear what behavior is considered as a bug.

closeIdleSessions=true does not allow HTTP session to expire

It doesn’t matter what value closeIdleSessions has : HTTP session won’t expire with values

vaadin.heartbeatInterval=10
server.servlet.session.timeout=90

if closeIdleSessions=false either (if I correctly understood the behavior which is considered as a bug here).

closeIdleSessions means :

whether a session should be closed when all its open UIs have
     been idle for longer than its configured maximum inactivity time.
     
      A UI is idle if it is open on the client side but has no activity other
      than heartbeat requests. If {@code isCloseIdleSessions() == false},
      heartbeat requests cause the session to stay open for as long as there
     are open UIs on the client side. If it is {@code true}, the session is
     eventually closed if the open UIs do not have any user interaction.

I believe there is some misunderstanding here: Vaadin never close/invalidate HttpSession . The session mentioned in the javadocs is VaadinSession and according to the description this session is closed.

HttpSession stays the same because heartbeat request (the interval set to 10) is sent several times during the interval which is used for HTTP session inactivity check : it’s 90. So the HTTP session never expires because there is an activity (sending a heartbeat request) which prevents the session to be closed.

Setting the heartbeat interval value to 120 allows HTTP session expire because the inactivity in this case is longer than session timeout.

So the behavior is correct.

If you want to close HTTP session along with Vaadin session then you may just add a SessionDestroyListener and call HttpSession::invalidate.

Please note that the Vaadin session and the HTTP session are not the same thing. There can be several Vaadin sessions for the same HTTP session, it’s not 1:1 but M:1. And this is exactly the reason why HTTP session is never closed by Vaadin : all settings are about Vaadin session which is not 1:1 to HTTP session.

So: do you think I can do something more about this? It looks like our javadocs for DeploymentConfiguration::isCloseIdleSessions can be improved by removing confusion about session: it should be the Vaadin session (not just a session). But I don’t see what I can do more about this.