That part I understand, but in the example you do:

ctx.pipeline().addLast(someEventExecutorGroup, "handler", new 
MyProtocolHandler());

I'm just curious why using your own ExecutorService inside the handler is 
preferable to adding someEventExecutorGroup to that handler here.  Doesn't 
that achieve the same function?

Also, when you do add a group to a specific handler, is it used 
automatically or do you have to invoke it directly to use it for work like 
this:

ctx.executor().execute/schedule()

On Friday, February 16, 2018 at 12:20:25 AM UTC-8, Sean Bright wrote:
>
> Eric,
>
> I don't know what I can add beyond what has already been written in this 
> thread. I haven't following Netty development so I don't know if this is 
> still the case or not. At the time, a channel was bound to a thread in an 
> EventExecutorGroup, so you could run into a situation where a group of 
> channels that were all bound to the same thread would be under serviced if 
> one of those tasks took a lot of CPU time. If instead you delegate to a 
> standard ExecutorService, each task for a given channel might run on a 
> separate thread so a single task couldn't starve all of the channels.
>
> Kind regards,
> Sean
>
> On Friday, February 9, 2018 at 8:40:00 PM UTC-5, Eric Fulton wrote:
>>
>> Hey sorry I know this is a very old thread, but can you explain why in 
>> you example you think it would be better to use your own ExecutorService 
>> over someEventExecutorGroup?  What would be the difference?
>>
>>
>>
>>
>> On Wednesday, October 9, 2013 at 7:27:06 AM UTC-7, Sean Bright wrote:
>>>
>>> Thanks Norman.
>>>
>>> So based on this, it seems that if I have a "typical" pipeline:
>>>
>>> ctx.pipeline().addLast("decoder", new MyProtocolDecoder());
>>> ctx.pipeline().addLast("encoder", new MyProtocolEncoder());
>>> ctx.pipeline().addLast(someEventExecutorGroup, "handler", new 
>>> MyProtocolHandler());
>>>
>>> Using an EventExecutorGroup doesn't actually buy me anything.  I/O won't 
>>> be blocked, but handler execution will.
>>>
>>> I understand the point of doing all of this - if you know your methods 
>>> will always be called on the same thread it reduces the synchronization 
>>> complexities in the handlers - but in this model when you are dealing with 
>>> hundreds of connections, any handler method that causes a delay in 
>>> processing will block (num_connections / num_event_executor_threads) - 1 
>>> other handlers.
>>>
>>> So it would appear that in order to get the behavior that I want (any 
>>> one connection should not affect another), I would eliminate the 
>>> EventExecutorGroup and would need to submit tasks to an ExecutorService 
>>> that I manage myself, correct?
>>>
>>> I guess I just don't see how an EventExecutorGroup is beneficial.
>>>
>>> In any case, I love Netty.  Keep up the good work!
>>>
>>>
>>> On Tuesday, October 8, 2013 11:40:30 AM UTC-4, Sean Bright wrote:
>>>>
>>>> Greetings,
>>>>
>>>> I just want to validate my understanding of Netty 4's thread model 
>>>> compared to Netty 3's (specifically as it applies to NIO).
>>>>
>>>> With Netty 3, you would specify a boss thread pool and a worker thread 
>>>> pool (all/most of the examples use Executors.newCachedThreadPool() with 
>>>> the 
>>>> default args).  ChannelHandler events would be called on the I/O threads 
>>>> from the worker group.  Any delay in the handler methods would cause a 
>>>> delay in processing I/O for other connections.  In order to compensate for 
>>>> this, you could add an ExecutionHandler to the pipeline which would cause 
>>>> the handler methods to be fired on an executor thread and therefore 
>>>> wouldn't affect I/O.
>>>>
>>>> In Netty 4, you specify a boss group and worker group, and as channels 
>>>> connect they are registered to specific threads.  So channel 1 will always 
>>>> have it's handler events fired on thread A, channel 2 will always have 
>>>> it's 
>>>> handler events fired on thread B.  Again, any delayed processing that 
>>>> occurs in the handler method will hurt I/O for other channels registered 
>>>> to 
>>>> that worker thread.  To compensate, you specify an EventExecutorGroup so 
>>>> that I/O is not affected with long running tasks.
>>>>
>>>> Assuming everything above is correct...
>>>>
>>>> Assume that I create a DefaultEventExecutorGroup, passing 4 as the 
>>>> number of threads, and assign that to my handler in the pipeline.  Now, 8 
>>>> channels connect:
>>>>
>>>> Channel A: EventExecutor 1
>>>> Channel B: EventExecutor 2
>>>> Channel C: EventExecutor 3
>>>> Channel D: EventExecutor 4
>>>> Channel E: EventExecutor 1
>>>> Channel F: EventExecutor 2
>>>> Channel G: EventExecutor 3
>>>> Channel H: EventExecutor 4
>>>>
>>>> Each channel is registered to EventExecutor thread.  If Channel A in 
>>>> the above example performs a long running task (say, in channelRead0), 
>>>> then 
>>>> won't Channel E be blocked during this time?  Is that correct or am I not 
>>>> understanding something?  If I am correct, why would I ever want to use an 
>>>> EventExecutor?  I feel like I would be better off using a shared Executor 
>>>> directly from my handler methods (and handling thread synchronization 
>>>> myself).  At least in that case I wouldn't be blocking other clients.
>>>>
>>>> Thank you,
>>>> Sean
>>>>
>>>>

-- 
You received this message because you are subscribed to the Google Groups 
"Netty discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/netty/d840f140-9459-4d75-8081-7a57408b694a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to