Skip to content

Commit 0f4c110

Browse files
authored
Combine the two NIOAsyncChannel channel handlers (#2779)
Motivation: The NIOAsyncChannel allocates 12 times on init. 4 of these allocations come from creating two channel handlers and two channel handler contexts. There's no inherent reason that these channel handlers can't be combined to eliminate two allocations (one handler and one context). Modifications: - Combine `NIOAsyncChannelInboundStreamChannelHandler` and `NIOAsyncChannelOutboundWriterHandler` into a single `NIOAsyncChannelHandler`. Most of this was straightforward as only a few handler operations were duplicated across both. - Add a 'NIOAsyncChannelHandlerWriterDelegate' in place of the 'NIOAsyncChannelOutboundWriterHandler.Delegate'. One knock on from this is that the new delegate stores callbacks rather than the concrete type of the handler. This is necessary to prevent the generics from the new channel handler bubbling up to the outbound writer (which would break API and be somewhat odd). Result: Fewer allocations
1 parent 8631602 commit 0f4c110

11 files changed

+292
-378
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"mallocCountTotal" : 12
2+
"mallocCountTotal" : 10
33
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"mallocCountTotal" : 12
2+
"mallocCountTotal" : 10
33
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"mallocCountTotal" : 12
2+
"mallocCountTotal" : 10
33
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"mallocCountTotal" : 12
2+
"mallocCountTotal" : 10
33
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"mallocCountTotal" : 12
2+
"mallocCountTotal" : 10
33
}

Sources/NIOCore/AsyncChannel/AsyncChannel.swift

+29-8
Original file line numberDiff line numberDiff line change
@@ -315,16 +315,27 @@ extension Channel {
315315
) throws -> (NIOAsyncChannelInboundStream<Inbound>, NIOAsyncChannelOutboundWriter<Outbound>) {
316316
self.eventLoop.assertInEventLoop()
317317

318-
let inboundStream = try NIOAsyncChannelInboundStream<Inbound>.makeWrappingHandler(
319-
channel: self,
318+
let handler = NIOAsyncChannelHandler<Inbound, Inbound, Outbound>(
319+
eventLoop: self.eventLoop,
320+
transformation: .syncWrapping { $0 },
321+
isOutboundHalfClosureEnabled: isOutboundHalfClosureEnabled
322+
)
323+
324+
let inboundStream = try NIOAsyncChannelInboundStream(
325+
eventLoop: self.eventLoop,
326+
handler: handler,
320327
backPressureStrategy: backPressureStrategy,
321328
closeOnDeinit: closeOnDeinit
322329
)
330+
323331
let writer = try NIOAsyncChannelOutboundWriter<Outbound>(
324-
channel: self,
332+
eventLoop: self.eventLoop,
333+
handler: handler,
325334
isOutboundHalfClosureEnabled: isOutboundHalfClosureEnabled,
326335
closeOnDeinit: closeOnDeinit
327336
)
337+
338+
try self.pipeline.syncOperations.addHandler(handler)
328339
return (inboundStream, writer)
329340
}
330341

@@ -338,17 +349,27 @@ extension Channel {
338349
) throws -> (NIOAsyncChannelInboundStream<ChannelReadResult>, NIOAsyncChannelOutboundWriter<Never>) {
339350
self.eventLoop.assertInEventLoop()
340351

341-
let inboundStream = try NIOAsyncChannelInboundStream<ChannelReadResult>.makeTransformationHandler(
342-
channel: self,
352+
let handler = NIOAsyncChannelHandler<Channel, ChannelReadResult, Never>(
353+
eventLoop: self.eventLoop,
354+
transformation: .transformation(channelReadTransformation: channelReadTransformation),
355+
isOutboundHalfClosureEnabled: isOutboundHalfClosureEnabled
356+
)
357+
358+
let inboundStream = try NIOAsyncChannelInboundStream(
359+
eventLoop: self.eventLoop,
360+
handler: handler,
343361
backPressureStrategy: backPressureStrategy,
344-
closeOnDeinit: closeOnDeinit,
345-
channelReadTransformation: channelReadTransformation
362+
closeOnDeinit: closeOnDeinit
346363
)
364+
347365
let writer = try NIOAsyncChannelOutboundWriter<Never>(
348-
channel: self,
366+
eventLoop: self.eventLoop,
367+
handler: handler,
349368
isOutboundHalfClosureEnabled: isOutboundHalfClosureEnabled,
350369
closeOnDeinit: closeOnDeinit
351370
)
371+
372+
try self.pipeline.syncOperations.addHandler(handler)
352373
return (inboundStream, writer)
353374
}
354375
}

0 commit comments

Comments
 (0)