Live data from Hacker News

Async-await on stable Rust

blog.rust-lang.org

261–270 of 392 posts

Re: Async-await on stable Rust

#261

Earlier quoted context omitted.

ML-inspired languages have all these features too; is the advantage of Rust over those just that it’s more mainstream, the ecosystem is bigger, etc.?

One of my favorite features of Rust as someone who dabbles is that thread safety is expressed in the type system. F# is perfectly happy to let me share mutable data across threads without any synchronization, while the Rust compiler knows whether something can be safely accessed because you've either transferred ownership, or the type is thread safe. The ownership system is also a very clever approach to managing mut…

IMO both language types offer shared state and immutable data structures so I don't see them as mutually exclusive. As the Rust guys I've heard say "sharing state and mutation are fine, just not together". It's a question of whether the problem your trying to solve is better as a highly mutable one with "sharing" (e.g I'm thinking system programming with contended system resources) or you want to share data across many threads simultaneously and are happy with slower single threaded performance for greater multi threaded throughput (writes are rare so sharing and locking on an atomic ref on occasion is OK so you want structural sharing of data). Rust helps the coder avoid the issues when coding in the traditional "sharing and mutation" paradigm especially without a GC; languages like F# have some modern things to do this like atomic refs for data sharing, flagging mutables, async lock types, support for imperative programming etc. Both approaches work and IMO suit different kinds of problems; good to have both available.

Re: Async-await on stable Rust

#262
post #30

Isn't it kind of a poor design choice that Rust will not actually begin execution of the function until `.await` is called? If I didn't want to execute the function yet, I wouldn't have invoked it. Awaiting is a completely different concept than invoking, why overload it? If you want to defer execution of a promise until you await it, you can always do that, but this paradigm forces you to do that. The problem is the…

Those don't actually execute simultaneously in Javascript, though. In Javascript, C# and I suspect Java, each usage of await generates a state machine that can _defer execution_. So while one function is blocked, another can continue to execute. The concept is the same in Rust, except in Rust a nested await does not generate a new state machine. The entire async operation just uses a single state machine. The reason…

Java actually doesn't have async/await as a language level feature. It does have the Future interface, but it's just an interface, and not special in any way.

Re: Async-await on stable Rust

#263
If you're just starting to learn Rust, I suggest waiting a little before using async. It's awesome, BUT libraries, tutorials, etc. will need a while to update from the prototype verion of Futures (AKA v0.1) to the final version (std::future). Changes made during standardization were relatively minor, but there's no point learning two versions of Futures and dealing with temporary chaos while the ecosystem switches to the final one.

Re: Async-await on stable Rust

#264
This is awesome... been waiting on this... looking at a lot at rocket and yew (really new with rust), and had been waiting to see the async stuff shake out before continuing (been holding for a few months now), may take a bit of time over the weekend to start up again.

Re: Async-await on stable Rust

#265
post #123

Earlier quoted context omitted.

I don't know Rust but I understand the question if await is the only way to yield execution. Without a yield instruction its strange to ask "how do I start all these futures before I await" and join does make sense because it does both of those things. But other languages can start futures, yield, reenter, start more futures, and wait for them all while making progress in the mean time. I'm curious what the plan in t…

Join doesn't do everything. It's just a way to take multiple futures, and return a Future wrapping them all. I think there's a misunderstanding of how Futures and Executors interact in rust here which is why everyone is having a hard time understanding things. A future in rust is really just a trait that implements a `poll` function, whose return type is either "Pending" or "Ready ". When you create a future, you're…

This is essentially what I assumed and what I believe what ralusek assumes to be the case. This does not change our question.

What would be the syntax for how you would spawn a future, add it to the current Executor, cooperatively yield execution in the parent such that progress could be made on the child, but also return execution to the parent if the child yields but does not complete?

In C# I believe you could simply call

    Task.Run(Action);
This will schedule the action to the current executor. If you yield execution through await that task will (have a chance to) run. The crux of the question is that the fact that you do not need to await that specific task, you just need to cooperatively yield execution such that the executor is freed up.

    var shortTask = Task.Run(Task.Delay(100).Wait);
    var longTask = Task.Run(Task.Delay(500).Wait);
    await Task.Delay(1000);
  
    await shortTask;
    await longTask;
In C# this will take ~1000 milliseconds as the child futures yield execution back to the parent such that it can start its own yielding task.

Re: Async-await on stable Rust

#267
post #98

This is a big improvement, however this is still explicit/userland asynchronous programming: If anything down the callstack is synchronous, it blocks everything. This requires every components of a program, including every dependency, to be specifically designed for this kind of concurency. Async I/O gives awesome performance, but further abstractions would make it easier and less risky to use. Designing everything a…

Or just use a preemptive scheduler (such as a regular OS scheduler). Or just be explicit, and take difficulties with being explicit as an indication that the data flow is maybe not very well designed. I don't know, maybe there are valid applications for await (such as much frequented web servers, where you might want to have 10s of thousands of connections, that would be too expensive to model as regular threads, but…

> Or just use a preemptive scheduler (such as a regular OS scheduler).

Well... I can't help but whenever I see the await stuff it reminds me of times where I had to do cooperative multitasking and was longing for OS and/or CPU support for something which is non-invasive to my algorithms. But then I'm not sure whether I'm the grumpy old man or it is just history repeating.

Re: Async-await on stable Rust

#268
post #255

Earlier quoted context omitted.

What you tried wasn't "this", though. It was one particular implementation of lightweight threading that has to cope with Rust's peculiarities, special requirements and compilation targets. There is absolutely nothing essential about lightweight threads that prevents them from emitting essentially the same code as the stackless-coroutine approach. It's just that in Rust it might be very hard or even not worth it, giv…

Fibers under the magnifying glass [1] might be a relevant paper here. Its conclusion, after surveying many different implementations, is that lightweight threads are slower than stack less coroutines. [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p136...

No, its conclusion is that fibers with certain properties in C/C++ are slower -- and particularly hard to implement correctly -- than stackless coroutines in C/C++. That's because of the particular characteristics of those languages. In fact, you'll note that the only negative thing he says about Go is that it incurs an overhead when interacting with non-Go code.

Re: Async-await on stable Rust

#269
post #110
post #65

Earlier quoted context omitted.

JavaScript does not automatically start the tasks. It executes the function if you...execute the function. If you just want to pass around something with deferred execution, you can just pass the function around, or wrap it in a closure.

It does automatically start the tasks. JavaScript asyncs are "hot". You can simulate "cold" asyncs using a function, as you describe, but in other languages this is how they work by default.

I’m not sure exactly what hot is here, but if that’s the case then all javascript functions are hot. It’s behaving consistently with any other function. I assume the point here is that Rust in this case changes the way function calls work based on async, which is, well, inconsistent.

Re: Async-await on stable Rust

#270
post #5

Earlier quoted context omitted.

Are there that many people looking for a new low level language for server side software?

Yes! Rust is the first language that is both truly good as a low-level systems language and also truly good as a high-level modern labguage at the same time . To me, it's amazing to finally have another option aside from just C/C++. Technically, I might have had some other options before, but rust gets it right.

I would say Ada/SPARK gets a lot of things right, too. What it lacks is hype and thus, a vibrant ecosystem. It can be a huge deal-breaker to many people.
Post reply on HN