New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce IoHandleEventLoopGroup / IoHandleEventLoop and its implemen… #13991
Conversation
I am opening this a draft mainly because I wanted to show and proof that we can back port some of the changes that we did in main without breaking too much things. I think even thought this PR introduce some API breaking it shouldn’t affect almost any user. To proof this I did not change how we create the different EventLoopGroups in our testsuite and everything still works. So while the old way of constructing Eventloops still work the new way would be a bit different: Old API:
New API:
The benefit of the new way is that it is quite easy to instrument / doctorate an EventLoop/EventLoopGroup now. Basically you can just extend MultiThreadIoHandleEventLoopGroup / SingleThreadIoHandleEventLoop and add all the customization once while be able to reuse it with any transport implementation.
Beside this IoHandleEventLoop can support not only Channel but also other subtypes of IoHandle. This would for example allow us to add file io support with io_uring and still use the same eventloop as for sockets etc. I am sure there are more things we could do by adding this kind of flexibility. With all this said I still think the change is too dangerous for a new 4.1.x release. With this in mind I wondered if we might want to aim for releasing 4.2.0 with the following change:
I would love to hear what other project members and the community think about this ? |
If interested I can also change all the creation code of |
…tations MultiThreadIoHandleEventLoopGroup / SingleThreadIoHandleEventLoop Motivation: At the moment each transport has its own EventLoopGroup and EventLoop implementation. Most of these are final because they are tightly coubled with the specific Channel implementations. This is unfortunate for multiple reasons, as for example: - It's hard to instrument EventLoop* implementations as these are not extensible at all or even if they are the same logic needs to be added to multiple EventLoop* implementations. - Registration / Deregistration is limited to Channels which remove flexibility as for example some Operation Systems allowing to also handle other IO (for example file IO) with something like an EventLoop (one example would be io_uring). - A lot of code-duplication between different EventLoop* implementations exists as most share kind of the same logic of running non IO tasks. Modifications: - Add the concept of IoHandleEventLoopGroup / IoHandleEventLoop and the corrosponding IoHandle, IoHandler and IoHandlerFactory. This allows to only have a custom implement for IO handling per transport while share the same code for execution of tasks, scheduled task and ultimatly IO. - Add the implementations MultiThreadIoHandleEventLoopGroup and SingleThreadIoHandleEventLoop that can be used by all (or most) transport implementations by having these just provide their own IoHandler / IoHandlerFactory implementations. Result: More code sharing and easier of customizing EventLoops.
2620422
to
e9c9852
Compare
Do you plan to align with the design in Netty 5? |
transport-classes-epoll/src/main/java/io/netty/channel/epoll/EpollEventLoop.java
Outdated
Show resolved
Hide resolved
for (EventExecutor e: this) { | ||
((EpollEventLoop) e).setIoRatio(ioRatio); | ||
} | ||
// NOOP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, need to document that this does nothing now
transport-classes-epoll/src/main/java/io/netty/channel/epoll/EpollHandler.java
Outdated
Show resolved
Hide resolved
transport/src/main/java/io/netty/channel/IoExecutionContext.java
Outdated
Show resolved
Hide resolved
Will look into the build timeout later today |
What design you talk about ? The ideas was to introduce the same concept with minimal real world breakage |
I mean split the ioHandler with the event loop, I will take some time to look into this. |
That's exactly what this PR does ;) |
Also I think if we would switch to java8 I could maybe do something more flexible to support different |
@normanmaurer I don't know whether we should discuss this here in this PR but
Have you considered moving out of incubation some of the projects? (io_uring, QUIC, HTTP/3)? |
transport/src/main/java/io/netty/channel/IoHandleEventLoop.java
Outdated
Show resolved
Hide resolved
Yes but let's focus on this one first :) |
I would like to +1 for moving to Java 8 on Netty 4.2.x, as Netty 4.1.x has a very long history, With Java 8's default method, lambda completableFuture, etc., we can achieve more than it is now. We can submit a PR and wait to see if people complain about moving to Java 8 on Netty 4.2.x |
I think we should definitely try or even use 11. Let's discuss about this as a followup. |
I will port things over for for sure |
transport-classes-epoll/src/main/java/io/netty/channel/epoll/EpollEventLoop.java
Outdated
Show resolved
Hide resolved
/** | ||
* {@link EventLoop} which uses epoll under the covers. Only works on Linux! | ||
*/ | ||
public class EpollHandler implements IoHandler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this class need to be public?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it needs to be... that said we should make it final. All the IoHandler
implementations need to be public as you use these to create the factory to inject in the MultiThreadIoEventLoopGroup
.
For example:
var group = new MultiThreadIoEventLoopGroup(NioHandler.newFactory());
Another possibility would be to not make these public but provide a IoHandlerFactory
implementation that is public.
Like this:
var group = new MultiThreadIoEventLoopGroup(new NioHandlerFactory());
This factory would then instance the handles.
@chrisvest @He-Pin @yawkat not sure what is better ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current approach seems fine to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. The factory seems nicer as it limits the escape of additional API but it's not a huge deal either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we are using Java 8 now, so final class with factory would be better.
…easier implementation of IoHandler subtypes without the need to also change the IoHandle
@He-Pin @violetagg @bryce-anderson @idelpivnitskiy @chrisvest @franz1981 @vietj @yawkat @trustin I just pushed more changes... I think from an API point of view I am now consider this done (and everything compiles / pass tests). So what changed from the original PR design:
The nice thing about the new API is really that it is trivial for advanced users to write their own The concept that is used now with I know the changes are non-trivial so thanks to everyone who takes the time for review and providing feedback :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments
transport-classes-epoll/src/main/java/io/netty/channel/epoll/EpollChannelConfig.java
Show resolved
Hide resolved
Thanks a lot for all the reviews.... This is now merged :) |
…ucting it Motiviation: #13991 introduced a new way of how EventLoopGroups should be constructed. We should update our code to use the new way in examples and tests Modifications: Rewrite all tests / example to use new way of constructing Result: Cleanup
…ucting it Motiviation: #13991 introduced a new way of how EventLoopGroups should be constructed. We should update our code to use the new way in examples and tests Modifications: Rewrite all tests / example to use new way of constructing Result: Cleanup
…ucting it Motiviation: #13991 introduced a new way of how EventLoopGroups should be constructed. We should update our code to use the new way in examples and tests Modifications: Rewrite all tests / example to use new way of constructing Result: Cleanup
…ucting it Motiviation: #13991 introduced a new way of how EventLoopGroups should be constructed. We should update our code to use the new way in examples and tests Modifications: Rewrite all tests / example to use new way of constructing Result: Cleanup
…ucting it Motiviation: #13991 introduced a new way of how EventLoopGroups should be constructed. We should update our code to use the new way in examples and tests Modifications: Rewrite all tests / example to use new way of constructing Result: Cleanup
…tations MultiThreadIoHandleEventLoopGroup / SingleThreadIoHandleEventLoop
Motivation:
At the moment each transport has its own EventLoopGroup and EventLoop implementation. Most of these are final because they are tightly coubled with the specific Channel implementations. This is unfortunate for multiple reasons, as for example:
Modifications:
Result:
More code sharing and easier of customizing EventLoops.