Skip to content

rt: do not track time-based metrics on wasm32-unknown-unknown#7322

Merged
Darksonn merged 7 commits intotokio-rs:tokio-1.45.xfrom
jasgin:fix-time-for-wasm
May 23, 2025
Merged

rt: do not track time-based metrics on wasm32-unknown-unknown#7322
Darksonn merged 7 commits intotokio-rs:tokio-1.45.xfrom
jasgin:fix-time-for-wasm

Conversation

@jasgin
Copy link
Copy Markdown
Contributor

@jasgin jasgin commented May 8, 2025

Fix for #7319

Time is generally unsupported in WASM. Fix involves removing Instant from metrics handling when WASM is the target family and tokio's time feature is not enabled.

NOTES:
Will iterate with a test to catch this in the future.

@github-actions github-actions Bot added the R-loom-current-thread Run loom current-thread tests on this PR label May 8, 2025
@jasgin jasgin force-pushed the fix-time-for-wasm branch from f4e99fa to 1fe2ebe Compare May 8, 2025 15:32
Comment thread tokio/src/runtime/metrics/batch.rs Outdated

#[cfg(target_family = "wasm")]
pub(crate) fn new_for_wasm() -> MetricsBatch {
Self::new_unstable_for_wasm()
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.

what do you think instead about a function like:

fn now() -> Option<Instant> {
  if cfg!(target_family = "wasm") { None } else { Instant::now() }
}

Then use that everywhere that its needed? Since WASM can compile the now function, it just can't call it, I think this should more or less take care of it

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.

Good idea, I'm on board with that

if let Some(processing_scheduled_tasks_started_at) =
self.processing_scheduled_tasks_started_at
{
let busy_duration = processing_scheduled_tasks_started_at.elapsed();
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 like the impact of making this optional since it ensures we can't call elapsed() unless we actually got an instant.

@jasgin jasgin force-pushed the fix-time-for-wasm branch from 1fe2ebe to b93f58e Compare May 8, 2025 18:01
@github-actions github-actions Bot removed the R-loom-current-thread Run loom current-thread tests on this PR label May 8, 2025
@jasgin jasgin force-pushed the fix-time-for-wasm branch from b93f58e to 9754ded Compare May 8, 2025 18:03
Comment thread tokio/src/runtime/metrics/batch.rs Outdated
#[inline(always)]
fn new_unstable(worker_metrics: &WorkerMetrics, now: Instant) -> MetricsBatch {
fn new_unstable(worker_metrics: &WorkerMetrics, maybe_now: Option<Instant>) -> MetricsBatch {
let poll_timer = maybe_now.map_or(None, |now| {
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.

map?

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 right, I guess and_then due to the extra option?

u64::try_from(dur.as_nanos()).unwrap_or(u64::MAX)
}

fn now() -> Option<Instant> {
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.

document why this exists

Comment thread tokio/src/runtime/metrics/batch.rs Outdated
Comment on lines 193 to 194
if self.processing_scheduled_tasks_started_at.is_some() {
self.processing_scheduled_tasks_started_at = Some(Instant::now());
}
}
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.

this can use now()

@jasgin jasgin force-pushed the fix-time-for-wasm branch 3 times, most recently from a6c8891 to 266709e Compare May 8, 2025 18:38
time is unsupported in WASM, fix involves removing Instant
from metrics handling for cfg gated WASM target family as a
stopgap solution
@jasgin jasgin force-pushed the fix-time-for-wasm branch from 266709e to fd50424 Compare May 8, 2025 19:12
@Darksonn Darksonn added T-docs Topic: documentation A-tokio Area: The main tokio crate M-time Module: tokio/time M-metrics Module: tokio/runtime/metrics T-wasm Topic: Web Assembly and removed T-docs Topic: documentation labels May 9, 2025
Comment thread tokio/src/runtime/metrics/batch.rs Outdated
u64::try_from(dur.as_nanos()).unwrap_or(u64::MAX)
}

/// `WASM` does not support time: <https://github.com/tokio-rs/tokio/issues/7319>
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.

The major problem here is that WASM does support time ... sometimes. Perhaps we could change this logic to only apply when you enable the time feature of Tokio? I'm not sure if that would be breaking.

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.

That seems reasonable. In the longer term, we could add a builder option to opt in or out of these time based metrics.

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.

Thanks. Added this, let me know if we wanted to conditionally compile the fields as well, but it seems viable to leave them as None when time is not enabled (esp if it's a temporary fix).

@jasgin jasgin force-pushed the fix-time-for-wasm branch 3 times, most recently from 017d1ad to 71b5702 Compare May 9, 2025 16:53
@jasgin jasgin force-pushed the fix-time-for-wasm branch from 71b5702 to 2a1d0ad Compare May 9, 2025 17:00
Copy link
Copy Markdown
Contributor

@rcoh rcoh left a comment

Choose a reason for hiding this comment

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

LGTM — This sounds like a good stopgap to unbreak people who are broken by the current release. Not sure what the right long term option is.

@Darksonn
Copy link
Copy Markdown
Member

@jccampagne does this work for you?

@jccampagne
Copy link
Copy Markdown

jccampagne commented May 13, 2025

Hi, thanks for the reply; I am offline for a few days; will try later in the week.

@jccampagne
Copy link
Copy Markdown

I just tested it - it works for me.
Thanks everyone!

@Darksonn
Copy link
Copy Markdown
Member

Sorry, I still have a question about this. Does this mean that we still are making a breaking change in this scenario:

  1. Using WASM on a platform without time.
  2. Time feature is enabled.

After all, I think but am not sure that this works today as long as you don't actually use tokio::time::sleep. But I could be mistaken.

@rcoh
Copy link
Copy Markdown
Contributor

rcoh commented May 22, 2025

This change is very narrow, it's only for metrics.

These metrics could never have worked since they call Instant::now.

The set of people broken by this change is:

  • on WASM
  • platform supports Instant::now
  • they don't have the time feature enabled

These customers would previously have non zero values for these metrics but now they don't.

However, these metrics were only stabilized in the last release.

@Darksonn
Copy link
Copy Markdown
Member

I don't mean broken just by this change since last release, but broken since the release before that - after all, that's the breakage this is trying to fix.

@rcoh
Copy link
Copy Markdown
Contributor

rcoh commented May 23, 2025

oh yeah I see what you're saying.

Unfortunately this change fully solves neither:

  • People broken by the inclusion of Instant::now in metrics (because enabling time is only a weak heuristic for time working)
  • People seeing 0 for these metrics who could be seeing them (because there's no reason why you need to enable time just because your platform supports time)

Ultimately the only thing that would actually work is:

  1. A cfg gate provided by rustc that reliably determines whether Instant::now will work
  2. A standard library method like Instant::try_now that does this.

I started a discussion to this effect here.

Comment thread tokio/src/runtime/metrics/batch.rs Outdated
/// Gate time metrics as platforms like `WASM` do not typically support [`std::time`]
/// <https://github.com/tokio-rs/tokio/issues/7319>
fn now() -> Option<Instant> {
if cfg!(target_family = "wasm") && !cfg!(feature = "time") {
Copy link
Copy Markdown

@Noratrieb Noratrieb May 23, 2025

Choose a reason for hiding this comment

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

You should do an exact match: cfg!(all(target_arch = "wasm", target_os = "unknown", target_vendor = "unknown")). Instant::now should be available just fine on all other Wasm targets that have std.

It is not expected that any new broken targets like this will be added.

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.

Thanks!

@Darksonn Darksonn force-pushed the fix-time-for-wasm branch from 34a5d95 to 0a0ee85 Compare May 23, 2025 17:52
@Darksonn Darksonn changed the base branch from master to tokio-1.45.x May 23, 2025 17:53
Copy link
Copy Markdown
Member

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

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

Thank you. Now working on merging this to tokio-1.45.x for a patch release.

@Darksonn Darksonn changed the title rt: fix wasm target by removing time from metrics rt: do not track time-based metrics on wasm32-unknown-unknown May 23, 2025
The time feature is not relevant here. WASM with time enabled should
wokr on wasm32-unknown-unknown as long as you don't actually call
tokio::time::sleep.
@Darksonn Darksonn enabled auto-merge (squash) May 23, 2025 18:54
@Darksonn Darksonn merged commit 421a7b0 into tokio-rs:tokio-1.45.x May 23, 2025
80 checks passed
kodiakhq Bot pushed a commit to pdylanross/fatigue that referenced this pull request May 26, 2025
Bumps tokio from 1.45.0 to 1.45.1.

Release notes
Sourced from tokio's releases.

Tokio v1.45.1
1.45.1 (May 24th, 2025)
This fixes a regression on the wasm32-unknown-unknown target, where code that previously did not panic due to calls to Instant::now() started failing. This is due to the stabilization of the first time-based metric.
Fixed

Disable time-based metrics on wasm32-unknown-unknown (#7322)

#7322: tokio-rs/tokio#7322



Commits

3768696 chore: prepare Tokio v1.45.1 (#7359)
421a7b0 rt: do not track time-based metrics on wasm32-unknown-unknown (#7322)
b1bdb3c ci: update macros_type_mismatch for Rust 1.87.0 (#7339)
See full diff in compare view




Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

@dependabot rebase will rebase this PR
@dependabot recreate will recreate this PR, overwriting any edits that have been made to it
@dependabot merge will merge this PR after your CI passes on it
@dependabot squash and merge will squash and merge this PR after your CI passes on it
@dependabot cancel merge will cancel a previously requested merge and block automerging
@dependabot reopen will reopen this PR if it is closed
@dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
@dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
@dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
@dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
@dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-tokio Area: The main tokio crate M-metrics Module: tokio/runtime/metrics M-time Module: tokio/time T-wasm Topic: Web Assembly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants