ByteBuffer.withUnsafeReadableBytes does not accept async closures
#2,630 建立於 2024年1月24日
描述
I haven't found a template for feature request, improvement or question, thus adding it as blank one.
Recently, there is NIOAsyncChannel was added to swift-nio. It is very convenient to use it with swift concurrency.
However, sometimes it is hard to dial with ByteBuffer without async interface, such as ByteBuffer.withUnsafeReadableBytes that accepts async closure.
I have the following use case:
let channel = try await ClientBootstrap(group: Self.eventLoopGroup)
.connect(host: ipAddress, port: port) { channel in
channel.eventLoop.makeCompletedFuture {
try channel.pipeline.syncOperations.addHandler(ByteToMessageHandler(StreamDecoder(self.logger)))
return try NIOAsyncChannel(
wrappingChannelSynchronously: channel,
configuration: .init(
backPressureStrategy: .init(lowWatermark: 5, highWatermark: 10),
inboundType: ByteBuffer.self))
}
}
try await channel.executeThenClose { inbound in
for try await buffer in inbound {
try await buffer.withUnsafeReadableBytes { ptr in // cannot use it here because withUnsafeReadableBytes does not support swift concurrency
header = ProtocolHeader(ptr) // some protocol that accepts UnsafeRawBufferPointer
try await hander.handleMessage(header)
}
}
}
Thus I have to copy memory from ByteBuffer which I believe is not efficient:
try await channel.executeThenClose { inbound in
for try await buffer in inbound {
let buf = buffer.withUnsafeReadableBytes { buf in
// Workaround, no async method in ByteBuffer...
let newBuf = UnsafeMutableRawBufferPointer.allocate(byteCount: buf.count, alignment: 8)
newBuf.copyBytes(from: buf)
return newBuf
}
defer {
buf.deallocate()
}
header = ProtocolHeader(UnsafeRawBufferPointer(buf))
try await hander.handleMessage(header)
}
}
I am looking for a good solution here. The easiest way from my point of view seems to allow async withUnsafeReadableBytes.
However, it might be not inline with its design, therefore I am looking for a good way to solve the issue.
Could you advise on above, please?