bbqueue icon indicating copy to clipboard operation
bbqueue copied to clipboard

Feat/async support

Open xgroleau opened this issue 2 years ago • 5 comments

Initial draft for async support. Just want your input before continuing/cleaning up. My experience with async is pretty limited so feedback and comments are more than welcomed!

I diverted a bit from the previous work API since I wanted to keep the flexibility. This async api is as close as possible to the sync one.

Status:

  • [x] Basic implementation
  • [x] Basic tests
  • [x] Add Frame flavor implementation
  • [x] Cancellation tests
  • [x] Test on MSRV, gate behind feature if necessary
  • [x] Complete API documentation

xgroleau avatar Oct 28 '22 15:10 xgroleau

This looks really useful, thanks! I'm going to try it in some network code and see how it works out.

Thanks @jeff-hiner! I continued developing the fork a bit since the PR, there are probably some fixes missing in this PR versus the fork. You can check it out here. Also note that the fork abstracted on the source of the storage since I wanted to provide the buffer myself.

I spoke to James some time ago and he won't merge the PR for now but we left it as reference for other users.

Since I am using it for internal project, I did not take the time to publish as a separate crate, but if there is some traction, I could publish a crate of the fork until the upstream gets async support if I have the time to update the doc.

xgroleau avatar Jan 09 '23 20:01 xgroleau

Just curious, could you elaborate on why you choose to leverage the waker? To my understanding, the executor will eventually poll the task anyway, so it shouldn't be a big issue. Specially given that the comparison of some atomic values is so fast. Using the waker leads to increased complexity on the codebase. Do you fear task starvation from the scheduler?

Altair-Bueno avatar Jun 05 '23 12:06 Altair-Bueno

Just curious, could you elaborate on why you choose to leverage the waker? To my understanding, the executor will eventually poll the task anyway, so it shouldn't be a big issue. Specially given that the comparison of some atomic values is so fast. Using the waker leads to increased complexity on the codebase. Do you fear task starvation from the scheduler?

Sure! The thing is that most executor won't poll again unless the task is awoken, thus you need the waker. Without a waker, the executor would need to poll every task. So unless you use an executor that does a busy polling loop, the executor will not poll the task again like you mentionned.

For example, embassy puts the MCU in a low power state when all tasks are pending and wait for an interrupt. Needing to loop while polling would make this impossible.

You can learn more about the inner workings of async here

xgroleau avatar Jun 05 '23 14:06 xgroleau

Just FYI, I've been using a fork of some of @xgroleau 's work for implementing a completion-based i/o model with async. I did run into some deadlock issues with the custom waker, so I patched in futures::task::AtomicWaker and replaced a bunch of NonNull and raw pointers with normal refs (which removed a bunch of unsafe). I don't know exactly what fixed the issue, and I need to break the fixes out into smaller PRs, but it's been running a while in production with no issues. Here's the branch if you want to experiment with it or incorporate any of the changes into your own fork.

https://github.com/jeff-hiner/bbqueue/tree/xgroleau-async

jeff-hiner avatar Jun 05 '23 18:06 jeff-hiner

The thing is that most executor won't poll again unless the task is awoken,

Hm i didn't knew that! Thanks.

And thanks Jeff too! I definitely will give it a try.

Altair-Bueno avatar Jun 06 '23 15:06 Altair-Bueno