Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Remote Application Platform (RAP) » Timeouts, UICallBack and single-sourcing
Timeouts, UICallBack and single-sourcing [message #674051] Wed, 25 May 2011 12:35 Go to next message
Ryan Donnelly is currently offline Ryan Donnelly
Messages: 35
Registered: July 2009
Member
Hi,
We have a complex single-sourced RAP/RCP application that we will be
deploying on Tomcat with RAP 1.4 (probably an RC build - we can't wait
for June 22) in about a month. We have deployed on a small scale with
earlier versions of RAP (principally 1.2.1). Our use of the UICallBack
framework with the earlier version was to leave it activated from start
of createUI() to finish.

We have always used a timeout and SessionStoreListener to do our own
cleanup if the user closes the browser. However, with RAP 1.4 (I am
running against latest from CVS), on both Tomcat and Jetty under
Eclipse, we are no longer getting the timeout. From several newsgroup
postings and bugs, I understand that leaving UICallBack active all the
time can prevent timeouts being received. I am therefore trying to
follow your suggested method described here

http://wiki.eclipse.org/RAP/FAQ#How_to_update_the_UI_from_a_background_thread

of activating UICallBack, doing the Display.(a)syncExec(), and
deactivating UICallBack.

However, because of the nature of our single-sourced code base, it is
not possible to do the UICallBack.activate() before the background
thread creation. The only reasonable way that I've found to do it with
a low impact to our existing code base is to create a wrapper for
Display.(a)syncExec(), such that one version is called for SWT and one
for RWT.

SWT version:

public static void asyncExec(Display display, Runnable r)
{ display.asyncExec(r);
}


RWT version:

public static void asyncExec(Display display, Runnable r)
{
final String id = Integer.toString(System.identityHashCode(display));

display.asyncExec(new Runnable() {
public void run()
{
UICallBack.activate(id);
}
});

display.asyncExec(r);

display.asyncExec(new Runnable() {
public void run()
{
UICallBack.deactivate(id);
}
});
}


Doing it this way does restore at least some of the timeout
functionality (I will make another posting on more problems here).
However, what I am observing is that doing it this way we are not
getting all the UI updates (e.g. I have to click in the UI to get things
to update). So I am wondering:


1) Is it possible to call UICallBack.activate() through
Display.asyncExec() right before the Runnable is called, rather than
before background thread creation? This post, for instance, suggests
starting UICallBack "well ahead"

http://www.eclipse.org/forums/index.php/mv/msg/162119/512880/#msg_512880


2) Does RAP guarantee that the Runnables from three calls to
Display.asyncExec() above are executed in the order that the calls were
made? It is my understanding that SWT does (please correct me if I'm
wrong). If not, that could be the problem.


3) Is my use of the id correct? As I understand it, within the same
HttpSession all calls should use the same id (I based it on the Display
in my example above). Throughout our complex, multithreaded application
we could have several of these asyncExec() overlapping within one
session. It seems to me from looking at your UICallBack code that you
handle this, only shutting off the mechanism when the number of
registered requests for a session reaches 0. Is there any problem here?


4) In our application, Display.asyncExec() can be called from both the
UI Thread and from a background thread. Do I need to distinguish
between these two cases in my code above (i.e. calling
UICallBack.activate() and deactivate() directly instead of in a Runnable)?


Thanks,

Ryan
Re: Timeouts, UICallBack and single-sourcing [message #674452 is a reply to message #674051] Thu, 26 May 2011 20:45 Go to previous messageGo to next message
Ryan Donnelly is currently offline Ryan Donnelly
Messages: 35
Registered: July 2009
Member
Hi,
After further investigation, it seems clear to me that it is not
possible to activate UICallBack from a background thread through
Display.(a)syncExec():

display.asyncExec(new Runnable() {
public void run()
{
UICallBack.activate(id);
}
});

Unless UICallBack has already been activated, the Runnable is never
executed (until I click in the GUI).

Can you please confirm this?

If this is the case, could you please explain how, using UICallBack as
suggested as opposed to globally, a long-running server-side thread
could ever trigger a UI update (e.g. in response to a message it
received from somewhere which has nothing to do with the GUI)? The only
time I could activate UICallBack would be at the creation of this
thread, which would mean essentially leaving UICallBack on all the time.


I am also wondering, as far as session timeouts and UICallback:

1) With the suggested use of UICallBack, there is still some time in
which it is active, in which I assume timeouts will not arrive. Is a
session timeout that occurs during this period lost forever, or does it
arrive after UICallBack is disabled?

2) If the browser is closed, we rely on a session timeout to clean
things up. If UICallBack happens to be activated when the browser is
closed, the timeout will never arrive?

If timeouts do not arrive in these two situations, then it seems to me
that I cannot rely on session timeouts to do cleanup, and I will need to
create my own timeout mechanism. Is the following reasonable? We would
have some javascript in the browser that regularly sends a request to
the server. If the server does not receive this request within a
defined timeout, it assumes the browser has closed and performs the cleanup.


I know there are a lot of points in these two postings. I appreciate
any light the RAP team can shed on them.


Thanks,

Ryan


On 25/05/2011 13:35, Ryan Donnelly wrote:
> Hi,
> We have a complex single-sourced RAP/RCP application that we will be
> deploying on Tomcat with RAP 1.4 (probably an RC build - we can't wait
> for June 22) in about a month. We have deployed on a small scale with
> earlier versions of RAP (principally 1.2.1). Our use of the UICallBack
> framework with the earlier version was to leave it activated from start
> of createUI() to finish.
>
> We have always used a timeout and SessionStoreListener to do our own
> cleanup if the user closes the browser. However, with RAP 1.4 (I am
> running against latest from CVS), on both Tomcat and Jetty under
> Eclipse, we are no longer getting the timeout. From several newsgroup
> postings and bugs, I understand that leaving UICallBack active all the
> time can prevent timeouts being received. I am therefore trying to
> follow your suggested method described here
>
> http://wiki.eclipse.org/RAP/FAQ#How_to_update_the_UI_from_a_background_thread
>
>
> of activating UICallBack, doing the Display.(a)syncExec(), and
> deactivating UICallBack.
>
> However, because of the nature of our single-sourced code base, it is
> not possible to do the UICallBack.activate() before the background
> thread creation. The only reasonable way that I've found to do it with a
> low impact to our existing code base is to create a wrapper for
> Display.(a)syncExec(), such that one version is called for SWT and one
> for RWT.
>
> SWT version:
>
> public static void asyncExec(Display display, Runnable r)
> { display.asyncExec(r);
> }
>
>
> RWT version:
>
> public static void asyncExec(Display display, Runnable r)
> {
> final String id = Integer.toString(System.identityHashCode(display));
>
> display.asyncExec(new Runnable() {
> public void run()
> {
> UICallBack.activate(id);
> }
> });
>
> display.asyncExec(r);
>
> display.asyncExec(new Runnable() {
> public void run()
> {
> UICallBack.deactivate(id);
> }
> });
> }
>
>
> Doing it this way does restore at least some of the timeout
> functionality (I will make another posting on more problems here).
> However, what I am observing is that doing it this way we are not
> getting all the UI updates (e.g. I have to click in the UI to get things
> to update). So I am wondering:
>
>
> 1) Is it possible to call UICallBack.activate() through
> Display.asyncExec() right before the Runnable is called, rather than
> before background thread creation? This post, for instance, suggests
> starting UICallBack "well ahead"
>
> http://www.eclipse.org/forums/index.php/mv/msg/162119/512880/#msg_512880
>
>
> 2) Does RAP guarantee that the Runnables from three calls to
> Display.asyncExec() above are executed in the order that the calls were
> made? It is my understanding that SWT does (please correct me if I'm
> wrong). If not, that could be the problem.
>
>
> 3) Is my use of the id correct? As I understand it, within the same
> HttpSession all calls should use the same id (I based it on the Display
> in my example above). Throughout our complex, multithreaded application
> we could have several of these asyncExec() overlapping within one
> session. It seems to me from looking at your UICallBack code that you
> handle this, only shutting off the mechanism when the number of
> registered requests for a session reaches 0. Is there any problem here?
>
>
> 4) In our application, Display.asyncExec() can be called from both the
> UI Thread and from a background thread. Do I need to distinguish between
> these two cases in my code above (i.e. calling UICallBack.activate() and
> deactivate() directly instead of in a Runnable)?
>
>
> Thanks,
>
> Ryan
>
Re: Timeouts, UICallBack and single-sourcing [message #674480 is a reply to message #674452] Fri, 27 May 2011 01:54 Go to previous messageGo to next message
Frank Appel is currently offline Frank Appel
Messages: 46
Registered: July 2009
Member
Rony,

if you have an application in which a background thread triggers an UI update e.g. in response to a message it receives from somewhere which has nothing to do with the GUI and you have no hint when this message arrives, you have to switch on the UICallback mechanism globally.

Once the HTTP response content is rendered by the browser it needs a user interaction to receive new information from the server. That's part of the request/response nature of the HTTP protocol (Note this behaviour may be changed by HTML 5 Server Push). The UICallback mechanism actually works around that problem by sending an additional request that gets blocked at the server side. This allows to notify the client about server side changes by unlocking this request if needed.

The latter implies that the UICallback mechanism has to be activated before any background thread messages arrive. And this explains also why it is not possible to activate the UICallback mechanism from within the background thread. So if you don't know exactly when to switch on and off the UICallback mechanism, you'll have to use the global approach (that's what it is there for).

Given the nature of the mechanism the updates of the UI via the callback requests do also reset the timeout watch of a running session. As long as the user does not close the browser window/tab and the time between background UI updates do not exceed the timeout threshold the session is indeed kept alive.


Regards
Frank
Re: Timeouts, UICallBack and single-sourcing [message #674486 is a reply to message #674480] Fri, 27 May 2011 02:28 Go to previous message
Cole Markham is currently offline Cole Markham
Messages: 127
Registered: July 2009
Senior Member
Rony,

I have just a few comments to add to Franks excellent assessment.

First off, we successfully use the global UICallback method in our application and have not run into any major problems.

Because the UICallback blocks the request on the server, there may be some timeout on the client or an intermediate proxy which will drop the connection. This will at least disable the UICallback and prevent any background updates from being "pushed" back to the client. Once there is user interaction on the client side it should reestablish the callback. One way to prevent this type of timeout is to have the server periodically send a "keep alive" message to the client.

With regard to session timeout, like Frank said, the UICallback will keep the HTTP session open since there is an active request. Once the user closes the browser, the session timeout will behave as normal (i.e., the timeout period will start from that point).

If you need a logical user session timeout to know when the user may have walked away but left the browser open, this is more difficult. It would be difficult to distinguish between requests originating from your background thread and interaction by the user. You would probably need some metric within your application that looked at things like selection, mouse movement, active view (if you are using the workbench), etc. Once you have detected the user has not been active, then you can disable the UICallback and/or manually expire the HTTP session.

Cole
Previous Topic:UIThreadTerminatedError on session timeout
Next Topic:Deploy on JBoss 6.0.0
Goto Forum:
  


Current Time: Sat May 25 01:52:48 EDT 2013

Powered by FUDForum. Page generated in 0.01647 seconds