Events
Yang Zhang
yanghatespam at gmail.com
Mon Jun 8 03:28:05 EDT 2009
이희승 (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.
Another example:
class Thing {
synchronized public void foo() {
Callback callback = new Callback() {
public void callback(Result x) {
synchronized(object) { Thing.this.handle(x); }
}
};
doSomethingAsynchronous(..., callback);
}
synchronized public void handle(Result r) { ... }
}
The innocuous attempt to synchronize (serialize) accesses to the Thing
lead this fragment to halt, given the current framework semantics.
>
>>>> The blocking syscall (e.g. select) made at the core of any asynchronous
>>>> IO framework comes with a timeout parameter, which the framework can use
>>>> for asynchronous sleeps. The framework manages a priority queue of
>>>> "sleep" events, and wakes them up at the appropriate times using this
>>>> timeout mechanism.
>>> This is only true when you use select().
>> Or poll, or epoll, or kqueue (kevent()), or asio (asio_suspend()), or....
>>
>>> You can't make such an
>>> assumption either because Netty API is not necessarily supposed to use
>>> selector API only. For example, a new Netty transport can be
>>> implemented with old blocking I/O and JDK 7 asynchronous I/O API, and
>>> therefore it's not a viable option to integrate the timeout feature into
>>> the core out of the box.
>> With blocking IO, you use a separate thread per blocking event (in this
>> case, delays) - so again, the callback would not need to fire
>> recursively in the same call stack.
>>
>> I'm unfamiliar with the JDK7 API, but I would be surprised if it did not
>> have timeouts as well.
>
> I agree that select/epoll/... can be used to implement application
> timeout by specifying poll timeout (Selector.select(long timeout) in Java).
>
> JDK 7 AIO allows you to specify read/write timeout, but I'm not sure if
> it's related with application event timeout scheduling:
>
> * http://tinyurl.com/njh6l6
Yes, you can simply use the timeout of any single one of the
asynchronous reads/writes.
>
> BTW, I think you are mixing two issues - recursive calls and timeouts.
> Non-recursive calls can be achieved without timeouts and vice versa. Is
> there any reason they need to be implemented in a tightly coupled manner?
No, and in fact in my original email I did distinguish the two,
mentioning delays only parenthetically.
--
Yang Zhang
http://www.mit.edu/~y_z/
More information about the netty-users
mailing list