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.