• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Sudden Logout Problem - Related to Concurrency?

 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello folks, I am investigating an issue on the Production server in our Struts-based app running on a clustered OAS environment.

Struts ActionClass is defined as a singleton, which means the ActionClass will be created only once and will create a new thread for each incoming request, and call the execute() method. In our implementation, in the execute(...) method, we are instantiating an object that contains several static and non-static methods.


So, since s is a per-thread instance of ShareableCode class, any calls to its static and non-static methods must be implicitly thread-safe, since each thread instantiated by the TwentyPointAction class has its own copy of s. The same must be the case in a clustered, multiprocessor environment too. Am I correct? THe problem is I am facing is sudden, inexplicable logouts under severe load conditions. These seem to happen when the request's session ID does not match up with the session's ID. That is, request.isRequestedSessionIdValid() returns false, since request.getRequestedSessionId() does not match request.getSession(false).getId(). When the sudden logout appears, request.getSession(false).getId() returns a new value that has never appeared before in the logs. I think session-replication timeout is probably the issue, but just want to be sure that the non-synchronized isValidUser() method is not getting its request and session objects mixed-up due to concurrency issues.

In general, are method calls to static and non-static methods of a class threadsafe if we ensure that the calling thread instantiates its own copy of that class, and ensure that no shared resource is read or updated?

TIA for your help.
 
Harish Verma
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Apologies for multiple post creations. I received an error each time I tried to submit and assumed the post didnt make it; but I was wrong and now I see multiple threads in this forum. Apologies again and request admin cleanup. Thanks.
 
Harish Verma
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am adding some more info about this problem.





The log shows the following:
[08.07.2009 15:51:32]-[INFO]-[6]-[ShareableCode]-[isValidUser(): The incoming request contains this session ID: ac10138830fccbac6f25ef034679a9d6d48cfda6ed76]

[08.07.2009 15:51:32]-[INFO]-[6]-[ShareableCode]-[isValidUser(): request.getSession(false) returned a session object with ID=ac10138930fc8cfaed30e56a4df7918aa0cb964cb6c3]

[08.07.2009 15:51:32]-[ERROR]-[6]-[ShareableCode]-[isValidUser(): session.isNew() returned TRUE - the client has probably turned off cookies.]

ac10138830fccbac6f25ef034679a9d6d48cfda6ed76 - this is the session assigned to the user after login.
ac10138930fc8cfaed30e56a4df7918aa0cb964cb6c3 - this appears out of nowhere, 'mapped' to this request.

And so the user ends up at login again, despite having logged in barely a minute ago.

The request is 'wrapped' to another, new session object, despite the presence of the session created during login. Note that request.isRequestedSessionIdValid() is returning TRUE - that's why the code skips to if (session.isNew()) block.

if request.isRequestedSessionIdValid() is true, how come the request is 'wrapped' into a different session? I have googled widely, but cannot pin down where the problem is - Struts, OAS server, or our application code.

Any help is appreciated. TIA.
Harish
 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Harish,

I don't have any familiarity with your system, and very little familiarity with clustering. This question does not appear to be a problem with Threads and Concurrency by itself, but seems more likely caused by clustering/JEE setup and configuration.

Like I said I have no real experience in this area, but I would research 2 things:
1) The session id that is requested is not the same as the one that is returned. This could be because, under high load, the request for any specific user may not be going to the same server. When it gets to the new server the session doesn't exist, so it has to be pulled from whatever store is shared between the clustered servers. This might mean that a new Session ID is assigned. I would check if this is what is happening.

2) If this is the case, it might be that relying on the Session ID to check for current login may not be appropriate. Instead, when a user completes logging in, put a token in the session. Then when you check for valid login simply check for this token. It looks like you might already be doing this with the session.getArrtibute("objUserProfile") check. So one thing to try would be to simplify this entire thing: get rid of the session id checks entirely. The goal, after all is to see if the user is logged in, so check for the token. If it is there, the user is logged in, if not, then the user is not logged in.
 
Harish Verma
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Steve Luke wrote:Hi Harish,

I don't have any familiarity with your system, and very little familiarity with clustering. This question does not appear to be a problem with Threads and Concurrency by itself, but seems more likely caused by clustering/JEE setup and configuration.

Like I said I have no real experience in this area, but I would research 2 things:
1) The session id that is requested is not the same as the one that is returned. This could be because, under high load, the request for any specific user may not be going to the same server. When it gets to the new server the session doesn't exist, so it has to be pulled from whatever store is shared between the clustered servers. This might mean that a new Session ID is assigned. I would check if this is what is happening.

2) If this is the case, it might be that relying on the Session ID to check for current login may not be appropriate. Instead, when a user completes logging in, put a token in the session. Then when you check for valid login simply check for this token. It looks like you might already be doing this with the session.getArrtibute("objUserProfile") check. So one thing to try would be to simplify this entire thing: get rid of the session id checks entirely. The goal, after all is to see if the user is logged in, so check for the token. If it is there, the user is logged in, if not, then the user is not logged in.


Thanks much Steve for your suggestions. There is no store as such that is shared between the servers in the cluster. We rely entirely on the replication process to do the needful for us. Somewhere down the line, the requested session is missing and the server container gives us a new one. In this scenario, getting rid of all the ID checks does not help; the session is brand-new and ofcourse does not contain objUserProfile, so the condition fails anyway and we end up at login. I guess I'll have to ask the client to upgrade their hardware - this is going to get unpleasant. :cry:
 
I've never won anything before. Not even a tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic