Hi, the current DataTransport protocol works but could be improved in some ways. (You might already have planned to do so as part of your async work?)
- The
setReaderHandler function means that the constructor doesn't have access to the reader, which means the class variable holding the reader has to be declared optional, which means the code gets complicated by checks to see if it has been set.
- The
write function isn't declared throws, meaning that it's forced to report errors through a side channel. It's also not compatible with async except with fire-and-forget or reporting back through a side channel.
- Errors during read also have to be reported through a side channel, meaning that
ProtocolTransport or other objects taking a DataTransport as an input either have to be made aware of the side channel somehow, or will be oblivious to errors.
One way of addressing the above might be to make the protocol look more like this:
public protocol DataTransport {
typealias ReadHandler = (Data) async throws -> Void
func write(_ data: Data) async throws -> Void
func readLoop(_ onData: @escaping ReadHandler) async throws -> Never
}
write should be self-explanatory. readLoop would keep reading until the Task is cancelled, which would replace the close function in the current protocol version. And the reader, too, can throw if there's a problem. (I think it best for the function to never return and throw on EOF, to make EOF handling more explicit and so that there is only one way for the loop to exit, but this is more or less a matter of taste.)
The ReadHandler in the proposal is also changed to allow throw and async. I think this would let us eventually remove the dispatch queue we talked about on #2 and enable adding backpressure. Implementing that change could be left for another time, but I figured it best to change the protocol already in the interest of keeping breaking changes to a minimum.
All of this obviously isn't compatible with Swift <5.5, I'm not sure how big of a problem that is to you. Nothing speaking against dropping compatibility from my end, but you might have other plans.
Curious to hear what you think about all this.