Live data from Hacker News

Why you might want async in your project

notgull.net

101–110 of 182 posts

Re: Why you might want async in your project

#101
post #87

I mean.. I appreciate that there are proponents and people trying to improve the state of async rust but to allude that everything is dandy is either dishonest or more likely a strong curse of knowledge bias. I’ve worked deeply in an async rust codebase at a FAANG company. The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere, not to mention the giant dep tree of crates…

> The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere

And?

> not to mention the giant dep tree of crates to do even menial things.

Again, And?

I don't really care about having to pull in crates. That has always been how Rust does things - it prefers many small crates over fewer large crates. Async is no different.

And I don't care about Arc either. Writing `let x = blah()` is not much better than `let x = Arc::new(blah())`.

If you're talking about something else, like idk, maintaining mutability across multiple threads, yeah that's going to be more painful. It's also painful in most other languages and is generally avoided for that reason.

> The ones who try to use proper lifetimes etc are haunted by the compiler and give up after enough suffering.

You say "proper lifetimes" as if lifetimes are desirable. In async code they are not - your lifetime is often "arbitrary" and that's what an Arc gives you. The solution is, as mentioned, using an Arc or Box or Mutex.

> Async was an extremely impressive demo that got partially accepted before knowing the implications.

I think this is a totally ignorant characterization of async, which was years in the making, took lessons learned from decades of async in other languages, and was frankly led by some of the most knowledgeable people in regards to these sorts of systems.

> (If you disagree, try to explain pin projection in simple terms.)

The vast majority of people will never have to know what a pin projection is, let alone how it works. It rarely comes up, and virtually only if you're writing libraries. I could explain it but I see no reason to do so here (it is not complicated at all, `Pin` is probably the harder one to explain).

> The damage to the ecosystem from fragmentation is massive.

It's not even noticeable lol like, what? What fragmentation? I've never run into an issue of fragmentation and I've written 100s of thousands of lines of Rust.

> It would have been better to

How nice to sit on the sidelines and throw out a paragraph sized proposal. Everything looks great when you hand wave away the complexity of the problem space.

Async Rust isn't perfect (I frankly don't think there is a "perfect" solution, that should not be contentious I hope) and I welcome criticism, but your post is totally unconstructive and unsubstantial.

Re: Why you might want async in your project

#102

I might need a lot of stuff in my software. Eventually. I might need distributed database, or to to scale it out to run on multiple machines, and then maybe Raft, or reactive architecture, zero-copy IO, or incremental updates or ... or ... the list goes on and on. Thinking too much and in particularly going with over complicated solutions from the very start because "might" is just bad engineering. Also, even if I do…

I guess one thing going for it is that then Rust is a lot more like Node, which could help increase its popularity. I wonder if Rust at some point in its history became self-serving (bigger == better).

Re: Why you might want async in your project

#103
post #87

I mean.. I appreciate that there are proponents and people trying to improve the state of async rust but to allude that everything is dandy is either dishonest or more likely a strong curse of knowledge bias. I’ve worked deeply in an async rust codebase at a FAANG company. The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere, not to mention the giant dep tree of crates…

Your position wrt green threads sounds like Graydon's ( https://graydon2.dreamwidth.org/307291.html ).

Yeah, perhaps. But I am not part of that minuscule subset of people who have deep expertise in both compiler internals and runtime architecture to have well founded opinion on the design. There is FFI and stack issues that’d need some incredibly bright engineers to sort out.

My argument is more along the lines of: modularity is the (only) way to reduce complexity. We already have modular runtimes in other languages (project loom in Java, webassembly etc). Most people should not care about runtimes much. The ecosystem cost of async ended up being high. Thus, runtimes should be an implementation detail for most users.

Doesn’t mean Rome has to be rebuilt. Perhaps the async we have can be saved, but even so it involves biting the apple of actually defining precisely what a runtime is so that crate authors can think of them just like they think of allocators today (ie not at all).

Re: Why you might want async in your project

#104

I might need a lot of stuff in my software. Eventually. I might need distributed database, or to to scale it out to run on multiple machines, and then maybe Raft, or reactive architecture, zero-copy IO, or incremental updates or ... or ... the list goes on and on. Thinking too much and in particularly going with over complicated solutions from the very start because "might" is just bad engineering. Also, even if I do…

> But nobody wants to write a library that isn't "web-scale" anymore, so tough luck.

It's more like "I want to be able to put timeouts in my code". 99% of why I want async is so that if something takes too long I can just stop that. That is incredibly hard to do without async.

Re: Why you might want async in your project

#105
post #98

>Except, this isn’t a problem with Rust’s async, it’s a problem with tokio. tokio uses a 'static, threaded runtime that has its benefits but requires its futures to be Send and 'static. It's not a problem with tokio either. The author's point is specifically about the multi-threaded tokio runtime that allows tasks to be moved between worker threads, which is why it requires the tasks to be Send + 'static. Alternative…

Actix-web uses the single threaded Tokio runtime per physical core. This architecture is harder to design for than multi threaded async Tokio. Performance gains aren't worth the effort.

We use the same design for a product at $dayjob and have had no difficulty in designing for it. There is a lot of benefit from being able to use Rc and RefCell instead of having to go for Arc and Mutex. (Of course it's best if it can be written to not have any RefCell / Mutex at all.)

Re: Why you might want async in your project

#106
post #87

I mean.. I appreciate that there are proponents and people trying to improve the state of async rust but to allude that everything is dandy is either dishonest or more likely a strong curse of knowledge bias. I’ve worked deeply in an async rust codebase at a FAANG company. The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere, not to mention the giant dep tree of crates…

> The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere And? > not to mention the giant dep tree of crates to do even menial things. Again, And ? I don't really care about having to pull in crates. That has always been how Rust does things - it prefers many small crates over fewer large crates. Async is no different. And I don't care about Arc either. Writing `let x = b…

I am of the same impression — Rust as a language forces you to come at terms with your own ideas of how code should look.

That being said I still have a deep dislike of having to read through nested Arc Mutexes or whatever to figure out what the code does in principle before I figure out what is going on in detail with the ownership.

I know there are no perfect solutions and there are trade-offs to be made, but I wish there was a way to have it more readable.

So instead of this:

    let s = Arc::new(Mutex::new(Something::new("foo")));
something a bit like this:

    let s = Something::new("bar").arc()
                                 .mutex();

Re: Why you might want async in your project

#107
post #87

I mean.. I appreciate that there are proponents and people trying to improve the state of async rust but to allude that everything is dandy is either dishonest or more likely a strong curse of knowledge bias. I’ve worked deeply in an async rust codebase at a FAANG company. The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere, not to mention the giant dep tree of crates…

I don't have a degree in CS so I always feel out of my element in these discussions...

Is the runtime something the compiler adds to the binary to make sure it is able to correctly interact with the system it is built for?

It seems like people argue that green threads require a runtime as if async doesn't? I don't understand the arguments on either side. In terms of what code looks like I far prefer being able to just declare green threads like golang does.

Honestly I wish I understood on a deep level, but I've been programming for 17+ years and the fact that I still don't implies to me that I never will.

Re: Why you might want async in your project

#108
post #56

Earlier quoted context omitted.

NB: In Python >= 3.9 the idiomatic way to do this is to_thread(), not familiar with these ASGI functions but I would guess they're a polyfill and/or predate 3.9. https://docs.python.org/3/library/asyncio-task.html#asyncio....

They are not polyfills. Multiple scheduling modes are provided for libraries that are not thread safe (it's a total mess and I avoid these wrappers like the plague)

I've had to weld some async and sync Python together with queues and callbacks, it's not pretty.

Re: Why you might want async in your project

#109
post #106

Earlier quoted context omitted.

> The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere And? > not to mention the giant dep tree of crates to do even menial things. Again, And ? I don't really care about having to pull in crates. That has always been how Rust does things - it prefers many small crates over fewer large crates. Async is no different. And I don't care about Arc either. Writing `let x = b…

I am of the same impression — Rust as a language forces you to come at terms with your own ideas of how code should look. That being said I still have a deep dislike of having to read through nested Arc Mutexes or whatever to figure out what the code does in principle before I figure out what is going on in detail with the ownership. I know there are no perfect solutions and there are trade-offs to be made, but I wis…

FWIW Arc implements From so you can do `let foo = blah().into()` and if `foo` is passed to something expecting Arc it'll be an Arc. This probably works for Arc> as well so you'd be able to do `.into().into()` but I'm not sure.

Re: Why you might want async in your project

#110
post #87

I mean.. I appreciate that there are proponents and people trying to improve the state of async rust but to allude that everything is dandy is either dishonest or more likely a strong curse of knowledge bias. I’ve worked deeply in an async rust codebase at a FAANG company. The vast majority chooses a dialect of async Rust which involves arcs, mutices, boxing etc everywhere, not to mention the giant dep tree of crates…

I don't have a degree in CS so I always feel out of my element in these discussions... Is the runtime something the compiler adds to the binary to make sure it is able to correctly interact with the system it is built for? It seems like people argue that green threads require a runtime as if async doesn't? I don't understand the arguments on either side. In terms of what code looks like I far prefer being able to jus…

A Runtime generally refers to "things added to the program to make it work". That can mean libc, it can mean a GC, etc.

> I don't understand the arguments on either side. In terms of what code looks like I far prefer being able to just declare green threads like golang does.

Under the hood `async` is sugar over a function such that the function returns a `Future` instead of a `T`. What is done with that future is up to the caller.

In most cases this is handed off to a runtime (your choice of runtime, generally speaking) that will figure out how to execute it. You could also manually poll the future until it's complete, which does happen sometimes if you're manually implementing the Future trait.

If you have no async code you can simply avoid having an async runtime altogether, reducing the required runtime for an arbitrary program.

> I far prefer being able to just declare green threads like golang does

This relies on an implicit runtime. That's fine - lots of Rust libraries that work the way you're suggesting will just assume a runtime exists.

That lets you write:

    spawn(async {println!("hello from async");});
And, just like a goroutine, it will be scheduled for execution by the implicit runtime (or it will panic if that runtime is not there).

Note that this implicit runtime has to be there or you'll panic. This means that the reasonable behavior would be to always provide such a runtime, which would mean that even "sync" programs would need it. Or otherwise you'd need to somehow determine that no "async" code is ever actually called and statically remove it. That is a major reason why you wouldn't want this model in a language that tries to minimize its runtime.

> but I've been programming for 17+ years and the fact that I still don't implies to me that I never will.

I think it's just a matter of exposure. Try writing in more languages like C, C++, Rust, etc, and dig into these features.

Post reply on HN