Using an eventbus framework with Vaadin - how to know a user doesn't need a

Hi,

today I got into trouble while using Vaadin together with an event bus framework. I wanted to update different parts of my UI based on actions performed by Services. For example when I successful save an object I wanted to inform all parts of the UI currently presenting information of that object to any user of the webapp. My first approach was to use the well known EventBus from Guava. But there is a problem when it comes to unregister from the EventBus. First I tried to register in the onAttach method and unregister again in the onDetach method. There are multiple issues in this approach:

  1. I wanted the component to listen on events even though it wasn’t visible at the moment but the onDetach method already unregistered from the EventBus.
    2. My workaround was to always register to the EventBus and not only when the component was initially attached inside the onAttach method. But i had to reload the initial data even though there might have not been any changes on the object.
  2. The next issue i ran into even with my workaround in place was that the onDetach method does not get called everytime the component is not visible for the user anymore. For example if the user just closes the browser or the tab. This leads to a memory leak because of all the not unregistered components.

The solution I finally found was to use MBassador as the framework, because it supports weak references. The garbage collector makes sure that components not used anymore are removed from the event bus and the memory.

But I am still puzzled why I have to rely on the Java garbage collector and can’t just handle the correct destruction of components on my own.

In my opinion there should be a “visibilityChangeEvent” that should be fired every time the component gets attached/detached, changes the visibility status internally or if the user just closes the browser.

Is there a good way to get an event like this with Vaadin already or did I probably miss something else?

This would also be a good feature for stuff like unlocking resources for other users when someone closes the browser or just to show a message before the user leaves to show that he has unsaved changes.

Hi Lutz,

I am using the Guava EventBus for an internal project, too, and have been faced with the same issues. I ended up with using a presenter for my view classes that takes care of attaching to the bus in its constructor and updates the view’s model when it is attached.

Regarding detaching there might be a miss-understanding. The onDetach method is not called immediately but when the UI is detached. Check `onDetach` not called when reloading the page | Vaadin for some details. So, you might just have to wait a little.

Hope that helps!

Cheers,
Paul

Hi Paul,

thank you very much for your clarification! So in the worst case the unnecessary calls are just made for a few minutes. I think that is okay at least for the EventBus problem.

The problem with locked resources would still be a little bit bigger, because other users might have to wait a longer time until they can modify it. I think the only way to modify this is to reduce the heartbeatInterval setting.

The problem with locked resources would still be a little bit bigger, because other users might have to wait a longer time until they can modify it. I think the only way to modify this is to reduce the heartbeatInterval setting.

Yes, as far as I know only heartbeatInterval will help with the detach events. Btw. have you tried the BeforeLeaveObserver and the beforeLeave() method? Normally, it is only called when you navigate to another view but honestly I am unsure how it behaves when reloading the page.

The limitations of the beforeLeave() method and the BeforeLeaveObserver are even bigger than with the onDetach() method. The method only gets called while navigating inside the app. So reloading, navigating with the URL or exiting the browser tab are not catched. Additionally the components that have to be updated are not views but just components inside of them. So the beforeLeave() gets called even fewer times than the onDetach() method.

Ok, then forget about it. I wasn’t sure if the behavior of beforeLeave() changed but as we are talking about plain components it wouldn’t help anyway.

Then, another thing you could try is relying on Javascript: javascript - Detect browser or tab closing - Stack Overflow Unfortunately, I could not find a ready-made webcomponent you could use. And in directory there is only one add-on for Vaadin 8 that does not seem to work anymore: Vaadin Add-on Directory

I guess there are a lot people who would love to have this feature for V10+ : )

I recently saw this thread discussing the unload event: https://vaadin.com/forum/thread/17523194/unsaved-changes-detect-page-exit-or-reload But I have a few concerns about this way because of Leif’s comment there. I think right now theres no perfect way to implement something regarding my issues. Hopefully there will be some “safe” API in the future that can be called.