bevyengine / bevyengine/bevy

`bevy_tasks` cannot be implemented correctly on the web

Open
#20,404 5 comments 0 reactions 0 assignees View on GitHub
A-Tasks C-Bug D-Async D-Complex I-Crash O-Web S-Needs-Design
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

On the web, blocking the main thread is to be avoided: the behavior is browser-specific, but at best it will freeze the UI, and at worst it will crash the page. This means we really shouldn't block anywhere that might possibly run on the browser's main thread. And, unfortunately, because bevy targets single-threaded web deployment, to me it seems like this means effectively the entire code-base must be non-blocking.

This has a few repercussions:
+ It's impossible to correctly implement `TaskPool::scope` without blocking. Currently when single threaded it has a panicking failure case that is impossible to fix.
+ Fixing `TaskPool::scope` would require changing it to return a `Future`. This may require making much more of our executor and scheduling code into async, due to function coloring.
+ There are several other places where we make calls that may potentially block within the engine. Proper web support would require that we either ensure these never block in practice, or swap the blocking calls for `async` ones.

`TaskPool::scope` only fails under specific conditions: when all the scope has pending tasks, but they are all asleep (waiting for other futures to complete). When this happens, the scope returns early. Since this is only single-threaded, this does not cause UB, but it does cause a panic when the runtime figures out that it's missing the results it expected from the incomplete tasks.

Luckily for us, the issue with `TaskPool::scope` is rare. You only hit it when you set up a scope with futures that do actually have to wait for meaningful amounts of time, and mostly people don't seem to do that. But it's dreadfully easy to hit when doing complex networking in the browser.

---

Setting `scope` issue aside, there's a general question of what to do about `bevy_tasks`. Because bevy aims to be extremely cross-platform, it is also constrained to the least-common denominator of what those platforms support. Unfortunately, `bevy_tasks` currently does things that just will not work on the web. What should we do about that?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.