I haven't used NIO in a bit and am struggling to remember: what is the concurrency policy for interacting with Channel
? Are calls to writeAndFlush
and friends synchronized internally, or do I need to ensure I am on the vent loop by calling channel.eventLoop.execute { }
and only call those function in the body of the closure? I don't see anywhere where this is documented.
Doesn't seem to be documented, but IIRC channel writes are thread safe, handler operations are not.
Yes, all Channel
operations are thread safe. Documented on the Channel
docs.
(Conversely, all ChannelHandlerContext
operations must be done on the Channel
's eventLoop
. That seems to unfortunately be missing in the ChannelHandlerContext
docs. It'd be awesome if somebody would like to add a PR adding this.)
Generally: The Channel
itself is completely thread-safe and you can do whatever you want with it. The event-processing inside a Channel
always happens on Channel.eventLoop
. That means you'll only be called on the right EventLoop
and you're expected to not call anything outside of the correct EventLoop
. In return you get performance and you get to manage ChannelHandlerContext
state without locks.
Thanks for the links! I guess my brain is sometimes blind to things in big blocks at the top ;)
One small follow up: is it safe to “escape” a ChannelHandlerContext? For example, saving it in a property of the handler in handlerAdded (and setting it to nil in handlerRemoved) or should they only be used in the body of the handler functions?
That's fine yeah. But you are then responsible for making sure no calls are happening off context.eventLoop === context.channel.evenLoop
. In debug
mode, NIO will police this and crash in assertInEventLoop
.
Said that, I would recommend to not escape it too far (deliberately trying to stay vague here) just to keep the complexity as low as possible. I'd recommend to keep the ChannelPipeline
(which is the list of ChannelHandler
s represented by a ChannelHandlerContext
each) a pipeline. So the information should either flow inbound ('from the network') or outbound ('to the network') and not like spaghettis in a pot .