Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Move Isolated EL operations to EL protocol #3070

Merged
merged 4 commits into from
Jan 20, 2025

Conversation

Lukasa
Copy link
Contributor

@Lukasa Lukasa commented Jan 17, 2025

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.

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.
@Lukasa Lukasa added the 🔨 semver/patch No public API change. label Jan 17, 2025
Copy link
Contributor

@glbrntt glbrntt left a 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)
Copy link
Contributor

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 { ... }?

Copy link
Contributor Author

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.

Copy link
Contributor

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)
    }
}

Copy link
Contributor Author

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.

Copy link
Contributor

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.

@Lukasa Lukasa enabled auto-merge (squash) January 20, 2025 13:43
@Lukasa Lukasa merged commit 77c1b79 into apple:main Jan 20, 2025
34 of 35 checks passed
@Lukasa Lukasa deleted the cb-move-isolated-el-operations-to-protocol branch January 20, 2025 14:11
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
🔨 semver/patch No public API change.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants