Earlier quoted context omitted.
> The supervisory system is an extra, you don't technically need it but it can help make your application bullet proof and I would definitely recommend if you go the Erlang route to use it to your advantage. An actor system without supervisors is throwing away a lot. How do you handle an actor that crashes? The thing is, again, Actors are very low level - they're a foundational model. You end up having to build proto…
I am responding to the very last point about dropping a future and the resource usage. Let's assume a future that implements reading from a network socket. And the file descriptor (fd) was already passed to epoll/select (I am ignoring io_uring). After dropping the future, the socket is is still being considered by the kernel for reading. Eventually epoll will return, and the IO runtime (like tokio) will notice the st…
Local async executors and why they should be the default
181–190 of 327 posts
Re: Local async executors and why they should be the default
#182Earlier quoted context omitted.
Maybe for prototypes or small scripts but disagree otherwise. The promise of automatic memory management is that you don't have to think about memory. But the second you don't think about memory you are doomed to write bad code anyway. Maybe because of performance but most probably due to architecture. To have a language that forces you to think about memory is not a curse, it is a blessing.
> But the second you don't think about memory you are doomed to write bad code anyway. Yeah but the failure modes are different. "Doomed" in C++ means now I've got worms all over my network. Pretty much a fully negative outcome. "Doomed" in Rust means I can't change it anymore until I relearn and refactor everything. If it's a pacemaker or rocket engine, that's probably ideal. But if it's not... "Doomed" in Go or Jav…
And that when the Go/Java doom scenario bites you you'll have a whole lot of technical debt to pay back.
Re: Local async executors and why they should be the default
#183Earlier quoted context omitted.
Great that D, Go, Swift, C#, Nim, Eiffel, Common Lisp, Haskell, OCaml,.... also offer ways of doing it.
You don't seem to care but you are missing the point.
Learn to use them, and then you'll get the point.
Re: Local async executors and why they should be the default
#184Earlier quoted context omitted.
> But the second you don't think about memory you are doomed to write bad code anyway. Yeah but the failure modes are different. "Doomed" in C++ means now I've got worms all over my network. Pretty much a fully negative outcome. "Doomed" in Rust means I can't change it anymore until I relearn and refactor everything. If it's a pacemaker or rocket engine, that's probably ideal. But if it's not... "Doomed" in Go or Jav…
The promise with a good architecture is that the doom part is more infrequent though. And that when the Go/Java doom scenario bites you you'll have a whole lot of technical debt to pay back.
Chose the one that provides the right set of tools for high performance code.
Re: Local async executors and why they should be the default
#185Earlier quoted context omitted.
The promise with a good architecture is that the doom part is more infrequent though. And that when the Go/Java doom scenario bites you you'll have a whole lot of technical debt to pay back.
There are more languages to chose from with automatic memory management than Go and Java. Chose the one that provides the right set of tools for high performance code.
Re: Local async executors and why they should be the default
#186Earlier quoted context omitted.
You don't seem to care but you are missing the point.
Nope, you're the one missing the point, just because a language has some kind of automatic memory management, it doesn't mean C like features for deterministic manual memory management, or any other kind of manual resource management aren't available. Learn to use them, and then you'll get the point.
Re: Local async executors and why they should be the default
#187Earlier quoted context omitted.
I'm confused what you mean here. If you have a function that "depends on" another function you call it within the other function. If it's async you .await it. Do you mean something about spawning tasks or passing callbacks around?
I have this function that I still struggle to write. async fn function_handler(_event: Request) -> Result , Error> { let aws_clients = AwsClients { s3_client: S3_CLIENT.get().await.to_owned(), glue_client: GLUE_CLIENT.get().await.to_owned(), athena_client: ATHENA_CLIENT.get().await.to_owned(), }; println!("{}", aws_clients); let config = CONFIG.get().await; let version = VERSION.get().await; let db_eid_cache = create…
let (
db_eid_cache,
table_eid_cache,
job_eid_cache,
table_summaries_cache,
job_summaries_cache,
query_summaries_cache,
) = try_join!(
create_db_eid_cache(aws_clients.clone(), config),
create_table_eid_cache(aws_clients.clone(), config),
create_job_eid_cache(aws_clients.clone(), config),
create_table_summaries_cache(aws_clients.clone(), config),
create_job_summaries_cache(aws_clients.clone(), config),
create_query_summaries_cache(aws_clients.clone(), config),
)?;
The code dealing with your clients looks suspect. Why do you have a global with a .get method that is async and returns a reference? It should probably be sync. On top of that it probably shouldn't be a global variable. Pass it in as context to the handler.I'm also suspicious of having this `AwsClients` struct and a bunch of free functions that take it by owner. Why aren't you adding an `impl` block with those as methods? And why are they taking ownership requiring the .clone`?
Re: Local async executors and why they should be the default
#188Earlier quoted context omitted.
> But the second you don't think about memory you are doomed to write bad code anyway. Yeah but the failure modes are different. "Doomed" in C++ means now I've got worms all over my network. Pretty much a fully negative outcome. "Doomed" in Rust means I can't change it anymore until I relearn and refactor everything. If it's a pacemaker or rocket engine, that's probably ideal. But if it's not... "Doomed" in Go or Jav…
The promise with a good architecture is that the doom part is more infrequent though. And that when the Go/Java doom scenario bites you you'll have a whole lot of technical debt to pay back.
If attention is paid, if the architecture is good, all else like programmer salary/skill being equal, any of those languages (and plenty of others) will work fine. (And honestly, not a huge difference in the work to achieve that, a good design will look about the same in all four.)
It's only an interesting question which to use if attention is not paid, or you don't want to invest enough to ensure attention will be paid; in which case you need to look at the causes and effects of that.
Re: Local async executors and why they should be the default
#189Earlier quoted context omitted.
Eh, in that case, you can also just write single or multithreaded Rust code, entirely ignoring async Rust. I do. And multithreaded Rust is much more pleasant experience than multithreaded C++. Which dependency is forcing async Rust on you? Alternatives are usually available.
Postgres (which is a wrapper around tokio-postgres, and as a result drags the whole tokio bloated dependency graph). I would love to have a purely sync alternative to that.
Middleware/library writers that touch on anything that could be async (db, SPI, network etc.) will now have to write two versions of their API and duplicate most code.
Re: Local async executors and why they should be the default
#190A Send bound is no great burden. The only type that you will regularly interact with that is not Send is the lock type from a Mutex or RwLock, which is good because if you hold it across a long await you can slow down your app, a bug prevention mechanism that does not exist in straight multithreading. The only point that actually illustrates a threading-caused problem is the thing about multithreading sockets, which it admits is almost imperceptible, and which you can also solve by not doing that.
Almost everything the author identifies as a parallelism problem is a 'static problem. Tokio is missing a scoped spawn like std has, and if it gained one then the much described multithreading woes would reduce to basically nothing.