0
# Platform Optimization
1
2
Platform-optimized networking components that automatically select the best EventLoopGroup and Channel implementations for the current operating system.
3
4
## Capabilities
5
6
### EventLoopGroupProxy
7
8
Wrapper class that transparently selects optimal EventLoopGroup implementations based on the current platform, maximizing network performance.
9
10
```kotlin { .api }
11
/**
12
* Transparently allows for the creation of EventLoopGroups utilizing the optimal implementation for
13
* a given operating system, subject to availability, or falling back to NioEventLoopGroup if none is available
14
*/
15
class EventLoopGroupProxy(
16
val channel: KClass<out ServerSocketChannel>,
17
group: EventLoopGroup
18
) : EventLoopGroup by group {
19
20
/**
21
* Server socket channel class used by this event loop group
22
*/
23
val channel: KClass<out ServerSocketChannel>
24
25
companion object {
26
/**
27
* Create optimal EventLoopGroup for the current platform
28
* @param parallelism Number of threads in the event loop group
29
* @return EventLoopGroupProxy with optimal implementation for current OS
30
*/
31
fun create(parallelism: Int): EventLoopGroupProxy
32
}
33
}
34
```
35
36
**Platform Selection Logic:**
37
38
The EventLoopGroupProxy automatically selects the best implementation based on availability:
39
40
1. **macOS**: KQueueEventLoopGroup with KQueueServerSocketChannel (native kqueue)
41
2. **Linux**: EpollEventLoopGroup with EpollServerSocketChannel (native epoll)
42
3. **Fallback**: NioEventLoopGroup with NioServerSocketChannel (cross-platform NIO)
43
44
**Usage Examples:**
45
46
```kotlin
47
import io.ktor.server.netty.*
48
49
// Automatic platform optimization
50
val eventLoopGroup = EventLoopGroupProxy.create(parallelism = 8)
51
52
// The proxy automatically selects:
53
// - macOS: KQueueEventLoopGroup + KQueueServerSocketChannel
54
// - Linux: EpollEventLoopGroup + EpollServerSocketChannel
55
// - Others: NioEventLoopGroup + NioServerSocketChannel
56
57
println("Selected channel type: ${eventLoopGroup.channel}")
58
59
// Use in server configuration
60
val configuration = NettyApplicationEngine.Configuration().apply {
61
configureBootstrap = {
62
// The engine will automatically use the optimal channel class
63
// No manual configuration needed
64
}
65
}
66
```
67
68
### Platform Channel Selection
69
70
Utility function that determines the optimal ServerSocketChannel implementation for the current platform.
71
72
```kotlin { .api }
73
/**
74
* Get optimal ServerSocketChannel class for the current platform
75
* @return KClass of the most suitable ServerSocketChannel implementation
76
*/
77
internal fun getChannelClass(): KClass<out ServerSocketChannel>
78
```
79
80
**Platform Mapping:**
81
- **macOS**: `KQueueServerSocketChannel::class` (native kqueue I/O)
82
- **Linux**: `EpollServerSocketChannel::class` (native epoll I/O)
83
- **Windows/Other**: `NioServerSocketChannel::class` (standard NIO)
84
85
### Performance Characteristics
86
87
Each platform-optimized implementation provides different performance characteristics:
88
89
**KQueue (macOS):**
90
- Native kqueue-based I/O
91
- Optimal for macOS systems
92
- Low CPU overhead for connection management
93
- Excellent scalability for concurrent connections
94
95
**Epoll (Linux):**
96
- Native epoll-based I/O
97
- Optimal for Linux systems
98
- Superior performance for high-throughput scenarios
99
- Efficient handling of large numbers of file descriptors
100
101
**NIO (Cross-platform):**
102
- Java NIO-based implementation
103
- Works on all platforms
104
- Reasonable performance for most use cases
105
- Fallback when native implementations unavailable
106
107
### Automatic Detection and Fallback
108
109
The system automatically detects platform capabilities and falls back gracefully:
110
111
```kotlin
112
// Detection logic (internal)
113
val eventLoopGroup = when {
114
KQueue.isAvailable() -> {
115
println("Using native KQueue transport (macOS)")
116
EventLoopGroupProxy(
117
KQueueServerSocketChannel::class,
118
KQueueEventLoopGroup(parallelism, threadFactory)
119
)
120
}
121
122
Epoll.isAvailable() -> {
123
println("Using native Epoll transport (Linux)")
124
EventLoopGroupProxy(
125
EpollServerSocketChannel::class,
126
EpollEventLoopGroup(parallelism, threadFactory)
127
)
128
}
129
130
else -> {
131
println("Using NIO transport (cross-platform)")
132
EventLoopGroupProxy(
133
NioServerSocketChannel::class,
134
NioEventLoopGroup(parallelism, threadFactory)
135
)
136
}
137
}
138
```
139
140
### Thread Pool Configuration
141
142
The EventLoopGroupProxy creates event loop groups with proper thread naming and daemon thread configuration:
143
144
```kotlin
145
// Example of internal thread factory usage
146
val threadFactory = DefaultThreadFactory(EventLoopGroupProxy::class.java, true)
147
148
// Thread naming pattern: "EventLoopGroupProxy-<number>"
149
// Daemon threads: true (won't prevent JVM shutdown)
150
```
151
152
### Resource Management
153
154
EventLoopGroupProxy properly implements the EventLoopGroup interface with delegation, ensuring proper resource cleanup:
155
156
```kotlin
157
// Proper shutdown in server lifecycle
158
try {
159
// Server operations
160
} finally {
161
// Graceful shutdown with timeout
162
eventLoopGroup.shutdownGracefully(
163
quietPeriod = 1000, // 1 second quiet period
164
timeout = 5000, // 5 second timeout
165
unit = TimeUnit.MILLISECONDS
166
).await()
167
}
168
```
169
170
### Integration with Netty Configuration
171
172
The platform optimization integrates seamlessly with custom Netty bootstrap configuration:
173
174
```kotlin
175
val configuration = NettyApplicationEngine.Configuration().apply {
176
configureBootstrap = {
177
// Platform-optimized channel class is automatically selected
178
// Additional options can be configured as needed
179
180
option(ChannelOption.SO_BACKLOG, 1024)
181
option(ChannelOption.SO_REUSEADDR, true)
182
183
childOption(ChannelOption.TCP_NODELAY, true)
184
childOption(ChannelOption.SO_KEEPALIVE, true)
185
186
// Platform-specific optimizations
187
when {
188
Epoll.isAvailable() -> {
189
childOption(EpollChannelOption.TCP_KEEPCNT, 5)
190
childOption(EpollChannelOption.TCP_KEEPIDLE, 300)
191
childOption(EpollChannelOption.TCP_KEEPINTVL, 60)
192
}
193
}
194
}
195
}
196
```
197
198
### Performance Monitoring
199
200
Access to platform-specific performance metrics and monitoring:
201
202
```kotlin
203
// Check which transport is being used
204
fun getTransportInfo(eventLoopGroup: EventLoopGroupProxy): String {
205
return when (eventLoopGroup.channel) {
206
KQueueServerSocketChannel::class -> "KQueue (native macOS)"
207
EpollServerSocketChannel::class -> "Epoll (native Linux)"
208
NioServerSocketChannel::class -> "NIO (cross-platform)"
209
else -> "Unknown transport"
210
}
211
}
212
213
// Usage in monitoring/health checks
214
get("/transport-info") {
215
val transportInfo = getTransportInfo(eventLoopGroup)
216
call.respondText("Transport: $transportInfo")
217
}
218
```