Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Practical value for concurrent-request-timeout parameter or options for avoiding concurrent access to conversation exception

In the Seam Reference Guide, one can find this paragraph:

We can set a sensible default for the concurrent request timeout (in ms) in components.xml:

<core:manager concurrent-request-timeout="500" />

However, we found that 500 ms is not nearly enough time for most of the cases we had to deal with, especially with the severe restriction seam places on conversation access.

In our application we have a combination of page scoped ajax requests (triggered by various user actions), some global scoped polling notification logic (part of the header, so included in every page) and regular links that invoke actions and/or navigate to other pages.

Therefore, we get the dreaded concurrent access to conversation exception way too often, even without any significant load on the site.

After researching the options for quite a bit, we ended up bumping this value to several seconds (we're debating whether to bump it up to 10s), as none of the recommended solutions seemed able to solve our issue completely (even forcing a global queue for all the ajax requests would still leave us exposed to a user deciding to click a link right when one of our polling calls was in progress). And we'd much rather have the users wait for a second or two instead of getting an error page just because they clicked a link at the wrong moment.

And now to the question: is there something obvious we're missing (like a way to allow concurrent access to conversations and taking care of the needed locking ourselves, for instance :)? How do people solve this problem (ajax requests mixed with user driven interaction) in seam? Disabling all the links on the page while ajax requests are in progress (as suggested by one blog page) is really not a viable option.

Any other suggestions?

TIA, Andrei

like image 660
Andrei Avatar asked Feb 27 '23 00:02

Andrei


1 Answers

We use 60000 or 120000 (1-2 minutes). Concurrent-request-timeout is designed to avoid deadlocks. Historically we have far more problems with timeouts than deadlocks. A better approach is to use a client-side queue (<a4j:ajaxQueue> if using RichFaces) to serialize and remove duplicate requests as much as possible, then set the timeout high enough to avoid any remaining problems.

There are many serious issues resulting from Seam's concurrent request timeouts:

  • The issue is the last request gets the ConcurrentRequestTimeoutException. If the user double-clicks or reloads the page, only the last request matters -- why should he get an error?
  • Usually the ConcurrentRequestTimeoutException is suppressed, and only secondary NullPointerExceptions and @In injection failures are shown, making debugging difficult.
  • Seam 2.2.1 has a severe problem where transactions, ThreadLocals, and locks may leak after a timeout occurs, especially when used with <spring:spring-transaction/>. Look at SeamPhaseListener.afterRestoreView: there's no finally block to clean up after restoreConversation fails!

In my opinion there are many poor aspects to this design, so it's best to use a much higher timeout and try to avoid the issues.

like image 78
Peter Davis Avatar answered May 16 '23 06:05

Peter Davis