Stream: wasi

Topic: how to determine correct `cfg` gates for wasm targets?


view this post on Zulip BurntSushi (Jul 29 2024 at 17:01):

I have... no idea if I'm asking in the right place, and if not, I'm hoping someone here can point me in the right direction.

i'm currently trying to figure out how to integrate wasm support for a Rust datetime library, and this integration involves platform specific things like, "find the current system configured time zone."

i am currently testing wasm32-wasip1 support in CI, and this just integrates with the "host" OS. so there's very specifically (at least I think) _no_ platform support that Jiff needs to be aware of here. you just need to let the wasmtime process access /usr/share/zoneinfo and /etc/localtime (on Unix).

but in other wasm contexts, it seems appropriate to use a crate like js-sys to run some Javascript code to get the current time zone. it occurs to me that this is _not_ what should be done for _all_ wasm targets, yet that is effectively what is sometimes done.

i don't have a lot of wasm experience, and my wasm ecosystem knowledge is nearly non-existent. i don't even have a fully formed question, but i think it's something like, "how do I know when it's appropriate to use js-sys on wasm targets to do platform-specific things?"

While porting Numbat to jiff (sharkdp/numbat#511), I noticed that jiff's timezone detection doesn't work on WASM (currently panics with "time not implemented on this platform"). I am currently usin...
A date-time library for Rust that encourages you to jump into the pit of success. - BurntSushi/jiff
Rust crate to get the IANA time zone for the current system - strawlab/iana-time-zone
Rust crate to get the IANA time zone for the current system - strawlab/iana-time-zone

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:18):

Whether or not this is the right place I can at least try to help out :)

I think that you'll probably want to break things down into a few buckets:

That's at least the easy parts, but you probably already know much of that. The harder parts will make the answer much more nuanced here:

That's all to say I think the outlook is not so good for wasm support in Jiff. What I might recommend is:

  1. Add a "web" or "wasm-bindgen" or etc feature. That would be explicitly enabled by end-users and would enable js-sys/web-sys integration. That'd be the detection for "compiling for the web". The end user experience is not great since it requires an opt in but that's sort of a reflection of the ecosystem right now (the whole rust/wasm-on-the-web is not as buttery smooth as native)
  2. If users want WASI support in Jiff then tell them that wasm32-wasip1 is unlikely to ever be supported since it didn't have time zone support. The wasm32-wasip2 target is a work-in-progress.

I suspect the folks working on timezones for wasm32-wasip2 in WASI itself would love to get your feedback, but I'm not sure how best to connect them other than hope they're reading this as well.

Clocks API for WASI. Contribute to WebAssembly/wasi-clocks development by creating an account on GitHub.

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:20):

Looks like changes to wasi-clocks and timezones are at https://github.com/WebAssembly/wasi-clocks/issues/69. I haven't been following this though so I unfortunately can't give a tl;dr

Following up on #68 and #61 (comment), we likely want to make changes to the @unstable timezone proposal based on feedback. This is exactly what the unstable status of this extension was for, so I'...

view this post on Zulip BurntSushi (Jul 29 2024 at 17:25):

yeah i've actually responded there! it sounds like they're trending towards the IANA tz ID, which is all Jiff needs.

there is a separate question of how to access the "system" tzdb, but this is basically only a thing on Unix. so Jiff just bundles it everywhere else (like Windows). this is not especially great for shipping an artifact to web browsers, but i don't really think there's much of an alternative.

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:26):

yeah i've actually responded there

Oh excellent!

this is not especially great for shipping an artifact to web browsers

Makes sense yeah. Is the already a cargo feature to disable this? (or is that not possible?) Otherwise that's probably the best that can be done with wasm right now

view this post on Zulip BurntSushi (Jul 29 2024 at 17:27):

and thank you for the reply!

the opt-in feature approach is definitely kind of a bummer, but yeah, i see why you suggest that. one specific issue that has also cropped up is that SystemTime::now() will panic on some wasm targets but not on others. for cases where it panics, i think i'm supposed to use js-sys to access the Javascript Date API. that _seems_ like something that shouldn't require an opt-in though, i guess the alternative is to just go figure out exactly the wasm targets where std will panic? maybe that also will be a good approximation for "the web"?

view this post on Zulip BurntSushi (Jul 29 2024 at 17:28):

Alex Crichton said:

yeah i've actually responded there

Oh excellent!

this is not especially great for shipping an artifact to web browsers

Makes sense yeah. Is the already a cargo feature to disable this? (or is that not possible?) Otherwise that's probably the best that can be done with wasm right now

yeah it can be disabled. enabled by default. (well, the status quo is that Jiff doesn't have any wasm specific logic right now. but i expect "bundle tzdb" to be enabled by default on wasm. but can be disabled.)

view this post on Zulip BurntSushi (Jul 29 2024 at 17:32):

i guess there's maybe two different issues here. on the one hand, it seems okay to ask for an opt-in to make "get the current local time zone" work correctly. but on the other, it seems bad to require an opt-in to make Timestamp::now() not panic.

view this post on Zulip BurntSushi (Jul 29 2024 at 17:32):

but both, i think, require js-sys "on the web."

view this post on Zulip BurntSushi (Jul 29 2024 at 17:33):

That's at least the easy parts, but you probably already know much of that.

i didn't! thank you for spelling that out. :-)

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:34):

i guess the alternative is to just go figure out exactly the wasm targets where std will panic? maybe that also will be a good approximation for "the web"?

I can try to help out here: rustc --print target-list | rg '^wasm'

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:36):

but on the other, it seems bad to require an opt-in to make Timestamp::now() not panic.

I definitely agree with this, and I wish I had a better answer for you :(

I suppose most of what I'm saying here is convincing you that this may be the "least bad" solution for now.

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:37):

For the least amount of end-user friction I would recommend unconditionally using js-sys/web-sys on cfg(all(target_family = "wasm", not(target_os = "wasi")))

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:37):

that'll bite someone someday but it'll probably help more people in the meantime

view this post on Zulip Lann Martin (Jul 29 2024 at 17:38):

@Alex Crichton These answers are mostly for "get the current tz", right?

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:39):

right yeah, and then dealing with a few other big problems:

  1. There's no "web target" in Rust today so detecting that at compile time is not great
  2. WASIp1 had no support for time zones
  3. WASIp2 is growing support but it's not there yet

view this post on Zulip BurntSushi (Jul 29 2024 at 17:39):

gotya, understood. the other competing pressure here, unfortunately, is that existing datetime libraries will "just work," so an opt-in will likely be a point of confusion for users migrating. even crates like [getrandom seem to assume that wasm{32,64}-unknown-unknown implies "it's on the web."] :-( although based on what you've told me, i do agree with you at least in principle that it seems like the least bad way to go about it. otherwise one is making assumptions that may not be true.

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:40):

I'd follow community precedent there and not my own opinions

view this post on Zulip BurntSushi (Jul 29 2024 at 17:40):

gotya

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:40):

My personal opinion is that retroactively I think wasm32-unknown-unknown == web was a mistake

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:40):

but you're right that it's pretty embedded nowadays

view this post on Zulip BurntSushi (Jul 29 2024 at 17:40):

yeah that makes sense as an opinion

view this post on Zulip BurntSushi (Jul 29 2024 at 17:40):

this has actually be super duper helpful. and i'm glad i wasn't way off the mark. because something smelled amiss when i noticed that pretty much everyone did wasm integration just a little differently.

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:41):

I think realistically 99% of users of wasm32-unknown-unknown are on the web and the 1% can probably work through various compilation features/gates/flags to get their use case sorted if necessary

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:41):

yeah one of the major issues with web support is it's largely defined by wasm-bindgen, but there's no like wasm32-wbindgen target in the rust compiler (nor do I think there should be one)

view this post on Zulip Lann Martin (Jul 29 2024 at 17:41):

Maybe a default "wasm-unknown-means-web" feature?

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:42):

yeah Lann that's sort of what I'm thinking, but I wouldn't add that unless anyone actually asks for it

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:42):

Alternatively what rust should perhaps do is add a wasm32-web target with target_os = "web"

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:42):

and it looks and behaves exactly like wasm32-unknown-unknown except for the target_os = "web"

view this post on Zulip Alex Crichton (Jul 29 2024 at 17:42):

that would solve this once and for all, but cest la vie

view this post on Zulip BurntSushi (Jul 29 2024 at 19:57):

okay, so i did a little more digging, specifically into getrandom, and i think they are actually very well aligned with you @Alex Crichton. specifically, they have a js feature that is disabled by default, and when enabled, _only_ adds dependencies js-sys and wasm-bindgen on the wasm{32,64}-unknown-unknown targets. apparently there are some uses of wasm32-unknown-unknown that are non-web related, specifically, coming from the Cosmopolitan folks i think?

in any case, it seems like the getrandom maintainers also think there should be something like a wasm32-unknown-browser target.

given this, i think i'm going to copy getrandom's approach which is actually i think just about the same as what you suggested @Alex Crichton! i had just misunderstood what getrandom was doing.

(but there are definitely other crates that are perhaps not behaving as nicely.)

Currently the "custom" feature is last in our precedence order for selecting implementations. The original idea behind this was to ensure that a crate couldn't (accidentally or intentionally) chang...

view this post on Zulip Bakkot (Jul 31 2024 at 22:45):

This is a little off topic, but I would caution against using "browser" or "web" to mean "JS runtime": node is very widely used, and most anything that will run on the web will also run in node.


Last updated: Dec 23 2024 at 12:05 UTC