Hey all, pretty new to web dev in general, and have been lurking and reading as much as possible about Vaadin for the past month or so.
Anyways, I am running into a problem where I wanted to do some cleanup if a user closes their browser window and ends their session, and I wanted it to happen pretty quickly after the window is closed.
It seems like after 15-20 min, the detach method will get called, but that is a far cry from what the setting is set to above.
Also, this will print the value I set in the xml:
System.out.println(VaadinService.getCurrent().getDeploymentConfiguration().getHeartbeatInterval());
Any ideas on what I am doing wrong on this? I spent most of the afternoon searching, and not coming up with anyhing that answered my question before I went to ask here.
I’m not 100% sure, but seems to me that the close timing is not actually guaranteed. At least in
https://vaadin.com/wiki/-/wiki/Main/Cleaning+up+resources+in+an+UI it is said like this: “When the server does not receive a valid heartbeat for a given UI, it will eventually remove that UI from the session”.
I guess what might affect it is whether or not you get any further requests. As far as I know there is no periodically run cleanup (background thread) - it’s run whenever there’s a request. If you don’t get any further requests the UIs will be cleaned up on session expiration. Would that 15-20min be your session life time?
Indeed. Old UIs are only detached when the session receives new requests, and all UIs are cleaned up when the session expires. Anything more elaborate would be difficult to implement so that it makes sense for all use cases. It’s possible to write a timer-based cleanup mechanism on top of Vaadin’s, but it could be a bit easier (
ticket 11852 ).
I don’t mind building that functinality, I just wasn’t understanding why it wasn’t working as I thought it should (on that note, I should probably start looking at the Vaadin code so I understand how some of this stuff is done).
Well, let me just explain my use-case, because maybe I am just goind about this all wrong.
I have user accounts, and want to be able to limit an account to only be logged in on a single session at any one time.
How I did that, was to create an AccountContainer singleton, and once a user was logged in, they were added to a list inside that class, along with the session they are tied to.
Upon logout (using the button), they are removed from that list.
I was trying to also quickly remove an account from that list if the user closed their browser window, so the account becomes available to login on a new session promptly (which is why I was asking the above question).
Does a timer based solution sound like the right option? Or is there something quite simplee available to use I just don’t know about?
Also, sorry if some of this is common sense… I am just a hobby programmer whose only experience is on an MMO server, which is quite different than this type of development (unstructured vs structured). I am really enjoying using your framework though! Exciting to see how quickly things can be put together.
I had the same problem.
It got solved when I modified the session timeout parameter in web.xml (for me to 2 minutes). Now if the detach method gets called after around 3 minutes so sessionTimeout + 2*heartbeat
Yes, I agree that the tutorial is somewhat misleading. The cleanup mechanism, as it’s implemented, is a bit like garbage collection. It will be done at some point, but you might have to wait. So it’s good for releasing resources that shouldn’t pile up on the server, but not so good for doing time-dependent application logic such as your use case.
Hah, before I checked back on this thread, I read about that and gave it a shot, and it did work. I actually did something just a bit different, by setting it lower on a per-session basis
if(AccountContainer.getInstance().addAccount(account))
{
getUI().getSession().getSession().setMaxInactiveInterval(10); //sets the session to go inactive after 10 seconds of inactivity
getUI().getNavigator().navigateTo(Navigation.ACCOUNTCREATION.getNavAddress());
}