Skip to content
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

thread configuration (names & QoS on Darwin) #2943

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

weissi
Copy link
Member

@weissi weissi commented Oct 23, 2024

Motivation:

For the longest time, NIO only had internal APIs to choose the thread names and on Darwin, there was no way to assign the NIO threads certain QoS classes. That meant that on Darwin (e.g. macOS) you would always get poor latencies with NIOPosix, particularly on Apple Silicon machines where NIO might sometimes be restricted to the E-cores.

Modifications:

  • Introduce NIOThreadConfiguration which lets you configure a thread name prefix & QoS on Darwin

Result:

  • More control for the users.

@weissi weissi requested a review from Lukasa October 23, 2024 13:57
@weissi weissi added the 🆕 semver/minor Adds new public API. label Oct 23, 2024
Lukasa pushed a commit that referenced this pull request Oct 23, 2024
### Motivation:

On Darwin, QoS (quality of service) of threads plays an important role,
especially on Apple Silicon machines with P-cores and E-cores. If you
spawn raw threads (like NIOPosix) and use a mechanism that doesn't
support QoS propagation (like reading/writing to networks -- like
NIOPosix does), it's recommended to default to the main thread's QoS.

Otherwise you'll always be at the default QoS for "legacy" threads which
means bad latencies, especially on Apple Silicon machines.

In a follow-up PR #2943 we're adding better configurability for thread
configuration.

### Modifications:

Default to main thread QoS on Darwin.

### Result:

Better latencies for applications with higher QoS classes.
@@ -70,7 +70,7 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
private let index = ManagedAtomic<Int>(0)
private var eventLoops: [SelectableEventLoop]
private let shutdownLock: NIOLock = NIOLock()
private let threadNamePrefix: String
private let threadNamePrefix: String?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still used?

@@ -108,7 +108,8 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
}

private static func setupThreadAndEventLoop(
name: String,
name: String?,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come name is optional now?

#endif

public struct NIOThreadConfiguration: Sendable {
public var threadNamePrefix: Optional<String>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you document how this is used and the recommendations for its value? I know from looking at some examples that "-" is necessary for the various groupings and also that the prefix should be reasonably short.

Can you document what nil means in this context too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🆕 semver/minor Adds new public API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants