Problem:
In an event listener data in e.g. a Table can be updated and will be visible to the user immediately. Doing the same thing in a background thread will not update the UI but if the user press refresh in the browser the UI is suddenly updated.
Reason:
Vaadin consists of a server side that runs in a servlet container and a client side that runs in a web browser. The application state is kept on server side but communication is initiated by the client side whenever needed e.g. when a button is clicked.
The server has no possibility to contact the web browser when the state has been updated by a background thread. Instead the change “waits” on the server until the client sends the next request e.g. clicks a button or requests a full repaint by refreshing the browser. At this point the change is sent to the client and the UI is updated.
How can this be solved:
There are two ways to deal with this:
poll
or
push
.
Poll
can be accomplished using the Refresher add-on available in the Directory. The refresher causes the client to periodically poll the server to see if any changes have been made. If there are changes, they are rendered in the client.
Push
can be accomplished using the ICEPush add-on available in the Directory. ICEPush causes the client to constantly keep a connection open to the server. If the changes take place in the server you can call the push() method to notify the client immediately that there are changes waiting. The client will then contact the server and fetch those changes.
Why are there two different approaches?
Push
and
poll
both have different pros and cons.
Push
will constantly keep a connection open to the server which is good for immediate updates but bad for the server if there are many clients connected. Most servlet containers allocate one thread per request, which consumes many threads and much memory when there are many clients. Servlet 3.0 contains asynchronous support which deals better with this.
A
poller
will not notice changes immediately but only when it happens to poll the following time. Setting a low polling time causes a lot of requests to the server and thus server load. A high polling time causes less server load but also longer times before the UI is updated.
What should I use?
What you should use really depends on your use case. If your data is seldom updated or you do not need immediate updates of the UI you will probably be fine with the Refresher. If immediateness is required then ICEPush is the way to go, provided your server can handle the long connections.
If you are using Google App Engine you should use Refresher as Google App Engine does not allow connections to stay open for more than 30s.
If you are creating portlets you cannot use ICEPush as there is currently no portlet support.
Other background thread considerations:
Remember to synchronize on the application instance whenever updating the UI from another thread.