Blocking User Input

If a user clicks on something that triggers a trip to the server to process, they should not be allowed to continue clicking around while the server is processing the previous request. I am sure there will be those that disagree with me but I’d rather have the UI disabled (indicated with a “busy” cursor) for a few seconds than to let the user continue clicking around when the first request hasn’t finished, yet.

I have read suggestions to just disable what you don’t want them to click on while the work is being done (perhaps using a separate thread) but that supposes that you know in advance what’s going to take a long time and what’s not going to take a long time. In many situations, you don’t know that such-n-such is going to take along time.

So I am looking for a general solution to the problem. That is, is there any system-wide way to configure the front end to show a busy cursor after the user clicks on something, and stop responding to additional clicks, until the previous request comes back from the server?

This would totally defeat the purpose of an AJAX-ified UI. Why would I want to have incremental UI-updates if I just force the user to wait on my server anyways? In that case I can use right away the old Web-1.0-programming-model.

I agree with Tobias - you would not be doing AJAX just “SJAX” - synchronous calls to the server.

However, if you really want to do it (which I don’t recommend), you would need to modify ApplicationConnection so that it forces all calls to be synchronous (makeUidlRequest(), doUidlRequest()). Unexpected side effects may occur.

I understand your reaction but if you take a closer look at what Vaadin is doing under the covers, Vaadin is already synchronizing the processing of requests on the user’s application instance (as it enters into a synchronized block, synchronized on the app) so Vaadin is, inherently, single-threading the processing of all requests for a given user. All I am suggesting is that Vaadin should provide some type of busy cursor as a clue to the end user that their last request is still being processed. Otherwise, they just keep clicking around on things, queuing up work for the server which, as I mentioned before, has to line up behind the previous request before Vaadin will process it.

I believe that Vaadin already sets a busy icon for requests that take a “long” time. It starts out white, then yellow and then turns red if it continues to wait.

In general, we don’t see a lot of delays as most UI actions are not that costly. It’s mostly when in debug we see it since we’re slowing down the request dramatically.

For buttons that trigger longer processes, we use the Button.setDisableOnClick(true) to prevent it being clicked multiple times. Hope that helps…

EDIT TO ADD:
You can see this in the theme styles for .v-loading-indicator, .v-loading-indicator-delay, .v-loading-indicator-wait which define spinning icons to show.

We actually changed our so that the short-loading icon appears “as defined” but we gray out the screen when the yellow/red versions to make it clear that the server is unexpectedly bogged down, using:

/*.v-loading-indicator,*/ .v-loading-indicator-delay, .v-loading-indicator-wait {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
 
    margin: 0;
    padding: 0;

    opacity: 0.5;
    filter: alpha(opacity=50);
    z-index: 30000;

    background-color: #999999; 
    background-repeat: no-repeat;
    background-position: 50%;

    cursor: wait;
}

Note that we do not include plain v-loading-indicator in our change since we want that to keep the low-key approach of showing the icon in the upper right corner. I forgot who suggested this scheme earlier in a forum posting.

ApplicationConnection also takes care of this, with three “levels” of loading indicators: the first at 300ms, then at 1500ms and at 5s. The delays are currently not configurable (
#7448
).

Well it’s kind of a difference if you say “disable the UI” or “show a busy cursor” (and keep the UI working). We have pulled the busy-cursor Vaadin already displays out of its place in the upper right corner into the middle of the screen (and replaced it by a larger graphic) so that it gets visible to our users that there is still something working.

Can you point me to that code? Using 6.7.3, I can see concurrent calls to my application. For instance, I’ve had to store the HttpSession in a threadlocal so concurrent calls don’t null it out when implementing HttpServletRequestListener. It’s easy enough to see if you log a message at the beginning and end of a transaction: I can see more than one onRequestStart() call before an onRequestEnd() method.

Thanks,
Bobby

The synchronization by the framework is done in AbstractCommunicationManager.doHandleUidlRequest().

Thanks. Now I have a better understanding of this. The onRequestStart and onRequestEnd methods in my application could be called by multiple threads (this is what I was seeing), but not the business logic. Cool.

I’d like to suggest that the Javadocs for HttpServletRequestListener point out that these methods could be called by concurrent requests. If someone is implementing that interface in order to get a pointer to the current session, then the application can end up with a NullPointerException unless the code stores the session in a thread local. (Or locks on the start methods and unlocks on the end method – ugh.) I’d be happy to file a doc enhancement request if anyone agrees.

Cheers,
Bobby

Please do - this certainly should be clarified in javadoc at least, maybe also elsewhere in our documentation.

Thanks Henri.

I just filed
ticket 9063
.

Cheers,
Bobby