views:

181

answers:

2

Scenario: Apache Wicket based web application running on Tomcat server.

User opens URL in browser, session is created and simple main page is shown in browser, user clicks on button and AJAX call is invoked. Application gets request and doing some stuff preparing response. In same time user or JavaScript in browser invokes another AJAX call -- this second requests is processed in another thread in application, and because most parts of application are session specific and aren't thread-safe (because one user = one session), exception throws.

Possible solutions:

  1. make all application classes thread-safe (very costly)

  2. adapt GUI so no simultaneously runs two AJAX calls in one session (not possible due nature of browser GUI)

  3. synchronize all requests in one session on Wicket or Tomcat level (but how?)

  4. another practice or technique ???

Thanks

+2  A: 

What is the exception that is thrown? If an exception is thrown then I would assume that there is a critical section of the Session object that needs to be synchronized or handled with more care and maybe not the entire session.

I have not had reason to utilize them much, but I know there are channels as part of the wicket-ajax.js (found in org.apache.wicket.ajax package). These control how multiple AJAX calls are handled. They might be worth a look. In this file is the following comment:

/**
 * Channel management
 *
 * Wicket Ajax requests are organized in channels. A channel maintain the order of 
 * requests and determines, what should happen when a request is fired while another 
 * one is being processed. The default behavior (stack) puts the all subsequent requests 
 * in a queue, while the drop behavior limits queue size to one, so only the most
 * recent of subsequent requests is executed.
 * The name of channel determines the policy. E.g. channel with name foochannel|s is 
 * a stack channel, while barchannel|d is a drop channel.
 *
 * The Channel class is supposed to be used through the ChannelManager.
 */
Matt
I think that specific exception is irrelevant, in fact it was ConcurrentModificationException. More important is that code which is not thread-safe by design was called simultaneously from two threads. I want to block this preferably at Wicket level. I don't want to change all application logic.
mschayna
Are you modifying the same data? I know in our applications we have gone to good lengths to utilize Wicket's model objects rather than putting things in our session. We have some things in our session, but not a lot.
Matt
Finally: it was concurrent access from thread processing the request and another thread which was fired in another previously processed request. Wicket (I belive) really synchronizes requests from same page. Thanks.
mschayna
+2  A: 

Requests to pages or components within the same PageMap in a single Session are already synchronous - only one thread at a time. Requests for resources like images, javascript, css files etc. are handled asynchronously. (Different clients never block each other as each client has its own Session and PageMap).

However, access to items in the Session itself, I believe, are not explicitly synchronized.

Incidentally, accessing the Session/Pages from a thread which is not a Request Thread is not a good idea, as the container is free to do anything with your Session/Page between requests - e.g. write it out to disk etc.

alasdairg
As you mentioned, finally it was concurrent access from thread processing the request and another thread which was fired in another previously processed request. Wicket (I belive) really synchronizes requests from same page. Thank you.
mschayna