Live data from Hacker News

Tokio 1.0 – async runtime for Rust

tokio.rs

291–300 of 422 posts

Re: Tokio 1.0 – async runtime for Rust

#291
post #255

Earlier quoted context omitted.

I think it's rather that smol is "complete" and doesn't need much maintenance.

Maybe that's true. I don't know how complex these things are, or if they will be affected by future changes in the language, but it feels weird to say that a critical piece of software is complete. I wonder if many new libraries will use Smol.

One of the principles that stjepang was very keen on for smol was that libraries shouldn't depend on it. Libraries should be written in an async-executor generic way and the end binary should then be free to use smol as the executor, or tokio, or anything else.

I'm currently using smol (in an application I'm developing - not just a library) and I don't think this will scare me away. He appears to still be responding to pull requests, and smol consists of a reasonably small amount of very high quality code.

Re: Tokio 1.0 – async runtime for Rust

#292

Earlier quoted context omitted.

async-std [0] is pretty widely used as well. [0]: https://github.com/async-rs/async-std Most libraries can be used with different runtimes. Hyper for example, which uses Tokio by default, can be configured to use an async-std executor.

It bugs me that that library will spin up a scheduler without being asked to do so. As I understand it, that difference (vs Tokio) was the main driver behind the projects splitting. I also think it's a bit presumptuous for them to name themselves "std". It'll be even more ridiculous in the likely event that Tokio becomes the std:: asynchronous I/O library. It's asking for confusion.

[deleted]

Re: Tokio 1.0 – async runtime for Rust

#293
I'm hopeful that this leads to some focus on the ergonomics of "waiting for async things from sync code". Lots of "handlers" in the universe have synchronous interfaces, so if you want to implement them you end up needing to poll/wait on async from a regular function. I swear that every time I poke at Rust, I seem to find some way to cut my fingers...

My specific example is writing a fuse handler (now with cberner/fuser formerly zargony/rust-fuse) for GCS/S3. If you want to use make any async requests (like via hyper), you currently have to roll your own poller, like reqwest does in blocking mode [1].

The rust async/.await primer [2] offers the reader the seemingly helpful futures::executor::block_on, but basically no two executors can interact (and for good reason!). As others highlight, the ecosystem seems like it's going to end up standardizing on tokio (and/or some flavor thereof) and that hopefully now that it's 1.0, we can have stable enough deps for a while :).

[1] https://github.com/seanmonstar/reqwest/blob/5ee4fe5ab64a2e3d...

[2] https://rust-lang.github.io/async-book/01_getting_started/04...

Re: Tokio 1.0 – async runtime for Rust

#294
post #217

Earlier quoted context omitted.

I am not saying that the borrow checker cannot handle locks. Locks work great. (The borrow checker does not understand locks as a special construct, to be extra clear.) Did you read the post I linked? It lays out the details. I am happy to clarify if you don’t get the specifics.

I see now, I misunderstood your original post. You were saying async/await is necessary because futures work badly, not because all the alternatives (i.e. locks) work badly. Sorry, my mistake! Edit to add: futures work badly in every language, so there's no shame in the borrow checker not working with them. Edit 2: But in that case we're back to "why would Rust want async/await over (potentially green) threads with i…

I believe these are the talks from Steve that he's referring to. It was enlightening for me:

1. Rust's Journey to Async/Await - https://www.youtube.com/watch?v=lJ3NC-R3gSI

2. The Talk You've been Await-ing for - https://www.youtube.com/watch?v=NNwK5ZPAJCk

The first video goes into all the bits you're concerned about and all the things that Rust has tried before arriving where they are now

Re: Tokio 1.0 – async runtime for Rust

#295
I really like writing rust, however not having the async runtime be a part of std has hurt the language in my opinion.

Crate consumers have to consider which async lib a crate is using leads to a lot of annoying gotchas that can really confuse less experienced rust devs.

I'm hoping tokio becomes the default and eventually gets merged into std, it really is the best async implementation.

Re: Tokio 1.0 – async runtime for Rust

#296
post #141

Earlier quoted context omitted.

How big is it?

Here are the compiled-in dependencies: $ cargo tree -e no-dev,no-build --no-dedupe -p tokio tokio v1.0.0 ├── bytes v1.0.0 ├── libc v0.2.81 ├── memchr v2.3.4 ├── mio v0.7.6 │ ├── libc v0.2.81 │ └── log v0.4.11 │ └── cfg-if v0.1.10 ├── num_cpus v1.13.0 │ └── libc v0.2.81 ├── once_cell v1.5.2 ├── parking_lot v0.11.1 │ ├── instant v0.1.9 │ │ └── cfg-if v1.0.0 │ ├── lock_api v0.4.2 │ │ └── scopeguard v1.1.0 │ └── parking_…

the dephell report: https://gallant-ride-cab667.netlify.app/

Re: Tokio 1.0 – async runtime for Rust

#297
post #281

Earlier quoted context omitted.

Rust doesn't have a runtime. That's part of its awesomeness. That's why it can target microcontrollers. You're probably used to languages with garbage collectors. Having garbage collection forces you to have a "runtime" since that's where the GC code goes. Then more and more stuff accretes onto this unavoidable runtime, and before you know it you're writing Java code...

Um, rust does have a runtime, that's why you don't need to include packages for strings, refcounting, allocation, etc. Anything that has a language keyword should have a default implementation in that runtime, and much like box, ?, !, etc async and await are both language features that I shouldn't need to include from outside of the runtime.

Those are all pay-as-you go features; in my mind I associate runtime with a single, constant-ish initialization cost, plus possibly some background processing or inserted hooks that do janitor work for you. Rust doesn't have a runtime in that sense.

Re: Tokio 1.0 – async runtime for Rust

#298
post #240

Earlier quoted context omitted.

Alternatively use async everywhere from the start and your headaches go away too. It's mixing blocking code with async code that causes issues.

won't this just bifurcate the rust ecosystem between async and non-async rust libraries?

It's already there.

Re: Tokio 1.0 – async runtime for Rust

#299
post #293

I'm hopeful that this leads to some focus on the ergonomics of "waiting for async things from sync code". Lots of "handlers" in the universe have synchronous interfaces, so if you want to implement them you end up needing to poll/wait on async from a regular function. I swear that every time I poke at Rust, I seem to find some way to cut my fingers... My specific example is writing a fuse handler (now with cberner/fu…

I've encountered the "wait on async things from sync code" issue several times, too. I have found that something like `block_on` from either `futures` or `futures_lite` often does the trick.

https://docs.rs/futures-lite/1.11.3/futures_lite/future/fn.b...

Re: Tokio 1.0 – async runtime for Rust

#300
post #234
post #201

Earlier quoted context omitted.

I believe the idea is that within a project that uses async functionality, you should only use non-async functions when the logic does not call blocking functionality. If you are mixing async functionality and synchronous functions with/blocking I would consider the latter a defect unless it is handled properly within an asynchronous context.

I really don't understand the logic of this on a multi-threaded system. The vast majority of functions I write are best executed synchronously, the remainder is usually composed of logic wrapping heavy computations which can be executed in parallel or logic surrounding I/O which can be executed concurrently. An async system which poisons the rest of my code to force async usage doesn't seem like it will scale to code…

I think you're right on one level: if your codebase is pervasively, implicitly multithreaded, then there's little value in explicitly marking yield points. But if your codebase is pervasively, implicitly multithreaded, then it's impossible to maintain without locking everywhere (and difficult even then), and combining async with (blocking) locking does not work well.

In a codebase where concurrency is carefully controlled and constrained, an async system that gives you visibility into where the yield points are is very valuable: https://glyph.twistedmatrix.com/2014/02/unyielding.html .

Post reply on HN