-
Notifications
You must be signed in to change notification settings - Fork 721
Move Isolated EL operations to EL protocol #3070
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
Move Isolated EL operations to EL protocol #3070
Conversation
Motivation
Right now the isolated view on the EventLoop has to implement
its interface in terms of UnsafeTransfer, because there are no
non-Sendable operations it can use.
That hurts us because we have to allocate an extra closure for all
these operations, making them slower than they need to be. This
is unavoidable in some contexts, but most EventLoops would be able
to offer a fast-path that avoids this extra allocation.
To achieve that, we need to move this logic into a customisation
point on the EventLoop protocol. Our fallback default implementation
can be the same as we do today.
Modifications
- Add customisation points for EventLoop for each of its operations
that has a protocol witness already.
- Add default implementations of these, using the implementation
from EventLoop.Isolated.
Results
No behavioural changes, but the code has moved.
glbrntt
left a comment
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.
Couple of questions but looks good otherwise
| let promise: EventLoopPromise<T> = self._wrapped.makePromise(file: file, line: line) | ||
| let scheduled = self.scheduleTask(deadline: deadline, task) | ||
|
|
||
| scheduled.futureResult.flatMap { $0 }.cascade(to: promise) |
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.
Can we save an alloc here if we use scheduled.futureResult.whenComplete { ... }?
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 don't think so: the flatMap unwraps an extra level of futureness.
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 mean like this (I appreciate it's more code than the flatMap + cascade):
scheduled.futureResult.whenComplete { result in
switch result {
case .success(let futureResult):
promise.completeWith(futureResult)
case .failure(let error):
promise.fail(error)
}
}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, you're probably right. However, all the flatScheduleTask implementations in swift-nio follow this spelling. I've filed #3071 to track making the improvement generically, and so for now would rather keep this in line with the others.
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.
Thanks for filing that, makes sense to track them together.
Motivation
Right now the isolated view on the EventLoop has to implement its interface in terms of UnsafeTransfer, because there are no non-Sendable operations it can use.
That hurts us because we have to allocate an extra closure for all these operations, making them slower than they need to be. This is unavoidable in some contexts, but most EventLoops would be able to offer a fast-path that avoids this extra allocation.
To achieve that, we need to move this logic into a customisation point on the EventLoop protocol. Our fallback default implementation can be the same as we do today.
Modifications
Results
No behavioural changes, but the code has moved.