Locking an Application or System Wide Events

We have an application that periodically needs to go down for maintenance. We like to notify all users and display a billboard banner about an hour before the maintenance window starts. For the final 15 minutes before the start of the maintenance window, we change the color of the billboard to red to signify to the users that they are close to being locked out.

When the window finally starts, we lock out all the users so that navigating to the site simply displays message indicating that the system is undergoing maintenance.

We’ve done this by creating a VM singleton instance of an EventBus. We share this among all of our applications and when we need to lock the application, we fire an event that un-hides the billboard and shows the desired message.

What I’m wondering: does Vaadin provide a facility for this or is there a better “best practice” for this sort of system-wide event/messaging?

Appologies if this has already been answered. My searching didn’t turn up anything specific.

No, Vaadin doesn’t provide any mechanisms for this, but using an event bus is fine providing you take some precautions:

  • Make sure that inactive applications are removed from the event listener collection so that they can be garbage collected properly.
  • Remember to lock each application in a synchronized-block when making any changes from outside threads (like events)

Thanks Thomas. When you say “lock each application”, does this refer to the UI instance in Vaadin 7?

For those who are curious, Guava’s EventBus has worked very well for us for this purpose.

Actually no; synchronization is handled differently in V7, and I can’t for the life of me remember how the new mechanism worked… Hold on, I’ll find out.

just for reference, in Vaadin6 you are supposed to run your UI changing code inside a synchronized block, with the application that is modified as the lock object.

Here it is:

VaadinServiceSession.getLock().lock()

Thanks Thomas. Wondering if you could provide a link to where you found this info.

Don’t have the link, sorry, as I asked the developers personally :slight_smile:

Hi,

As previously mentioned, Vaadin doesn’t offer a specific solution for this. But it’s not hard to implement. The general concept is that you need to have one thread (I’ll call it the ‘admin’ thread representing some action an admin user has taken) set a String in Vaadin
Application
instances that are used by other (‘request’) threads.

Case 0:
If you’re using an add-on like
Refresher
, this is very simple. You can implement a singleton object in the web app to store the message using a
ReentrantReadWriteLock
. During the refresh() method of your app, you can check for this string. If it exists, then add it to a known place in your UI. It doesn’t matter in this arrangement whether the message changes while the app is refreshing or not – you’re only accessing it in one read operation, and during the next refresh it will update if it needs to. I already have an app in
a blog
that uses Refresher, so I could extend that example if anyone is interested.

Case 1:
You’re not using Refresher, so the page only changes during some user interaction. That means there isn’t a single method where you can put the logic to look for a message and display it if one exists. (You could implement
HttpServletRequestListener
and try to do this in the onRequestStart() method, but that method can be called concurrently so it doesn’t help – Vaadin synchronizes access to your Application object for business methods, but does not synchronize access to the servlet request listener methods since they’re called some time before/after the app object is accessed.) I see two options in this case. For either case, you’ll need to store the active sessions somewhere as they’re created, then iterate over them to get the application object of each one. There are a bunch of caveats there, including the fact that
the method to get the app context
can throw IllegalStateException (I can’t find my forum post about this now), but it’s not hard. I can publish an example if you’d like. So, once you have the applications,

Case 1a:
Add a method to your application object, for instance setImportantMessage(String message). This method is called by the ‘admin’ thread, not the ‘request’ thread, so you need to have the method synchronize with the same strategy that the ‘request’ thread uses. This means synchronizing on the

Case 1b: