Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [servlet-dev] AsyncContext.complete() whilst red/write blocked



On Tue, 1 Dec 2020 at 19:50, Greg Wilkins <gregw@xxxxxxxxxxx> wrote:

On Mon, 30 Nov 2020 at 22:44, Stuart Douglas <sdouglas@xxxxxxxxxx> wrote:
Is this RESTEasy doing this, or a user app written against RESTEasy? AFAIK RESTEasy won't start its own threads after suspending, so it sounds like this might be a user app that has created the multiple threads?
Ah the OP now says they can change their error handling, so not a function of RESTEasy.... but still something applications can do.
 
In general you should unblock the thread, because blocking a thread indefinitely is not nice.
yes - but how to do so safely.

This case sounds like it's the applications fault, but consider an app that calls start async, ...
... Consider the following case:
 
I think your example is a simple reduction of the generalization of this issue.   Ie that we have undefined behavior with regards to parallelism between an incomplete IO operation (eg blocking read by non container thread) and container dispatched actions (onTimeout in Stuart's example and onComplete in mine).

As it stands I don't think we can fix this with a simple clarification, as IMHO there are fundamental issues here.

The paths I can see to make this better:
  • Just describe these situations, say they are undefined behaviour and point to patterns to avoid them. 
  • We say that containers should not dispatch any action (onComplete, onError, onTimeout) whilst an IO operation is in progress.  This probably would help but would likely result in a great big lock that needs to be grabbed for every operation. It also might make it harder to have independent read/write sides
I don't think that really helps that much though, as having two threads even attempting to operate on the same response is a recipie for undefined behaviour. Say we have the timeout and the user thread both trying to write a response at the same time, they both call setContentLength(), and say the user thread runs it after the timeout thread so the users content length ends up winning. Then the timeout thread actually writes its data and before the user thread so the sent data does not match the content-length. Locks don't really help here because the fundamental issue is that two threads could be trying to write two fundamentally different responses (even if you lock on write() you could just end up with interleaved content in the same response).
 
  • Offer a new mechanism of a Runnable that is executed or failed with the same serialized semantics of a container action. Ie the Runnable will not be executed in parallel with any container thread calling any dispatch or onFooBar callback.  Effectively make any Runnable the equivalent of a thread dispatched into the servlet, so that any complete actions only take place once it returns.
+1

This is actually how the Undertow Core API deals with thread safety, it basically has a dispatch mechanism so you can start work that won't be executed until the currently executing thread is done with the exchange.
 

Note also, I think there is a related problem with async IO operations.   If isReady() has returned false, then should onError be called if complete() is called? Or should the complete() be deferred until after the IO operation has timed out?   Either way it is kind of ugly as the caller of complete will have has setup the response as they want it and the onError call is likely to write all over that or even call dispatch.  So perhaps in this case it is better not to call onError and just say that a call to onComplete is a signal of the cancellation of any outstanding async IO operations.

I think we need to deal with all of these issues together. They are all fairly complex to do properly and I think it is very difficult to be 100% safe with the current API (you basically need a big coarse grained lock over all request processing). 

Stuart
 

cheers
 

--
_______________________________________________
servlet-dev mailing list
servlet-dev@xxxxxxxxxxx
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/servlet-dev

Back to the top