Support io.Writer / io.Reader #14
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Go's io.Writer and io.Reader have massive support across the ecosystem. In some far-off iroh-go future, it would be amazing if we could somehow wrangle in these interfaces and connect them to the ffi plumbing. This seems hard though? It is also not blocking anything right now. But working with these interfaces would make a lot of small papercuts vanish.
The problems are two-fold: signature mismatches and also implementation expectation mismatches. Currently there are some slight signature mismatches which means iroh-go won't conform to either interface. More importantly, the expected behaviour of calling e.g.
RecvStream.Readas anio.Readervery likely does not match the ecosystem expectation of callingio.Reader: Read(p []byte) (n int, err error).Anyway, far future stuff! Maybe we never get there, even then things here are still very useful :) One type of solution would be to write a middle layer that communicates with the ffi on one hand, and on the other hand has data structures and implementations which fulfill all the go
io:{Read, Write}erinterface expectations. (Maybe what's somewhat happening already? I haven't peeked too much under the hood yet!!)It's great that you're running into this already! I don't think it'd be too hard actually, logistically speaking. Most repos that make use of FFI / uniffi end up writing a wrapper in between bindings and consumers, so this is pretty standard.
I'm playing around with a wrapper that makes error handling less awful in #10 which should be a first example of how it works with wrapping bindings for re-export.
Could you (whenever) sketch out your ideal API based on the code you're writing and what you'd like to encapsulate into the
Reader/Writer? It would be a nice milestone to work towards 🧗♀️That's a super idea! So concretely where I had the idea was in working with a smol wire protocol and needing to send prefixed length byte streams. I was looking to use
encoding/binary:Varintbut then noticed theReadandWritemethods. If I could've passed in a reader / writer fromiroh-goto these, I would've (I think?) been saved a little confusion and wrangling!I'll have to return to this for an a good API sketch because I'm still finding my way. But an early minimal idea maybe:
io.Read(p []byte) (n int, err error)io.Writer.Write(p []byte) (n int, err error)But maybe it's hard / not worth the wrangling to change
WriteandReadon these core iroh abstractions, so perhaps a compromise might be to wrap what already exists à laNewReader,NewWriterconventions:Thanks @cblgh 👏 And last thing, can you copy/pasta in the "current code"? You wrote
But I miss the code of what you're doing right now? Then we have the full picture.
Sure! I just refactored the relevant bits into a util so that I could reuse the same logic on client & server
MAY CONTAIN BUGS :) :)
hope it helps!
Reference: