Getting the number of active sessions in Vaadin

Last week I explored how to get the number of active sessions that Tomcat reports: https://adeelscorner.wordpress.com/2016/03/13/getting-the-number-of-active-sessions-in-tomcat/

The problem with that metric is that some of those sessions, or all, may not actually be active users. What if someone is connected to your java web application (Tomcat in this case), but has just been sitting idle, for hours or even days. They’re not really using your application per se. However, Tomcat will report them as active users, especially if your application has a heartbeat, or a long polling push connection established.

So an additional metric that is useful in determining if your java application is actually in use is to track the number of active sessions within your java application. In our case we’re using Vaadin, so that’s what this post is geared towards. However, you’ll see the general idea here and can apply this to any user based application.

Before I continue, I want to point out a useful Vaadin add-on to measure idle time: https://vaadin.com/directory#!addon/idle. This is pretty handy in checking the actual idle time for a user.

The other important thing to explore first is as follows. Each Vaadin Session is based on a cookie, so if a browser has multiple tabs open to the same application server running Vaadin, the Vaadin Session will be shared among those tabs, because the cookie is shared. Hence, when a Vaadin session ends (perhaps when the user logs out, or times out), all user browser tabs open corresponding to that session are disconnected.

Let’s get started. At the core of how this will work is a public static HashMap which we can use to track a browser tab that belongs to a particular Vaadin session, and how long it’s been active or idle. Since this is a static data structure, it will be shared among all sessions at the Tomcat level. So it’s pretty handy in tracking all sessions on that particular Tomcat server. We’ll be able to track not only how many browser tabs a user has open to your application, but how long they’ve been idle in each tab.

I created a class called ApplicationLevelTracker to assist, which is pretty simple really. It’s as follows:

public class ApplicationLevelTracker {
 public static HashMap < String, Pair < Boolean, Long >> browserTabUniqueIDToIdleTimeHashMap = new HashMap < String, Pair < Boolean, Long >> ();

 private String thisBrowserTabUniqueID;

 public ApplicationLevelTracker(int userID, String vaadinSessionID) {
  thisBrowserTabUniqueID = userID + ":" + vaadinSessionID + ":" + UUID.randomUUID().toString();
  registerIdle(false);
 }

 public void registerIdle(boolean idle) {
  Date date = new Date();
  browserTabUniqueIDToIdleTimeHashMap.put(thisBrowserTabUniqueID, new Pair < Boolean, Long > (idle, date.getTime()));
 }

 public void deRegisterThisTab() {
  browserTabUniqueIDToIdleTimeHashMap.remove(thisBrowserTabUniqueID);
 }

 public void deRegisterAllTabsForThisVaadinSession() {
  String userID = thisBrowserTabUniqueID.split(":")[0];
  String vaadinSessionID = thisBrowserTabUniqueID.split(":")[1];
  Set < String > keySet = ApplicationLevelTracker.browserTabUniqueIDToIdleTimeHashMap.keySet();
  List < String > browserTabUniqueIDsToRemove = new ArrayList < String > ();
  for (String key: keySet) {
   String _userID = key.split(":")[0];
   String _vaadinSessionID = key.split(":")[1];
   if (_userID.equals(userID) && _vaadinSessionID.equals(vaadinSessionID))
    browserTabUniqueIDsToRemove.add(key);
  }
  for (String browserTabUniqueID: browserTabUniqueIDsToRemove) {
   browserTabUniqueIDToIdleTimeHashMap.remove(browserTabUniqueID);
  }
 }
}

Here’s a breakdown of the class, and the methods: The constructor takes the user’s ID (any identifier you have for your user, in our case an integer), and the Vaadin Session ID. Using these keys, and a random ID, each browser tab that a user opens to your application will get its own unique ID created in the constructor.

When a user goes idle, registerIdle(true) is called. When a user is active, registerIdle(false) is called. This way we can track whether they are active or idle in the corresponding browser tab. These methods will be used by the Vaadin Idle add-on (more on that soon).

When a browser tab is closed, deRegisterThisTab() is called. When the Vaadin session is being ended (for example, you may do that when a user logs out from your application, or when Vaadin determines the user has timed out), deRegisterAllTabsForThisVaadinSession() is meant to be called, to clean them out of the tracking HashMap.

Next, to actually make use of the ApplicationLevelTracker, you’ll have to set it up and use it properly in your Vaadin UI class, where your application is created and each user’s instance is initiated. So in your UI class that creates your Vaadin application (the class usually extends Vaadin’s “UI”), you’ll need to set up the following code for all this to come together:

First, define this variable in your UI class:

private ApplicationLevelTracker applicationLevelTracker = null;

Next, when the views are being created, after the User is logged in (note: you should set it up so this code is called on every new creation of the UI class, and not just the creation of a new Vaadin Session (the same Vaadin session can have multiple UIs attached to it)), you’ll want to set up ApplicationLevelTracker:

applicationLevelTracker = new ApplicationLevelTracker(user.USER_ID, VaadinSession.getCurrent().getSession().getId());
Idle.track(UI.getCurrent(), 120000, new Idle.Listener() {
 @Override
 public void userInactive() {
  applicationLevelTracker.registerIdle(true);
 }
 @Override
 public void userActive() {
  applicationLevelTracker.registerIdle(false);
 }
});

Notice that the Vaadin Idle add-on is used here. We create an instance of ApplicationLevelTracker with the user’s ID, and the Vaadin session ID, which registers this browser tab in static (shared) memory. And then when the user goes idle, or when the user goes active, as reported by the Idle add-on, we register that with ApplicationLevelTracker.

Now that things are setup, we need to be sure they are cleaned up when the user goes away.

You can use this neat trick to register whenever that particular browser tab is closed, or when the user navigates away from your application. This is where you’ll want to call applicationLevelTracker.deRegisterThisTab():

JavaScript.getCurrent().addFunction("browserIsLeaving", new JavaScriptFunction() {
 @Override
 public void call(JsonArray arguments) {
  if (applicationLevelTracker != null)
   applicationLevelTracker.deRegisterThisTab();
 }
});
Page.getCurrent().getJavaScript().execute("window.onbeforeunload = function (e) { var e = e || window.event; browserIsLeaving(); return; };");

You’ll also want to use applicationLevelTracker.deRegisterThisTab() when the Vaadin detach listener is fired. A detach listener corresponds to the UI, and not the whole Vaadin session. So it will be fired when one particular instance of UI belonging to a singular browser tab (which may one of several tabs belonging to the same Vaadin session) is detected to have gone away, this code will be called to clean up that particular browser tab. You can add the following block of code in the init() method in your Vaadin UI class:

addDetachListener(new DetachListener() {
 @Override
 public void detach(DetachEvent event) {
  if (applicationLevelTracker != null)
   applicationLevelTracker.deRegisterThisTab();
 }
});

Lastly, wherever in your code the user logs out, and you end the Vaadin session, you’ll want to call applicationLevelTracker.deRegisterAllTabsForThisVaadinSession():

if (applicationLevelTracker != null)
 applicationLevelTracker.deRegisterAllTabsForThisVaadinSession();

And that’s it! Now you have an application wide HashMap which fully tracks all individual browser tabs open to your application, and information on how long the user has been active or idle in each tab. In my next blog post I’ll cover how to actually pull this information and use it in a meaningful way to make a determination of how many users are using your application at any given moment.

Before wrapping up I want to point out one final thing on how to interpret this tracking information after you’ve started collecting it. If a user is connected, and is idle for too long (say 2 hours, or several days), you can reliably know that they are not using the application. They are either connected and left their machine running and browser open, just sitting idle. Or they’re gone (no longer connected) and their session was never cleaned up for whatever reason. If the user has been active for a long time (say, several days), that means something is wrong too, unless they really have been working every minute in your application for the last several days without a break. In this case you can assume the user is not really there, that their browser connection went away and their tracking didn’t get cleaned up for whatever reason (for example, Vaadin didn’t fire the detach listener reliably, which I’ve noticed happens sometimes though it may be fixed in new Vaadin versions). The only case you can be pretty certain that a user is using your application at the present moment is if they’ve just been idle for a short period (say within a 30 minute window), or if they’ve been active within a short period (say 30 minutes again).

Vaadin upgrade from 7.4.5 to 7.6.1

I was recently tasked with upgrading our Vaadin applications at work from version 7.4.5 to version 7.6.1. I came across an issue that took me a long time to figure out, so I thought I’d share in case anyone else is running into the same.

The process went pretty smoothly at first. We use Ivy for our projects, and simply updating the Vaadin version in ivy.xml allowed all the new library files to be downloaded. Then I re-compiled the widgetset, and took one of our applications out for a spin.

Lo and behold I got an error stating: “Failed to load the bootstrap javascript: ./VAADIN/vaadinBootstrap.js?v=7.6.1”. I did some investigating, and noticed that the vaadinBootstrap.js served to the browser looked like a binary file, whereas the browser was trying to interpret it as a JavaScript file.

I eventually realized that the vaadinBootstrap.js is compressed. I did everything I could to verify that the compression filters were correct, but the browser for some reason seemed like it was not uncompressing vaadinBootstrap.js before trying to interpret it.

Turns out that in prior versions of Vaadin, with the Vaadin demo applications, Vaadin had stuck in a CompressionFilter using net.sf.ehcache.constructs.web.filter.GzipFilter to web.xml. It compressed all *.js, *.html, *.css files (which only works if the browser/client announces it supports it in the HTTP headers) before serving it. HOWEVER, in the new version of Vaadin (7.6.1) it seems that there are some new compression filters already built in! Hence, the content (in this case vaadinBootstrap.js) was compressed twice! So the browser would uncompress it as it should, but that would yield a second compressed file! Sheesh. Had almost pulled my hair out before I figured this out.

The solution was to get rid of all the custom compression filters using net.sf.ehcache.constructs.web.filter.GzipFilter from our web.xml. And then everything started working smoothly.

Vaadin: Executing custom JavaScript from a thread, or loading custom JavaScript functions into global scope

As you may know already, in Vaadin you can use com.vaadin.ui.JavaScript.getCurrent().execute(…) function to execute some custom JavaScript on the client browser.

  1. Executing custom JavaScript from a thread:
    The above works well as long as the JavaScript execute() method is being called on the main UI thread. However, if JavaScript.getCurrent().execute() is called from a background thread, the JavaScript won’t get executed until there is a periodic refresh of the UI, or there’s a UI event (triggered by the user, such as a mouse click somewhere). This can seem to cause erratic behavior, with the JavaScript executing at unpredictable times. (Side note: any Vaadin UI access/manipulation from a background thread needs to be done inside com.vaadin.UI.getCurrent().access(new Runnable() { … });, and also note that you want to do your time-consuming heavy lifting first (such as retrieving data from the back end) and then go into UI.getCurrent().access(…) to manipulate the UI).To get around this problem, simply use Vaadin Push. You’ll need to enable push if not already (see Vaadin documentation on how). Then depending on the push mode you’ve used (manual or automatic) you’ll either need to call com.vaadin.ui.UI.getCurrent().push() or not (for manual mode you’ll need to call the push() method, for automatic mode it will be called after the runnable you send to the UI.access(…) method finishes executing). So call get JavaScript.execute(…), and then UI.push() last. Example:

    new Thread() {
        public void run() {
            //some long running background work
                 UI.getCurrent.access(new Runnable() {
                public void run() {
                    JavaScript.getCurrent().execute("alert('Background Task Complete!');");
                                UI.getCurent().push();
                }
            });
        }
    }.start();
  2. Loading custom JavaScript functions into global scope:
    This is extremely useful so you can define a JavaScript function which you can use later from JavaScript.getCurrent().execute(…), such as inside an event (a button click, for example). However, the JavaScript function will need to be in the global scope by injecting it into thetag for the HTML page served by Vaadin. To do this, use the following code while your Vaadin view is being created, or is being enter()’ed.

    StringBuilder script = new StringBuilder(); script .append("var head = document.getElementsByTagName('head')[0];") .append("var script = document.createElement('script');") .append("script.content='function sayHello() { alert(\"Hello!\");}';") .append("head.appendChild(script);"); JavaScript.getCurrent().execute(script.toString());

    Note: as I mentioned, a JavaScript function can only be loaded this way when the view is being created, or in the view’s enter() method. To create a function this way AFTER the page is already loaded (such as through some event), you’ll need to use Vaadin Push, and call UI.getCurrent().push() after the JavaScript.getCurrent().execute() even though you’re not on a background thread.

  3. You can define a function in the script tag being created above, which can then be called later on through JavaScript.getCurrent().execute(“sayHello();”); perhaps inside a Vaadin button click listener.

Enjoy!

Getting rid of Jetty related exceptions when using Vaadin Push with Tomcat

At least in Vaadin 7.3.x and 7.4.x, running on Tomcat with Push enabled, you may see several exceptions in your console having to do with Jetty. Even though you’re not using Jetty, this is happening because Vaadin is getting tricked into assuming that Jetty is being used, since a Jetty library is found in the Java classpath.

Vaadin does realize after the exceptions that Jetty isn’t actually there and continues gracefully. But though these exceptions are harmless, they’re still unsettling to constantly in your tomcat logs. As I mentioned, this is happening because there is some Jetty library in your Java classpath. So thus the obvious solution get to rid of these exceptions is to remove all Jetty libraries from your Java classpath. Search for any .jar’s that have “jetty” in the name, and remove them.

If you’re using Ivy or Maven dependency management, the library may be downloaded as a sub-dependency from another dependency. You will need to go through all your dependencies to check which ones also reference Jetty. The culprits in our case were vaadin-client-compiler and HtmlUnit (both reference Jetty for Jetty related things, but since we’re not using Jetty anyway, getting rid of the Jetty library should cause no harm).

We use Ivy, and I found how to exclude certain sub-dependencies, which is simple. Use the  tag in your ivy.xml wherever jetty is a sub-dependency. A example follows:

<exclude org="org.eclipse.jetty" name="*" />

And viola! No more random Jetty based exceptions from Vaadin.

Making a pseudo div fade in using CSS animation

The example I’ll use applies specifically to Vaadin, for when the loading bar is shown if the server is taking too long. However, the same CSS styling I’ll use can be applied to any pseudo div.

When Vaadin loads a page (or a “view”), and if the page takes too long to load, there’s some client side JavaScript and CSS that Vaadin pre-loads, which displays a loading bar or progress bar. This bar progresses forward, from left to right, at the top of the page, under the “URL” area of your browser. And it eventually goes away when the page loads. This gives the user the indication that something is happening and they should wait.

If the page takes too long to load, this bar eventually starts blinking. And if the server is stuck (had a hiccup somewhere), this bar just blinks forever. After some waiting, more adept users eventually realize it will never load and they refresh the page which usually resolves the issue. However less tech-savvy users don’t know what to do at that point. So we set up a small message box (a pseudo div) that floats under the loading bar, which tells the user to refresh the page. This is kind of like what the GMail web app does when there’s a network issue.

First of all, to set up the pseudo div, we add the following to our theme’s scss (SASS) file that Vaadin uses:

.v-loading-indicator-wait:after
{
  position:fixed;
  content: "Temporary Internet issue... Please wait, or refresh page.";
  color: black;
  background-color: #F9EDBE;
  border-style: solid;
  border-color: #F0C36D;
  box-shadow: 2px 2px 5px #888888;
  left: 50%;
  transform: translateX(-50%);
  top: 10px;
  padding-top: 5px;
  padding-right: 5px;
  padding-bottom: 5px;
  padding-left: 5px;
}

“v-loading-indicator-wait” is the style Vaadin gives to the loading bar which shows up after a certain amount of waiting while the server is processing the request. So to show our floating div with the loading message, we can use the ::after (v-loading-indicator-wait::after), as indicated above.

The problem is, that the v-loading-indicator-wait is added after just a number of seconds of waiting (around ~5), and showing the floating div would be too soon. So the best way (or at least an easy way) to do it is to use animation to delay when it is added.

You can define the animation to “fade in” the div (from being invisible to visible) after a certain number of seconds, like so:

@include keyframes(animate-in-scale-up) {
  0% {
    @include transform(scale(0));
  }
}

@-webkit-keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

@-moz-keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

@-o-keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

.v-loading-indicator-wait:after
{
  //...all the other stuff
  -webkit-animation: fadein 12s ease 1 normal;
  -moz-animation: fadein 12s ease 1 normal;
  -o-animation: fadein 12s ease 1 normal;
  animation: fadein 12s ease 1 normal;
}

And viola. The floating div doesn’t show up until about 12 seconds after the “v-loading-indicator-wait” is added, which is about 5 seconds after a request is initiated and the server hasn’t responded. So that’s a total of 17 seconds between the user initiated the request and till when the message shows, which I believe is enough waiting time to realize the server may never respond.

Making a Vaadin window transparent/translucent

We had a need to do this recently, and it wasn’t obvious, so I thought I’d share.

One thing to note is that if the window is modal, this trick won’t work. Since for modal windows, Vaadin adds some more styling around the window to the back the background “dimmed”, thus giving a stronger visual focus on the modal window. For regular (non-modal) windows, this trick works great, especially if you just want to overlay some information on content behind the window.

In your java code, add the following style to your Vaadin Window:

myWindow.addStyleName("translucent");

In your theme stylesheet for your application (most likely a “.scss” file), add the following styles:

.v-window-translucent
{
  background-color: rgba(255,255,255,0.6) !important;
}
div.v-window-translucent .v-window-contents {
  background: rgba(255,255,255,0.6);
}

Then compile your theme, and refresh your page. Viola! Your window will now be translucent.

To tweak the translucency, modify the “a” (alpha) value in the rgba inside the theme style. 0.6 worked well for us, making it a bit translucent. To make it less translucent, try a value greater than 0.6. And to make it completely transparent, try 0.

Enjoy!

Resolving Vaadin push with long polling issues in AWS Elastic Beanstalk

This took me a long time to figure out, so I thought I’d share it with anyone else struggling with this.

When you upload a Vaadin application to the AWS Elastic Beanstalk, Tomcat sits behind an Apache server that proxies connections to it. (Note: this may apply to you even if you’re not in AWS/ElasticBeanstalk. If you use Apache as a proxy to an application server, be it Tomcat or something else, this could still be an issue).

If you’re using Vaadin push in long polling mode (Transport.LONG_POLLING), it turns out that the connection between the client (browser) and server (tomcat, or your other java application server) gets dropped due to a timeout issue. If there is no data exchanged between the server (tomcat) and the client (browser), then the connection is deemed “idle” by Apache and gets dropped. This is an issue because with long polling, the HTTP connection remains open indefinitely, and that’s information is pushed to the client from the server.

Now with Vaadin’s push, it’s supposed to recover from a dropped connection. The connection is supposed to just get reestablished, and everything resumes. That’s an ideal scenario. In my experience, that doesn’t always work the way it should. If I’m on a Vaadin web app through my browser, and sit idle for a while, when I come back to it a lot of time it resumes fine (I can see push reestablishing itself in the console), but a lot of times the app just hangs forever.

Another thing to note is that Vaadin sends a heartbeat to the client, to check if the client is still there. The default heartbeat is every 5 minutes. When a heartbeat is sent, Apache’s idle connection timeout is reset. So if there is no user activity for a few minutes, the goal is to adjust the configuration so that the heartbeat happens before Apache times out the HTTP connection.

So the solution for this is to

  1. Modify Apache’s timeout for idle connections. I believe the default setting in AWS’s configuration for Apache, is 60 seconds. You’ll need to ssh into your server, edit /etc/httpd/conf/httpd.conf, and look for the “Timeout” directive. Change the Timeout directive to be greater-than the default Vaadin heartbeat of 5 minutes. Try 6 minutes (note: the Timeout value is in seconds), so you’d set “Timeout 360”. The downside of this approach is if your server has hundreds of thousands of requests, surely some legitimately idle connections (where the client is gone without cleaning up and not coming back) will linger for longer than 60 seconds, this affecting your system performance.
  2. Modify Vaadin’s heartbeat to be less than 60 seconds. You can edit your web.xml, and add an heartbeatInterval parameter like so:
        <context-param>
            <param-name>heartbeatIntervalparam-name>
            <param-value>120param-value>
        context-param>
  3. You can tweak both the Vaadin heartbeat, and the Apache Timeout value to some reasonable values that suit your needs the best. Just make sure that the heartbeat interval is shorter than the timeout.

Enjoy!