-
Notifications
You must be signed in to change notification settings - Fork 475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion: Async I/O #430
Comments
I'd definitely wait for stable async/await for a release, but working on a PoC in nightly seems like a good idea. The macro workaround looks fine to me as it's easy to remove it when the feature has landed. If we do a full rewrite of the core system may I suggest some general improvements:
(I know it's unrelated, but I think it would be a good idea to think about that during the rewrite, if there are no reasons against it. Feel free to move this to another issue to ease the discussion here) |
A piece that's missing from this discussion is, what are some problems with the existing approach? Can we solve them without async/await? I don't totally understand what the issues are outside of the abstract we-block-on-I/O, and it could be beneficial to list them in this discussion thread. From an API design side, I tend to think that the omission of generators from the initial async/await implementation limits what we could do for the main update loop, but maybe that's just a lack of imagination on my part. An alternative might be to try async/await somewhere else: for instance, one place that we tend to proliferate threads is when dealing with D-Bus code. Maybe it's possible to come up with an ergonomic way for blocks to opt-in to a shared D-Bus threadpool using Futures. (We might have to check out the upstream options, of course.) |
Good point. Right now, we have a ton of boilerplate, many unnecessary copy's and no flexibility. I'm hoping async IO would also help us streamline a composable, low-overhead rendering pipeline that is also much more stable. Right now, there are many edge-case bugs that can arise from blocking I/O that can't be fixed easily.. Like, block updates that are synced on a shared interval output only a single visual update to i3status for performance, but the timers can be desynced if you, for example, use a custom block with network interaction. |
We can also take inspiration from some of these projects that have elegant solutions:
|
Azul has the architecture that is most similar to ours; https://github.com/maps4print/azul |
Maybe it's time to reconsider using async I/O now that async/await is stabilized? Doing a complete architecture overhaul sounds quite intimidating though. Maybe we could work out a way to progressively "async" the core by supporting both async and non-async behaviours at the same time?
I would say most blocks either wait for:
|
Is anyone working on this? I am bored and would be interested in having a go at progressively making stuff async with tokio. |
Hello, FYI I'm not working on this. I have mixed feelings about using async inside i3status-rust (only my opinion):
Nevertheless some widgets may benefit from being async (or simply being run inside a thread): @Noah-Kennedy I'll be looking forward reading your code if you decide to give it a go ;) |
Any updates on this? |
My attempt to write an async tokio-based version of Currently there are four blocks: Memory, (slightly simplified) Time, Temperature and sway's keyboard layout. I like the fact that a (time) block can be as simple as 50 SLOC - https://github.com/MaxVerevkin/swaystatus/blob/master/src/blocks/time.rs |
Looks pretty nice! |
By the way, if anyone has questions or suggestions regarding the design of swaystatus, don't hesitate to open a new issue, since it's my first attempt at async |
By the way, looks like the async implementation uses a little less memory ❯ procs swaystatus --or i3status-rust
PID:▲ User │ TTY CPU MEM CPU Time │ Command
│ [%] [%] │
142363 maxv │ 0.0 0.2 00:00:00 │ /home/maxv/rust/i3status-rust/target/release/i3status-rs
142364 maxv │ 0.0 0.1 00:00:00 │ /home/maxv/rust/swaystatus/target/release/swaystatus |
While porting Thanks to So that's what I got: https://imgur.com/a/v8344Ce The code is fairly simple (it's just the GUI, no functionality yet): https://github.com/MaxVerevkin/swaystatus/blob/c6a55364b28c692964cfb62bbcee0bffbf9140d4/src/blocks/pomodoro.rs What do you think? Should some other blocks allow this kind of configuration? IMO it's far better than editing the config file (in case of pomodoro). |
I think this is a step in the right direction, looks awesome @MaxVerevkin ! |
@ammgws @MaxVerevkin thanks for the ping! This looks great! How are you planning to persist the selections? should it be until restart so we start from the default but can change it per session? I'm not familiar with async in rust but I could try to port over your work from swaystatus! |
I don't plan it (at least for now). In case of If I wanted to store the settings persistently, I guess I would write into something like |
that is perfectly fine, one can set the default and then adjust per session |
You mean the async or
Yeah, that's what I thought too. |
Oh Async in rust in general! so please submit your pr, I'll def review and if I have extra time maybe port over other blocks! thanks a lot! |
So, one year later... There are two async designs for 1: Block is a
|
Async branch has now been merged into master (still some work to do before release is possible though) |
When I first designed i3status-rust, async I/O was still a long way from being usable. Thus my design involves a custom task scheduler to combine all the block computations in a single thread, but I/O still either blocks the main thread or has to be deferred to a separate thread with Mutexes and callbacks.. This is of course not helpful to reach the goal of maximum efficiency and minimal overhead.
In the years since, Rust has made great progress towards async I/O. Futures are stabilized, Tokio has reached 0.2 and the general ecosystem has massively improved. We can now borrow across async tasks too using the Pin trait, which has also been a blocker for me.
We could conceivably reimplement the core system to use futures, but I had built a prototype and it was ergonomic hell, and I don't want to put anyone who wants to contribute through that process. So, I believe we should wait for async/await syntax, whcih has also made great progress (https://areweasyncyet.rs/). We could build a proof-of-concept in the current nightly, but there are still some open issues that prevent me from going for it right now.
Would you guys agree that we should wait for the following features/ or do you think we can or should work around these issues right now?
The text was updated successfully, but these errors were encountered: