News for hackers. Stuff that matters.
Re:Building a shared vision for Async Rust by Animats on Thursday March 18, 2021 @09:54PM (#26509505)
The main thing I want for Async Rust is the ability to not use it.

What I'm doing involves a virtual world viewer with maybe a dozen threads. Some are compute bound. Some are talking to the GPU. Some are waiting for I/O. The normal situation is about 2 or 3 CPUs of work. Sometimes more.

I don't want an async model, which assumes you're I/O bound, interfering with keeping all those CPUs busy. Already I've had to switch from using "reqwest", which now seems to always bring in tokio, to "ureq", a minimal HTTP client. The way to do HTTP requests used to be with "hyper", but that became a lower level for "reqwest", and then "tokio" was slipped in underneath to make it "async". It always uses async, even if you make a blocking request.

"Async" is a specialized tool for web servers with very large numbers of clients. Outside of that niche, it's seldom needed.

Re:Building a shared vision for Async Rust by songqin on Thursday March 18, 2021 @10:21PM (#26509639)
Your comment touches on a few misconceptions I see a lot.

Firstly, `reqwest` exposes both an async and a synchronous API, allowing the developer to choose which one to use. They are largely interchangeable code-wise. [1]

Secondarily, and more broadly, async is possible to opt out of. You must understand that most web and network related libraries will be async by default for performance, because people who write in Rust and people who write web servers typically care greatly about performance. This is the intersection of those two groups. That being said, there are options outside of that ecosystem. [2]

If you truly want to use an asynchronous library without migrating your application to run entirely on an async runtime like tokio, you can run it inside of a synchronous function without much trouble. I've put together a playground link for you. [3]

1. https://docs.rs/reqwest/0.11.2/reqwest/blocking/index.html

2. Iron: https://github.com/iron/iron Rouille: https://github.com/tomaka/rouille

3. https://play.rust-lang.org/?version=stable&mode=debug&editio...

Re:Building a shared vision for Async Rust by Animats on Thursday March 18, 2021 @10:27PM (#26509666)
"reqwest" exposes a synchronous API, but it's doing async stuff underneath. If you turn on logging, you can see 30 or so async events associated with a single HTTP client side request. It's starting up and shutting down a polling thread just to make one HTTP client request.

You must understand that most web and network related libraries will be async by default for "performance". That's what scares me - async contamination of the low level Rust ecosystem. The async enthusiasts have to be kept in check to prevent breaking Rust as a systems language.

Re:Building a shared vision for Async Rust by songqin on Thursday March 18, 2021 @10:34PM (#26509705)
I had understood your concern as wanting to avoid the complexity of asynchronous code execution in your codebase, I did not realize your concern is about writing very low level systems code. In that case, you are doing the right thing: libraries like ureq, minreq, Isahc, curl, and more all offer what you want.

It is unclear to me what you mean by keeping the community "in check". There are a lot of people who rely on and enjoy the async story, and they will continue to produce code that improves that story. Simultaneously, there are people who do not need that, and they are not hindered by this. People will build what they want and need. You've just picked some libraries from some of the biggest async contributors in the community and requested that they be kept in check so that you don't have to switch to a synchronous alternative, of which there are plenty.

Re:Building a shared vision for Async Rust by Animats on Thursday March 18, 2021 @11:50PM (#26510019)
It's not that "low level". It's that it doesn't fit the model of "mostly waiting for the network". Here are some of the things I have going on:

- Incoming events UDP packets from multiple servers. These arrive at the client and go into a queue for processing.

- Refreshing the 3D window. This ties up one thread almost full time. At the beginning of each frame, it reads queued events that tell it what needs to change in the GPU. The rest of the time it feeds the GPU.

- Some incoming events require querying external HTTP servers to retrieve assets. When the results come back, they include compressed items which have to be decompressed, processed, and turned into GPU-ready textures or meshes. This is prioritized by how important it is to display that object right now, based on the viewpoint. So there are priority queues along with multithreading.

There's more, but you get the idea.

What's so great about Rust is that you can do stuff like this without crashing all the time, spending your life in the debugger, or recopying big objects to safely pass them around.

The previous implementation, in C++, looked a lot more like an "async" model. It had lots of "coroutines", mostly running off a single thread. It also had a few things running as independent threads because they were so CPU-intensive. It was very prone to short stalls that annoyed players. This happened because something had to do more work than expected and briefly stalled out the coroutine system. The killer in async systems is the subroutine that is usually fast but sometimes slow. So I've seen this problem done in "async" style, and it didn't work well.

I've previously done robotics work which had many asynchronous tasks. I've used QNX for that, and I've used ROS. There, you have a lot of intercommunicating processes, which works but has more overhead.

None of this maps well to an "async" model.

Part of the problem here may be that I've done a lot of multi-thread programming and am used to it. It's an alien approach to programmers who came up from Javascript. That's a big fraction of the web backend crowd.

(Personally, when I have to do a web service, I write it in Go. That's the use case for which Go is designed. It has the libraries for that, and the goroutine concept is well matched to that task.)

Re:Building a shared vision for Async Rust by dunkelheit on Friday March 19, 2021 @06:17AM (#26511721)
> I've previously done robotics work which had many asynchronous tasks. I've used QNX for that, and I've used ROS. There, you have a lot of intercommunicating processes, which works but has more overhead.

I wonder, why is this kind of system a bad fit for the async model? Is it because all threads must be reliably preemptable?

Re:Building a shared vision for Async Rust by AgalmicVentures on Thursday March 18, 2021 @11:08PM (#26509848)
You're replying to John Nagle, as in https://en.m.wikipedia.org/wiki/Nagle%27s_algorithm -- perhaps it would be worth considering his words further, before dismissing his concerns?

Surely we can all agree that spinning up unnecessary threads is undesirable?

Re:Building a shared vision for Async Rust by woah on Friday March 19, 2021 @07:24AM (#26512056)
Doesn’t matter who he is, if he’s mad that libraries made for and by web and network developers are using a concurrency model that works well for their applications, he should use different libraries.
Re:Building a shared vision for Async Rust by AgalmicVentures on Friday March 19, 2021 @09:37AM (#26513147)
It does matter -- he was one of the first "network developers". He published RFC 896 over 35 years ago; he has more experience on this topic than almost anyone.

> Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith.

This is not the strongest plausible interpretation of what he said --

He's not asking for people to not develop async code. He's asking for them to not hide it in synchronous code.

If you're expecting a blocking system call, and actually get a brand new background thread that's polling, it's quite reasonable to be frustrated.

Re:Building a shared vision for Async Rust by cycloptic on Friday March 19, 2021 @01:57PM (#26516390)
>If you're expecting a blocking system call, and actually get a brand new background thread that's polling, it's quite reasonable to be frustrated.

It really isn't if the documentation doesn't outright say that it's single threaded and not thread safe. For a lot of simpler use cases where you just want to ship a thread-safe API (e.g. application does not have its own thread pool) then it just makes sense in a lot of cases to use some kind of automatic thread pooling. The caller does not have to know or care how the internal state machine is implemented.

If you have implemented your own thread pool it seems you should know enough to dig down enough to the lower layers to where you can get to that blocking syscall, or least to the point where you can strip off the O_NONBLOCK flags yourself.

Re:Building a shared vision for Async Rust by geofft on Thursday March 18, 2021 @11:37PM (#26509954)
Let me try to rephrase this in a way that doesn't pin the blame on "async enthusiasts" as people, and see if you agree:

Many years ago, well before Rust 1.0, Rust used its own M:N threading system, used segmented stacks, had it's own libuv-based event loop, etc. Also, it had garbage collection built into the language.

These were removed before 1.0, which made Rust a lot better as a systems language: you could reliably embed it into non-Rust programs, you could reliably interoperate with non-Rust libraries that didn't expect to be moved around threads, you didn't need to care about starting up the GC (or handling GC pauses), etc.

This was a good decision for Rust, and it turns out most of the things people wanted to do with these features could be done outside it - e.g., the borrow checker avoided the need for pervasive GC. (Though almost certainly not intentional, one side effect is that it distinguished Rust from Go: Go is great for standalone programs that need lightweight concurrency, but it's very bad at being embedded into other code and not the best choice if you're mostly calling FFI libraries.)

First, it would be good for Rust to stick to that decision. Rust should not regain a pausing GC in the standard library - similarly, it should not regain a thread manager in the standard library.

Second, it would be good for Rust libraries to work within the spirit of that decision. That's a lot harder, because part of the expectation when those features were removed was that some needs - notably around event-based processing - would be met by third-party libraries. As I understand it (and I might be totally wrong!), it was honestly a bit of luck that the borrow checker worked as well as it did and was ready at the right time, and the expectation was that someone would add a GC library and it would be widely used. However, it's very good that no widely-used GC library sprung up. In the same vein, it would be good for there to be no widely-used third-party thread manager library.

This might be hard, possibly requiring a borrow-checker-level miracle, but it's worth aiming for. And if there has to be a thread manager (or a garbage collector), it should not be part of core Rust.

Would you agree with that phrasing?

--

Incidentally, why does reqwest start up a polling thread when called in sync mode? Can't it do the polling on the main thread? (Or in other words, async programming doesn't imply multithreaded programming. I actually sort of expect that async programming is better suited to single-threaded programming with an event loop, because if you're okay with threads, you may as well just write synchronous code on threads! So either there is something subtle and very interesting here, or there's an easy fix, or I'm misunderstanding something badly.)

Re:Building a shared vision for Async Rust by dunkelheit on Friday March 19, 2021 @06:31AM (#26511803)
I think this rephrasing misses the mark a bit on the original concern. GP explicitly states that he wants Rust-the-language to remain as it is - close to the metal, no GC, with minimal runtime and 1:1 threading. The concern is indeed with the libraries/ecosystem. We are not quite there yet, but it is not hard to imagine that in a few years somebody who asks how to do some simple task in a blocking fashion will be met with replies in the vein of "well, that's not idiomatic", "why don't you use async", or "there was a library for that but it is now kind of unmaintained". All because the main effort of the community went into supporting and maintaining the async mode.

If the reqwest library indeed spawns a thread for every request, it is a good example of that dynamic. Sync mode kind of works but is clearly a second-class citizen and works in a suboptimal fashion. And if you want to peek under the hood to debug it you still have to deal with the async machinery in all its gory detail.

Re:Building a shared vision for Async Rust by geofft on Friday March 19, 2021 @10:05AM (#26513456)
So that gets at my second question. I would expect that if async mode is working well, it specifically avoids needing libraries to spawn a thread.

Or put another way - when Rust removed M:N threading and also shipped out of the box with no event handling support after removing librustuv, the recommendation was that libraries should use threads to handle concurrency and make blocking calls on each thread, and modern OSes make threads perform well, so why not. Isn't the whole point of revisiting async to avoid that answer?

I have the same use cases of wanting Rust to be a close-to-the-metal language with a minimal runtime that you can safely plop in place of any C code, and it seems to me that the way to do that is to get the async story to be so good that people start saying "Well, that's not idiomatic" and "That approach was common but the libraries are all unmaintained" to libraries that spawn threads. What am I missing? Why are we associating "more async" with "more threads" instead of "remain on the calling thread and use an event loop"?

Re:Building a shared vision for Async Rust by jjtheblunt on Thursday March 18, 2021 @11:25PM (#26509911)
Exactly
Re:Building a shared vision for Async Rust by cycloptic on Thursday March 18, 2021 @11:45PM (#26509987)
That doesn't seem to be related to async? I don't know the details of rust's async implementation but that sounds like a problem with your application's setup -- you should be able to have a single threaded async executor that uses an event loop, or in simple cases, just calls poll/select directly?

To put it another way, it's unfortunate that particular synchronous API is implemented using threads, but there is nothing about async that implies one way or another that a synchronous method will be implemented using threads -- I've seen plenty of (questionable) C functions that do similar things like using pthread_create and then pthread_join immediately after to fake a blocking task.

Re:Building a shared vision for Async Rust by ori_b on Friday March 19, 2021 @12:17AM (#26510115)
Er? No, the point is that threads are what you want for cpu-bound tasks. Async does not deal well with long running cpu intensive jobs that hog the cpu without yield points.
Re:Building a shared vision for Async Rust by cycloptic on Friday March 19, 2021 @09:11AM (#26512877)
Why not? The fix there sounds like it's as simple as adding some yield points.
Re:Building a shared vision for Async Rust by ori_b on Friday March 19, 2021 @09:20AM (#26512955)
Yield points in the middle of a large matrix multiplication (for example)?

Manually scheduling threads seems like a really shitty way to program

Re:Building a shared vision for Async Rust by cycloptic on Friday March 19, 2021 @11:17AM (#26514277)
Not really? That's cooperative multitasking and it's used a lot: https://en.wikipedia.org/wiki/Cooperative_multitasking

But regardless, the GP post was not taking about matrix math, it seems it was talking about sending an HTTP request and waiting for a response, which is something that actually is I/O bound on the TCP socket.

Re:Building a shared vision for Async Rust by ori_b on Friday March 19, 2021 @11:55AM (#26514813)
I know what it is, and there's a reason that all the systems listed as using it are obsolete.

> "I don't want an async model, which assumes you're I/O bound, interfering with keeping all those CPUs busy."

Strongly implies to me that there's a CPU-bound component there.

Re:Building a shared vision for Async Rust by cycloptic on Friday March 19, 2021 @01:30PM (#26516014)
The systems that use it as a native threading model are obsolete, but there's also this sentence there:

>Cooperative multitasking is used with await in languages with a single-threaded event-loop in their runtime, like JavaScript or Python.

There's no reason rust can't have an executor that does the same, and you only use that within the event loop on your one or two HTTP worker threads. If you're waiting in a thread for an HTTP request to return, that's never going to be CPU-bound. I still am failing to see what the problem here is besides a complaint about some rust crate only supporting a multi-threaded executor, which again is a different problem than whether it's done with async futures or not. One could just as easily write some C code that forces the use of threads.

Re:Building a shared vision for Async Rust by ori_b on Friday March 19, 2021 @02:59PM (#26517102)
Those languages are also well known for not handling multiple cpu bound threads well. (And for that matter, it's simply wrong about Python, which uses native threads, but locks very heavily: you need to write native code to use more than one core effectively from one process.)

The goal is to NOT do what you're suggesting. It's a holdover from when native threads were much more expensive than they are today, and multiple cores on a single cpu were rare.

Re:Building a shared vision for Async Rust by h0l0gr4ph1c on Friday March 19, 2021 @12:34AM (#26510184)
Complexity kills code. Being able to reason about what your code is doing, is FAR more valuable to me than async. Having tokio act as my runtime and switch tasks as it sees fit will be debug hell.

The problem I see is the current async story is opt-out. It's use async or go find something else. Async should be opt in. As in, the code works regardless of an async runtime, async is added magic if you want it, but it will run like normal single threaded code if not.

Re:Building a shared vision for Async Rust by Animats on Friday March 19, 2021 @01:03AM (#26510294)
The problem I see is the current async story is opt-out. It's use async or go find something else. Async should be opt in.

That sums this discussion up nicely.

Re:Building a shared vision for Async Rust by songqin on Friday March 19, 2021 @11:23AM (#26514359)
> The problem I see is the current async story is opt-out.

Surely this is only the case if you have picked asynchronous libraries to use?

Re:Building a shared vision for Async Rust by steveklabnik on Friday March 19, 2021 @11:29AM (#26514446)
Yes, in fact, you cannot even use async Rust without writing your own executor or bringing one in via a library. It is very, very much opt in. That was a hard constraint on the design.

However, I think what the parent is getting at is the feeling of the total package, not the technical details. If every library you want to use is async, you can't really "opt out" exactly, even if technically the feature is opt out.

Re:Building a shared vision for Async Rust by h0l0gr4ph1c on Monday March 22, 2021 @09:14AM (#26540315)
By opt in I mean I can opt in to using an executor if I want async. If I don't code still works and is might not be as performant.

Couldn't you have made another hard constraint to make async code work as normal if the programmer wanted?

Re:Building a shared vision for Async Rust by steveklabnik on Monday March 22, 2021 @09:17AM (#26540350)
An executor is required, in name or in spirit. Every async system has software that does this. Most language runtimes that do simply give you no choice in the matter.
Re:Building a shared vision for Async Rust by h0l0gr4ph1c on Tuesday March 23, 2021 @12:09AM (#26550999)
Rust is a language that does things different to other languages because it is a better way. I challenge you to do the same with Async. There is a different better way.
Re:Building a shared vision for Async Rust by h0l0gr4ph1c on Monday March 22, 2021 @07:58AM (#26539598)
I actively choose libraries that are non-async. I don't want to use the programming model.

If aysnc could work like regular blocking code , if we want, and async code when you want, I think rust would be in a better place.

Just because you can do something doesn't mean you should.

Re:Building a shared vision for Async Rust by deft on Friday March 19, 2021 @12:02AM (#26510062)
No, its not a misconception. It still uses tokio. It still triples my compile time.
Re:Building a shared vision for Async Rust by hda2 on Thursday March 18, 2021 @10:59PM (#26509809)
> The main thing I want for Async Rust is the ability to not use it.

This is what many of us want. Sadly this doesn't seem to be a use-case many in rust are interested in supporting as a first class citizen (from what I've read at least).

I remember seeing someone being down-voted into oblivion for the mere suggestion of some sort of basic fallback executor in the standard library.

Rust's async story is a weird one.

Re:Building a shared vision for Async Rust by GolDDranks on Thursday March 18, 2021 @11:46PM (#26509989)
Just to be clear, you are saying that many 3rd party libraries in the ecosystem are not interested in "supporting as a first class citizen", right? Because as for the language itself and the standard library, they are committed to support both as first-class citizens.
Re:Building a shared vision for Async Rust by atweiden on Thursday March 18, 2021 @11:02PM (#26509831)
I'd just like to mention popol here [1]:

    Popol is designed as a minimal ergonomic wrapper
    around poll, built for use cases such as peer-to-peer
    networking, where you typically have no more than a
    few hundred concurrent connections. It’s meant to be
    familiar enough for those with experience using mio,
    but a little easier to use, and a lot smaller.
[1]: https://cloudhead.io/popol/
Re:Building a shared vision for Async Rust by alfiedotwtf on Friday March 19, 2021 @03:41AM (#26510870)
> "Async" is a specialized tool for web servers with very large numbers of clients. Outside of that niche, it's seldom needed.

Web is just 2 ports out of the 65535 TCP/IP ports. Network servers can benefit from an async model depending on the server design.

Let’s not sweep all of networking into “web”.

Re:Building a shared vision for Async Rust by lmm on Thursday March 18, 2021 @10:49PM (#26509778)
You want libraries to be able to offer implementations that are polymorphically async-or-not (perhaps using higher-kinded types). That's how I'm used to working in Scala.
Re:Building a shared vision for Async Rust by geofft on Thursday March 18, 2021 @11:20PM (#26509894)
This is also a problem over in Python-land. One of the interesting approaches is automatically generating non-async code from async code by editing out the async annotations (at the source level). The Trio folks call this "bleaching" the code, in reference to the "What color is your function?" blog post https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... complaining about how the common approach to async in JavaScript divides the world into "red" (async) and "blue" (sync) functions that interoperate poorly - you can bleach your code if it's the wrong color.

https://github.com/urllib3/urllib3/issues/1323 is a discussion of this. "Solution: we maintain one copy of the code – the version with async/await annotations – and then a little script maintains the synchronous copy by automatically stripping them out again. It's not beautiful, but as far as I can tell all the alternatives are worse.

https://github.com/python-trio/unasync is the current production implementation of this approach.

Re:Building a shared vision for Async Rust by kmeisthax on Friday March 19, 2021 @12:10AM (#26510091)
In Rust, you don't need to do this. If you want a blocking version of a non-blocking function, you spin on poll. Several async libraries ship a block_on function that does just that. If you can't do that, but don't want to bring in a proper big-boy executor; you can spin off another thread, have it block, and join it when it's done. (or use something like crossbeam's scoped threads)

Colored functions are a problem in JavaScript because it has to share an event loop with the rest of the browser. For Node.js and Python, that is less of an issue, but those languages are also either practically or actually single-threaded, which also means async behavior is contagious. Rust does not have this problem, at least not until you're writing WASM programs with it (in which case, you're restricted to sharing one thread with the rest of the browser again).

Re:Building a shared vision for Async Rust by geofft on Friday March 19, 2021 @12:20AM (#26510127)
Well, 'Animats expresses a desire in another comment for functions not to go off and spawn a new thread.

I do somewhat agree with that desire - I don't think that this is a problem for performance, but since most of my use of Rust is dropping it into existing C code, I think that spawning a thread is likely to have annoying visible side effects on the calling code, which might not be expecting me to do that.

Using a proper, single-threaded executor and running it on the current thread seems like it would work, yes. (To be fair, I also feel like just having the sync version of a Python API call "trio.run(self.equivalent_async_api)" would probably also work, and I don't totally follow why that's insufficient....)

Re:Building a shared vision for Async Rust by h0l0gr4ph1c on Friday March 19, 2021 @02:41AM (#26510620)
> "Using a proper, single-threaded executor and running it on the current thread seems like it would work, yes. (To be fair, I also feel like just having the sync version of a Python API call "trio.run(self.equivalent_async_api)" would probably also work, and I don't totally follow why that's insufficient....)"

Why do I need all this other bloat just to run a function? Why can't I just run the function?

Re:Building a shared vision for Async Rust by geofft on Friday March 19, 2021 @02:50AM (#26510667)
I'm not sure exactly what you're asking, but I think it's either answered by the "What color is your function?" article I linked above, or by the answer that this is exactly why unasync exists and why I suggested that approach is worth considering, or by the answer that you can, in fact, just run the function and the "bloat" (which is just syntactic bloat - note that performance is generally going to be better!) is taken care of behind the scenes by a wrapper that calls an executor for you.
Re:Building a shared vision for Async Rust by h0l0gr4ph1c on Friday March 19, 2021 @03:21AM (#26510780)
yes sorry, those were rhetorical questions. Your point about asking you fail to see why not using a blocking executor to deal with the async code. My problem is with needing the executor at all. I must have skipped a couple of you previous pints in this thread. Apologies about that...

Maybe we should start trying to think about async as being something can use if they want and ignore if they want. Code being async compatible rather than async required.

Re:Building a shared vision for Async Rust by geofft on Friday March 19, 2021 @10:00AM (#26513399)
How would this work? (I do really think this is the right model, I'm just trying to figure out what that model is, exactly. :) )

Let's say I have code like this, in Python asyncio:

    class ShardedDBClient:
        async def query(self, key):
            tasks = [self.query_shard(key) for shard in self.shards]
            results = await asyncio.gather(*tasks)
            for partial_result in results:
                if key in partial_result:
                    return partial_result[key]
            return None
How do you run this without an executor?

The obvious way to make it not be "async required" is to say, we get rid of the async/await keywords - but what do you do with that "await asyncio.gather" instruction? Do you call each of those callbacks serially?

Generally, even in Rust (perhaps especially in Rust), I would expect this to use some OS facility for waiting on multiple sockets (possibly even just boring select(), but preferably epoll/kqueue) to send a bunch of database requests out in parallel and then wait on all their sockets to handle responses as they arrive. I would expect that even if my own code doesn't involve async/await at all.

The easy way to implement that is

        def sync_query(self, key):
            return asyncio.run(self.query(key))
which creates an asyncio executor just to run that one function.

This is going to be a lot faster than querying those shards one at a time! And it also can semantically change how the library behaves - imagine that there's a timeout parameter, and I set a 100ms timeout. I probably mean that to be 100ms for the entire operation, not 100ms per request, but I probably also don't expect my calls to always fail if each query takes 10ms and there are more than 10 shards.

The downside is that this library is quietly using asyncio without you knowing. But how exactly is that a downside? I already expect the library to be using select/epoll/kqueue without me knowing. And in a language like Rust, the executor should basically compile out - it should be a "zero-cost abstraction" compared to writing the event-handling code by hand.

Re:Building a shared vision for Async Rust by pas on Friday March 19, 2021 @04:56AM (#26511269)
As long as the async code doesn't depend on calling itself concurrently it should be straightforward to simply execute it on the current thread, right? (Basically using an executor that has 1 thread, the current thread.)

And it'd be great to check and optimize away all this at compile time.

Re:Building a shared vision for Async Rust by lmm on Friday March 19, 2021 @12:25AM (#26510147)
It's a problem if your function to query a database or whatever instantiates a bunch of futures and yields between them when you're just going to block. Given that Rust is designed for environments that are so limited that they can't afford garbage collection, that stuff is proportionately pretty costly.
Re:Building a shared vision for Async Rust by millstone on Friday March 19, 2021 @01:20AM (#26510356)
Does spin-on-poll imply actual spinning (100% CPU) or actual blocking (waiting in a syscall)?
Re:Building a shared vision for Async Rust by dodobirdlord on Friday March 19, 2021 @01:34AM (#26510403)
That would have to be determined at the discretion of the implementer of the library. Rust is after all capable of being used to write code that will run in a context where there is no kernel and thus no syscalls.
Re:Building a shared vision for Async Rust by millstone on Friday March 19, 2021 @02:51AM (#26510669)
I don't get it - what library? I may have an `async` function and this is part of the Rust language, not tied to any library. Can I make it into a blocking function without 100% CPU?
Re:Building a shared vision for Async Rust by pas on Friday March 19, 2021 @04:52AM (#26511246)
"async/await" is just syntactic sugar for a function that returns a Future plus a state machine at yield points. You need a library (executor) to run that Future (execute that function).

The Rust standard library's block_on uses a global ThreadPool, and the docs recommend using a LocalPool if you need finer grained control.

So, to answer your question it depends on the executor (the thing that implements block_on).

Re:Building a shared vision for Async Rust by steveklabnik on Friday March 19, 2021 @09:41AM (#26513189)
(To be clear, block_on is not in the Rust standard library.)
Re:Building a shared vision for Async Rust by pas on Friday March 19, 2021 @10:01AM (#26513407)
ah, darn, thanks!

So for anyone reading for the correct details: the block_on I was thinking of is part of the futures crate, which is not in std, it's not an "official library".

Re:Building a shared vision for Async Rust by steveklabnik on Friday March 19, 2021 @10:59AM (#26514088)
It's all good! It was proposed, but decided to have an RFC first. Your point is still correct, just wanted to make sure to clarify this detail :)
Re:Building a shared vision for Async Rust by lmm on Friday March 19, 2021 @12:20AM (#26510123)
Wow. Reminds me of those go projects that use templated code with Canadian Aboriginal Syllabics to work around the lack of generics.