-
-
Notifications
You must be signed in to change notification settings - Fork 328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
preliminary wasm32 support for git-pack #735
Conversation
994717e
to
f5e89fe
Compare
@Byron How closely have you been following Wasm/WASI developments? WASI "preview 2" is coming soon, and it changes a lot — in particular, it is being rebased on top of the WebAssembly Component Model. If you are only writing programs that target wasm32-wasi then you won't need to care much about this (other than knowing that when rustc learns about preview 2, you'll be able to do a lot more out of the box, e.g. networking) but if you want to be able to build independently-deployable Wasm modules for different bits of of Gitoxide, then waiting for snapshot2 to land and the surrounding tooling to mature might be worthwhile. What are the main use cases you have in mind? I may be able to sketch a concrete example of what I'm talking about. |
Thanks so much for chiming in @jeffparsons, it's much appreciated! I have updated the PR description to be more informative. Thus far I thought the target must be I am looking forward to hearing how to best do that, I am definitely very green here and only have a minimal understanding of what needs to be done. Thank you |
455af8b
to
4f213b4
Compare
It looks like |
5f079a3
to
f151dda
Compare
For now failure is allowed as no work was done, but this should confirm the crate can at least be compiled to that target. We try different targets, including WASI, for good measure, and already build crates that are naturally working.
…wasm32. It's a breaking change because we also start using the `dep:` syntax for declaring references to optional dependencies, which will prevent them from being automatically available as features. Besides that, it adds the `wasm` feature toggle to allow compiling to `wasm32` targets.
I still don't have a great understanding of how you're intending for this to be used (e.g. what crates it needs to integrate with, the shape of that integration, what assumptions about the world those other crates make), so to start I'll just summarize the main ways I imagine Gitoxide being used with Wasm and my best understanding of what each would look like, and maybe we can explore from there. Hopefully there's something helpful in here... 🤞 (1) Gitoxide is consumed as a crate by other Rust code, targeting core WasmActual compilation target might be Any IO your own code tries to perform will (IIRC) either error or panic; the parts of The other aspect of IO that has to be handled outside of Gitoxide here is calling to/from the host (and other stuff run by the Wasm host, e.g. JavaScript). There are things like wasm-bindgen that allow you to effectively layer an ABI on top of If this is something you want to support, there's no harm in doing it, because support for everything else (Emscripten, WASI, etc.) can be additive. (2) Gitoxide is consumed by JavaScript code via Emscripten on the webCompilation target is This is the one I know the least about. I also think of this as mostly a stopgap, but I don't know enough about what it has to offer to dismiss it out of hand. I imagine that once the WebAssembly Component Model (see below) matures that all the things Emscripten does for Wasm can slowly be split out into WebAssembly Components. (3) Gitoxide is consumed as a crate by other Rust code, targeting WASICompilation target is Now you can actually use IO features from In this scenario, however, you don't care that everything will change under the hood when rustc moves over to targeting (4) Gitoxide is consumed as a WebAssembly componentCompilation target is In this final scenario you are supporting people who want to use Gitoxide from their language of choice, and who are either embedding a Wasm runtime in their program or shipping their own program as a Wasm module (possibly a Wasm Component) to be run in some other runtime, e.g., Wasmtime or a web browser. You would presumably rely on WASI for IO (via You would probably define your Wasm Component's interface using the WIT language, and then use something like cargo-component to define and build your Wasm Components in Rust, and something like jco if you want to help people use it on the web. Wasm and the Component Model are defined in a really neatly layered and modular way, which lets you polyfill/virtualize a lot of things. E.g. if someone wants to use your code in some non-WASI environment, they could use one of the tools available for linking multiple Wasm components together to produce a single Core Wasm binary that, e.g., assumes the presence of Emscripten, or some other virtual system environment altogether. So not everyone needs to jump on supporting WASI or even the Component Model immediately for it to be useful. You could start writing WebAssembly Components very soon, and run them in web browsers years before those web browsers decide they want to introduce native support for WebAssembly Components. ConclusionIf I were making this decision and I didn't have a specific reason to support Emscripten, then I would probably skip that sort of thing entirely. I would start out supporting just (1) and (3), and then as soon as rustc starts targeting On the other hand, if you do have some existing Emscripten based project you'd like to support, or just want to have a web based demo up and running sooner rather than later, supporting Emscripten might not actually be much work — I'm just not familiar enough with it to make any meaningful comment. |
❤️🙏 I have linked this analysis from the tracking the tracking ticket as well to be sure to have it should I venture further down this path. For now, this isn't planned though but I am sure it will eventually happen. 2024, maybe, I should have need for running more code in WASM as well. |
The goal of this PR is to make accelerated pack resolution available in WASM. This includes the following steps
From there it should be possible to have a WASM server receive a pack assuming it has a way to decode the pack into entries.
Maybe the decoding step must be possible here too for convenience.
Tasks
It seems it's best to extract parts into their own crate
Tasks for Extraction
All of what follows should compile as
WASM-unknown-unknown
targetcache::delta::Tree
AtomicBool
for interruptionsio::BufRead
io::Write
crc32
prodash
withArc
andAtomicUsize
for countersKind
andObjectId
EntriesToBytesIter- writes a pack right back to disk for lookup, but there is no diskcache::delta::Tree
- used to see each packed object and its hash for connectivity checks knowing what's in the pack- not needed as the delta::Tree is doing all the work. It does, however, contain the core algorithm on bringing everything together and in theory can be used to create a pack index file in memory.index::File::write_data_iter_to_stream(…)
Research
Blockers: everything with IO, namely
git-lock
andgit-tempfile
libc
seems to support onlywasm32-unknown-emscripten
To circumvent, some crates might have to be split. Problem here is type ownership - WASM compatible crates probably shouldn't own the type in question so must provide pure functions with a lot of parameters or contexts.
There might be duplication of documentation unless these are just referring to each other. It's still a slightly strange setup to have WASM in different crates, but inclusion seems easier to handle than exclusion.
Learnings
wasm32-wasi
seems to generally produce better error messages as it supports more out of the box. This can pinpoint locations where incompatible crates are being used.Interesting Reads
std
andasm
WASI
help?