Events

"이희승 (Trustin Lee)" trustin at gmail.com
Mon Jun 8 06:34:44 EDT 2009


On 08-Jun-2009 19:03, Yang Zhang wrote:
> 이희승 (Trustin Lee) wrote:
>> On 08-Jun-2009 16:28, Yang Zhang wrote:
>>> 이희승 (Trustin Lee) wrote:
>>>> On 08-Jun-2009 14:11, Yang Zhang wrote:
>>>>> 이희승 (Trustin Lee) wrote:
>>>>>> On 07-Jun-2009 16:46, Yang Zhang wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> 이희승 (Trustin Lee) wrote:
>>>>>>>> You can issue a new event by calling Channels.fireXXX(...),
>>>>>>>> ChannelPipeline.sendUpstream/Downstream(...), or
>>>>>>>> ChannelHandlerContext.sendUpstream/Downstream(...).  However, the
>>>>>>>> call
>>>>>>>> is made recursively.
>>>>>>> The fact that the call is made recursively is problematic: the code
>>>>>>> immediately following the async call is expected to immediately
>>>>>>> execute
>>>>>>> (at least, before the callback is executed), but with the recursive
>>>>>>> call, the callback will execute *in the same thread and before* the
>>>>>>> code
>>>>>>> immediately following the call.
>>>>>> In asynchronous I/O, you can't make any assumption on when and how an
>>>>>> asynchronous request will be executed.  The point of the asynchronous
>>>>>> I/O is, IMHO, it returns as quickly as possible, possibly before the
>>>>>> request is processed.
>>>>> It's fine for the async IO to complete before the request is processed
>>>>> (since, as you notice, you have no control over the timing), but the
>>>>> problem here is that it's firing recursively within the same event
>>>>> call
>>>>> stack.
>>>> Could you elaborate on why a recursive event call is a problem?  I
>>>> guess
>>>> I'm missing out something.
>>> The call site must be prepared for the event to not try to execute
>>> concurrently in a way that blocks itself.  A simple example:
>>>
>>>   final SynchronizedQueue<Result> queue = ...;
>>>   Callback callback = new Callback() {
>>>     public void callback(Result x) { queue.put(x); }
>>>   };
>>>   doSomethingAsynchronous(..., callback);
>>>   Result r = queue.get();
>>>
>>> This halts.  The way around this is to push the put or the get into a
>>> separate thread, but that's clumsy at best, requiring the user to either
>>> create a new thread or manage her own thread pool (outside Netty's own
>>> thread pool).  It furthermore requires an extra thread even in
>>> applications that limit themselves to a single event-handling thread.
>>
>> Did you mean SynchronousQueue or just synchronized Queue?  If you meant
>> a plain synchronized queue, it does not halt but can throw an NPE as
>> expected.
>>
>> If SynchronousQueue were used, as you pointed out, it does not work
>> because either put() or get() will wait for get() or put() respectively
>> and Netty usually does not execute callback and handler of the same
>> channel simultaneously.
>>
>> However, it's not a recursive call that causes the race condition but is
>> two dependent tasks being executed in order in the same thread.  How
>> does non-recursive event / callback execution solve this issue?
> 
> You're right that in a single-threaded reactor, this would not be able
> to proceed, so ignore the last sentence that I threw in there.  A
> non-recursive event execution would solve this because the event would
> be fired in a separate thread (assuming that multiple threads can wait
> for events).
> 
> The latter example I gave is probably the stronger of the two.

Ah, I see.  I think the second example is pretty good to describe the
problem IIUC.  I experienced the same issue when I implement SslHandler
actually: http://tinyurl.com/m3dfsb  I worked around the issue by using
Thread.holdsLock().  Your idea would definitely simplify the
implementation.  Not sure how easy it will be to implement your idea
though.  Patch welcome. :)

Thanks,
Trustin

-- 
— Trustin Lee, http://gleamynode.net/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 258 bytes
Desc: OpenPGP digital signature
Url : http://lists.jboss.org/pipermail/netty-users/attachments/20090608/33de25ae/attachment.bin 


More information about the netty-users mailing list