Skip to content

Support object_store with wasm: Default wasm32-unknown-unknown HttpConnector#329

Merged
tustvold merged 7 commits into
apache:mainfrom
H-Plus-Time:main
Apr 21, 2025
Merged

Support object_store with wasm: Default wasm32-unknown-unknown HttpConnector#329
tustvold merged 7 commits into
apache:mainfrom
H-Plus-Time:main

Conversation

@H-Plus-Time

@H-Plus-Time H-Plus-Time commented Apr 10, 2025

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

What changes are included in this PR?

Target-gated wasm32-unknown-unknown reqwest-based HttpConnector (with explicit handling surrounding non-Send, non-Sync futures).

Are there any user-facing changes?

wasm32-unknown-unknown users will need to add the getrandom = { version = "*", features = ["js"] } cargo entry if they aren't already using it. The alternative would be to feature flag in a similar manner to chrono, getrandom, zstd (i.e. 'js').

Comment thread src/client/body.rs Outdated

@alamb alamb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @H-Plus-Time and @kylebarron -- this looks really neat

I think it is important to have some sort of test for this feature otherwise it is quite likely it will be broken in some future reactor

How did you test this locally? Perhaps we can adapt such a test to run in our CI?

@H-Plus-Time

Copy link
Copy Markdown
Contributor Author

I tested through object-store-wasm (which provided all the wasm-bindgen bindings to create object store instances and so on from JS), but a reasonable approach would be:

  1. A single wasm-bindgen'd method that sets up a simple HttpStore pointing to localhost, and does a selection of simple operations (head, full get, ranged get) on a pre-defined object.
  2. Spin up a http server on localhost (serving static files, specifically that pre-defined object).
  3. Import, instantiate and run that wasm-bindgen'd module in a NodeJS script.

wasm-bindgen-test essentially does 1 and 3, a simple startup and teardown script for the server component would be all that's needed for 2.

It shouldn't be too much trouble, I'll get something basic together in the next few days.

@alamb

alamb commented Apr 16, 2025

Copy link
Copy Markdown
Contributor

Thanks @H-Plus-Time 🙏

(Note I will be out next week so I may be delated in responding)

…2, as well as those that use the MockServer. Very basic test wasm tests, address dropped/unused receiver in wasm bridge code
@H-Plus-Time

H-Plus-Time commented Apr 16, 2025

Copy link
Copy Markdown
Contributor Author

That should do it I think - that one test covers a sizable chunk of the wasm-specific code; put/post requests would be the only other aspect worth testing I think.

Oh, and I'm a little circumspect about including the .cargo/config.toml in source; there's probably not a great way around that, to be honest (the wasm tests fail (quite miserably) without it).

Comment thread .github/workflows/ci.yml
run: cargo build --all-features --target wasm32-wasip1
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Run wasm32-unknown-unknown tests (via Node)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@alamb

alamb commented Apr 16, 2025

Copy link
Copy Markdown
Contributor

kicked off the tests

@alamb

alamb commented Apr 16, 2025

Copy link
Copy Markdown
Contributor

@alamb alamb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me -- thank you very much @H-Plus-Time

Comment thread tests/http.rs

#[cfg(all(feature = "http", target_arch = "wasm32", target_os = "unknown"))]
#[wasm_bindgen_test]
async fn basic_wasm_get() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified this runs in CI: https://github.com/apache/arrow-rs-object-store/actions/runs/14505171194/job/40723998384?pr=329#step:11:138

warning: `object_store` (lib) generated 1 warning
warning: `object_store` (lib test) generated 4 warnings (run `cargo fix --lib -p object_store --tests` to apply 3 suggestions)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.11s
     Running unittests src/lib.rs (target/wasm32-unknown-unknown/debug/deps/object_store-4bf7d6aa80f96256.wasm)
no tests to run!
     Running tests/http.rs (target/wasm32-unknown-unknown/debug/deps/http-0715721c2cebdfb7.wasm)
                                                  
Executing bindgen...                              
                                                  
running 1 test
test basic_wasm_get ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; finished in 0.36s

So looks good to me

@alamb

alamb commented Apr 17, 2025

Copy link
Copy Markdown
Contributor

FYI @kylebarron could you perhaps take a look at this?

Also, FYI @XiangpengHao

@alamb alamb changed the title Default wasm32-unknown-unknown HttpConnector Support object_store with wasm: Default wasm32-unknown-unknown HttpConnector Apr 17, 2025

@kylebarron kylebarron left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Channels always confuse me, but overall looks good.

Comment thread src/client/connection.rs
Comment on lines +237 to +242
use futures::{
channel::{mpsc, oneshot},
SinkExt, StreamExt, TryStreamExt,
};
use http_body_util::{Empty, StreamBody};
use wasm_bindgen_futures::spawn_local;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: move imports to the top of this scope? E.g. before the req.into_parts line?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yep - I must have started from a copy-paste of the non-wasm impl, I'll move them.

@alamb

alamb commented Apr 17, 2025

Copy link
Copy Markdown
Contributor

Thanks again everyone. From my perspective this PR is ready to merge but I want to leave it open for another day or two to allow more time for comments. I'll be away next week so if another committer doesn't merge it before I'll merge it when I get back

@tustvold tustvold merged commit 8d3d831 into apache:main Apr 21, 2025
@tustvold

Copy link
Copy Markdown
Contributor

Thank you for this, looks good to me 👍

AdamGS pushed a commit to AdamGS/arrow-rs-object-store that referenced this pull request Sep 4, 2025
…Connector (apache#329)

* Implement default wasm32-unknown-unknown (JS platform dependent) HttpConnector.

* Disable all test blocks that strictly require the fs feature on wasm32, as well as those that use the MockServer. Very basic test wasm tests, address dropped/unused receiver in wasm bridge code

* CI wasm32-unknown-unknown tests

* Install node for wasm tests in CI

* cargo fmt

* Hoist use/imports in wasm HttpService
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support object_store with wasm: Default WASM32 HttpConnector

4 participants