bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Remove crossbeam-channel as a runtime dependency

Open james7132 opened this issue 1 year ago • 2 comments

Objective

Fixes #7153. crossbeam-channel is a great crate, but it may not be the right fit for a lot of Bevy's use cases. It inherently allocates an inner representation, and uses an Arc-like indirection to access it via the sender and receiver. This might be useful when we want to separate the two and move them to their own tasks on different threads, but this may represent additional overhead when working with the channel. We also tend to only use try_send and try_recv to avoid blocking at all costs. This makes sense given that we (almost) never want to block the current thread and wait on the other side to be populated.

Solution

Remove all runtime dependency on crossbeam-channel, and replace it with the concurrent-queue, which is already in use by bevy_ecs, bevy_tasks, and by a good chunk of the async-* dependencies Bevy is already using. Where absolutely necessary, the queue will be wrapped in an Arc to provide a similar interface as before.

The queue provides access to both ends of the queue from a single interface, does not require internal indirection, pushes and pops are strictly non-blocking, provides a similar internal implementation to that of crossbeam-channel, and allows us to remove one more dependency when compiling Bevy.

One potential improvement is to explicitly wrap the case of unclosable and unbounded queues in an Arc to create an infallible event queue.


Changelog

TODO

Migration Guide

TODO

james7132 avatar Apr 21 '24 08:04 james7132

Performance-wise how do these compare? Are there benchmarks of crossbeam vs concurrent-queue anywhere under different load conditions? Some usages of these (such as the ID lifecycle stuff) might be affected by perf regressions. I'm in favor of removing dependencies, but we're notably taking on new code with the wrappers, and increasing the number of queue variants (ConcurrentQueue, Arc<ConcurrentQueue>, EventQueue, EventReader, EventSender, instead of just Sender/Receiver), making this feel a bit more like a lateral move (I do acknowledge the benefits stated above though). But combine that with the "perf" question and I start to question why we're rocking the boat here.

cart avatar Apr 30 '24 23:04 cart

I don't have time to review this right now, but I think this PR is probably worth doing due to the fact that crossbeam-channel uses user-space spinlocks, which is pretty much always a bad idea in user-space applications

joseph-gio avatar Jul 13 '24 01:07 joseph-gio