Hacker News new | past | comments | ask | show | jobs | submit login
FuturesUnordered and the order of futures (without.boats)
43 points by todsacerdoti 76 days ago | hide | past | favorite | 16 comments



"Spawning multiple tasks requires that each task be 'static, which means they cannot borrow data from their parent task."

The lack of structured concurrency or anything like thread::scope in async Rust can be quite a headache. Requiring tasks to be 'static basically forces you to Arc<> everything, at which point you start wondering why you aren't just using a GC'd language like Go, Java, or Kotlin.


I was wondering something similar. Is all of this a symptom of the fact that the whole async (and multithread) system isn't based on structure concurrency? Wouldn't a really deep embrace of structured concurrency work beautifully with the borrow checker? Or am I on the wrong track?

Recently I read (I can't quite remember where, but I think it was in the context of actors) someone making out computational DAGs as "just a pipeline" - but this misses that a webserver or app or game or whatever should also have DAG-like computation graphs. I might be really on the wrong track here, but trying to jam all these independent "actors" into the one program seems odd - the game players, app users, web clients, etc are other actors. Your database might be an actor. But why would you want your own program to be a bunch of arbitrary actors that can interact with each other willy-nilly? Is there something useful you can do within a single process that isn't possible with structured concurrency?


Speaking entirely out of inexperience, perhaps it's a situation where you could theoretically do everything with structured concurrency, but you'd have to have deep understanding of all the details of your system, not to mention needing to update it if aspects change. So it might be less of a hassle in developer time and energy to have a looser model.


Structured concurrency in Rust is a hard problem. Boats blogged about this before: https://without.boats/blog/the-scoped-task-trilemma/


Ah thanks! I had seen this trilemma referred to before but never read the source until now.

From the scoped task trilemma:

> Assuming that we are not adding linear types to Rust, ...

Going back to my earlier post, I still wonder if some (theoretical) language with linear types would be able to do structured concurrency with convenient borrows and so-on? (The issues seem related to late drops, leaks, etc).


For me, the strongest reason to use Rust anyway is that Rust makes it practical to write a single library that can be efficiently embedded in multiple runtime environments. One probably wouldn't want to use a Go library, for example, in a C, Java, or Python project, even though it's possible with cgo. Of course, if a Rust library is using async under the hood, it'll probably run a main loop on its own thread. But that happens often enough in C and C++ libraries as well.


> Spawning multiple tasks requires that each task be 'static, which means they cannot borrow data from their parent task

Is this just tokio thing? For example https://docs.rs/async-executor/latest/async_executor/struct.... does not have 'static in the signature, but I'm not nearly familiar with the topic to understand fully all the details


Apparently that's a thread-local executor (scroll up to the top of the page).


Great post! Thanks for sharing

EDIT: What do you use to make your blog? I quite like the format


I use a markdown static site generator with a custom layout and CSS. Currently I use hugo, but I don't like it and I'm re-writing my site with zola when I have the time. The ASCII flow charts are made in vim, they're just code blocks in the markdown file.


Wake me up when Rust collections work with async code out of the box.

Every time I use Rust, my soul wants to see constructions using map, filter, and what not, similar to Scala. But no easy async support for those functions make the resulting code really difficult to look at.


This comment is really not relevant to my post, but its a work in progress. Async closures were just added to the nightly compiler, and their author wrote an async iterator combinator library here: https://github.com/compiler-errors/async-iterator-ext


Thank you.


IMHO Rust async is still unfinished and will be until it's 1:1 with the entire rest of the language.


So...the same as Scala?


(in Rust)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: