apple / swift-nio

Event-driven network application framework for high performance protocol servers & clients, non-blocking.
https://swiftpackageindex.com/apple/swift-nio/documentation
Apache License 2.0
8k stars 652 forks source link

think about if we want easier, more high-level byte writing APIs #14

Open weissi opened 6 years ago

weissi commented 6 years ago

suggested by @ddunbar

SwiftNIO might be appealing to developers of network servers that need good but maybe not the best network performance. In these cases, the allocate ByteBuffer, accumulate, ctx.write, ..., ctx.flush might be a bit awkward. A simpler API might also be a good starting point. For ChannelHandlers with OutboundOut = ByteBuffer, @ddunbar proposed the following API:

ctx.writeWithStream { stream in
    stream <<< “this” <<< Format.asJSON(…) <<< “bla bla bla”
}

which would basically do:

{
    var buf = ctx.channel.allocate(capacity: 256 /* random guess */)
    buf.write(staticString: "this")
    buf.write(bytes: Format.asJSON(...)) // Format.asJSON is actually more sophisticated than that. It returns a "formatter", which is a struct which knows how to render the output as JSON directly onto the stream. This avoids creating unnecessary temporary allocations of the JSON data.
    buf.write(staticString: "bla bla bla")
    return ctx.write(self.wrapOutboundOut(.byteBuffer(buf)))
}()

and I guess we could also offer a ctx.writeAndFlushWithStream API. Or maybe ctx.writeWithStream(flush: Bool = false, (Stream) -> EventLoopPromise<()>) -> EventLoopPromise<()> 🤔.

The custom <<< operator would be defined for everything we accept: ByteBuffer, (Contiguous)Collection of UInt8, String, StaticString, the various integers, ...

We should definitely evaluate having such a more high-level API.

This should probably live in some yet to be created NIOExtras module. And we need to think about how to make it perform well and in an unsurprising way.

weissi commented 6 years ago

@ddunbar any input here? The 2.0 development work will start shortly

ddunbar commented 6 years ago

We don't have any strong need for this, it was just an idea. It would be easy to experiment by writing a SwiftPM OutputByteStream implementation which targets a channel, to see what the ergonomics of it are like.

Davidde94 commented 3 years ago

@weissi @Lukasa is this something we still want to do?

Lukasa commented 3 years ago

Yeah, I think so.

weissi commented 3 years ago

We could also trial a few implementations of this in a new NIOExtrasWhatever package. Not sure if we should add a new operator to NIO, it may have source breakage potential for users if they're in love with operators.

But I also think we should try something in this space.