[Logo] OLD FORUM - Use new one: https://www.CaptainCasa.online/forum
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
Lonnnng lasting operations in an actionListener - Session timeout  XML
Forum Index -> Development
Author Message
CaptainCasa

Power User
[Avatar]

Joined: 21/11/2007 12:23:06
Messages: 5555
Offline

...just finished a Screensharsession in which the following problem was discussed...

1. A button in a dialog starts a processing on server side which takes long time (1 to 2 hours...)

2. The session timeout in web.xml is configured to 60 minutes.

PROBLEM The servlet engine ends the session after 60 minutes... The whole scenario is moved into some "confusing situation" as result.


WHAT ARE THE WAYS OUT?

The normal advice is: separate the long lasting operation into some own thread. And use control LONGPOLLING with websocket communication to observe this thread until it's finished. By observing the thread, regularly new http-requests are sent from the client to the server, which keep the session awake. (And of course: the user likes to continue to work or to at least be informed about updates on server side...)

In the concrete scenario this was not possible: the long lasting processing requires access to the http session. (You may discuss, if this is a really good idea... but the effort to change this, is not adequate.) So moving into another thread is not an option.

...the first idea, was to use the BlockerInfo messaging: by API BlockerInfo you can send a text and a progress message to the client which is shown in an info window. This is of course some "dramatic" increase of useability - but: it does not have any consequences for the session timeout. The BlockerInfo internally uses a WebSocket connection - and using a WebSocket is not considered as an activity to keep the session alive. Only receiving new http-requests are the ones to update the timeout management of servlet engines.

Finally the way to go for this scenario: use the HttpSession-APIs...

Code:
 public void onStartLonnnnngAction(ActionEvent event)
 {
     int currentSessionTimeOut = HttpSessionAccess.getCurrentHttpSession().getMaxInactiveInterval();
     try
     {
         HttpSessionAccess.getCurrentHttpSession().setMaxInactiveInterval(-1);
         ...
         ... the lonnnnng processing
         ...
     }
     finally
     {
         HttpSessionAccess.getCurrentHttpSession().setMaxInactiveInterval(currentSessionTimeOut);
     }
 }
 


So for the duration of the long processing you switch the session timeout to "inifinite" (-1) - and you reset it to the previous value afterwards.

Remark for super-experts: in case of session management by Cookies, it can happen that several requests are running in parallel! The "HttpSessionAccess.getCurrentHttpSession().setMaxInactiveInterval(...);" is used across these threads, so there is a multi-threading issue as consequence. In order to solve this, you just need to shift corresponding data to the HttpSession level - because that's the one which is the common object seen by all parallel threads. - The principle stays the same: deactivate the session timeout for the duration of the long operation.

Björn Müller, CaptainCasa GmbH
CaptainCasa

Power User
[Avatar]

Joined: 21/11/2007 12:23:06
Messages: 5555
Offline

...received following message on this topic...:

Unfortunately that didn't quite work for me yet.



I believe the problem is the following flow:

1. Initially set: currentSessionTimeOut := X sec.

2. At startup: setMaxInactiveInterval = -1

3. the long-running process runs through unmolested in > X seconds

4. then set again: setMaxInactiveInterval(currentSessionTimeOut) i.e. X sec.

5. but the “last access time” was not updated, so the time has now expired: remainingTime < 0 s

6. And so the session is apparently considered “invalid” the next time it is accessed. Error: a complete restart occurs

Björn Müller, CaptainCasa GmbH
CaptainCasa

Power User
[Avatar]

Joined: 21/11/2007 12:23:06
Messages: 5555
Offline

"got it!"...

Way out:

1. Leave currentSessionTimeOut at "-1" and do not reset! ;-)

or

2. Initiate resetting of the timeout to its old value with an explicit request;

In other words, trigger the method via the client and then reset the timer in the ActionListener of this method. Triggering a method through the client is done by component CALLSERVERONTRIGGER:

Code:
 Page...:
 
 <t:beanprocessing ...>
     <t:callserverontrigger trigger="#{d.Xxx.longActionEndedTrigger}" actionListener="#{d.Xxxx.onResetTimeoutAction}"/>
 </t:beanprocessing>
 ...
 <t:button actionListener="d.Xxx.onStartLonnnnngAction" .../>
 
 
 Code:
 
 
 int m_currentSessionTimeOut;
 Trigger m_longActionEndedTrigger = new Trigger();
 public Trigger getLongActionEndedTrigger() { return m_longActionEndedTrigger; }
 
 public void onStartLonnnnngAction(ActionEvent event)
  {
      m_currentSessionTimeOut = HttpSessionAccess.getCurrentHttpSession().getMaxInactiveInterval();
      try
      {
          HttpSessionAccess.getCurrentHttpSession().setMaxInactiveInterval(-1);
          ...
          ... the lonnnnng processing
          ...
      }
      finally
      {
         m_longActionEndedTrigger.trigger();
      }
  }
 
 public void onResetTimeoutAction(ActionEvent event)
 {
     HttpSessionAccess.getCurrentHttpSession().setMaxInactiveInterval(m_currentSessionTimeout);
 }
 
 
 


Kind regards! Björn

Björn Müller, CaptainCasa GmbH
 
Forum Index -> Development
Go to:   
Powered by JForum 2.1.6 © JForum Team