Live data from Hacker News

Why you might want async in your project

notgull.net

161–170 of 182 posts

Re: Why you might want async in your project

#161
post #156

Earlier quoted context omitted.

> basically every garbage collected runtime ends up with an awkward and kinda-broken version of RAII anyway (Closeable, defer, using/try-with-resources, context managers, etc). RAII works only for the simplest case: when your cleanup takes no parameters, when the cleanup doesn't perform async operations, etc. Rust has RAII but it's unusable in async because the drop method isn't itself async (and thus may block the w…

I agree but does RAII necessarily imply parameter-free destruction? Personally I love Rust’s `fn foo(self, …)`, which is just like a regular method but consumes the value. Deallocate by default is fine, but sometimes you need to run specific destructors (linear type style). I’ve long wished for an opt-out from implicit drop semantics for resource/handle types.

You can (kind of) emulate linear types by making `drop()` unlinkable[0]. Of course, I wouldn't recommend doing this since the error messages are awful and give no explanation at all of where the actual problem is...

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

Re: Why you might want async in your project

#162
post #156

Earlier quoted context omitted.

I agree but does RAII necessarily imply parameter-free destruction? Personally I love Rust’s `fn foo(self, …)`, which is just like a regular method but consumes the value. Deallocate by default is fine, but sometimes you need to run specific destructors (linear type style). I’ve long wished for an opt-out from implicit drop semantics for resource/handle types.

You can (kind of) emulate linear types by making `drop()` unlinkable[0]. Of course, I wouldn't recommend doing this since the error messages are awful and give no explanation at all of where the actual problem is... [0]: https://play.rust-lang.org/?version=stable&mode=debug&editio...

Haha never seen that one before! Unfortunately it’s pretty radioactive, couldn’t even box that thing.

Re: Why you might want async in your project

#163
post #127

Earlier quoted context omitted.

Java has sum types now with sealed interfaces and pattern matching. Records have detructoring out of the box, and I believe supporting it for general classes is in the works.

I think sealed interfaces it not quite the same as "tagged unions"-style enum's with payloads. Also, it does not matter much anymore, the whole std-lib is full of exceptions-to-implement-multiple-return-values.

    sealed interface Shape {}
    record Square(int x) implements Shape {}
    record Rectangle(int l, int w) implements Shape {}
    record Circle(int r) implements Shape {}
    
    double getArea(Shape s) {
        // Exhaustively checks for all alternatives.
        return switch (s) {
            case Square(var x) -> x * x;
            case Rectangle(var l, var w) -> l * w;
            case Circle(var r) -> Math.PI * r * r;
        }
    }
This is a good article: https://mccue.dev/pages/11-1-21-smuggling-checked-exceptions

Re: Why you might want async in your project

#164

> Why don’t people like async? That's pretty simple. The primary goal of every software engineer is (or at least should be) ... no, not to learn a new cool technology, but to get the shit done. There are cases where async might be beneficial, but those cases are few and far in between. In all other cases a simple thread model, or even a single thread works just fine without incurring extra mental overhead. As profess…

Show me how to cancel a network requests using only threads, with no access to the underlying socket APIs? Because that's trivial with `async`. That's not "fun", that's table stakes.

You can cancel socket operations using signals. You can eg have one or more background threads running timers which will interrupt the blocking IO if it doesn’t return in a timely manner. A lot of very important frameworks and services that are used in billions of transactions per day use this model.

Re: Why you might want async in your project

#165

Earlier quoted context omitted.

It's necessary to use some kind of poll construction if you want cancellation and timeouts without shutting down the entire application

Channel with an additional thread for sleep? Waiting for a channel is not a poll.

You either wait on the channel or wait on a read. How do you manage both?

Re: Why you might want async in your project

#166

Earlier quoted context omitted.

It's necessary to use some kind of poll construction if you want cancellation and timeouts without shutting down the entire application

True but you can still do that using traditional threads using cancellation tokens. In some ways it's worse because you have to explicitly add them, and I have yet to see any Rust APIs that actually use them (though there is a `cancellation` crate so at least some must be). In other ways it's better because it gives you control and explicit visibility over the cancellation points.

Do you have a source on these cancellation tokens for threads?

The cancellation crate hasn't been touched since 2016 and requires the running thread have a mechanism to be woken up. If you're in the middle of a read, you won't observe a wakeup unless you use an async-io function that can be timed out or interrupted.

This is no better than async/await. And await is just as obvious of the cancellation points.

That being said, there are also numerous crates for async rust cancellation tokens that can polled in parallel with a read such that you can observed the cancel instantly and switch to a cleanup process instead of immediately cancelling everything

Re: Why you might want async in your project

#167

Earlier quoted context omitted.

This is not true for Rust. Await in rust builds a larger state machine from the former. It does no implicit thread or task spawns (unless the future you're awaiting does them explicitly). Furthermore, async rust can be run single threaded

What happens if I block a future in a single threaded runtime?

Then you block the runtime? _aha you got me, threads and pre-emptive concurrency is better_.

This is where you have a reasonable trade off. I have accepted that async gives me more control over my code. For that I have to accept that blocking can slow down the app. After running async rust in production for over 2 years now I've not seen any blocking tasks block the executor. Maybe I'm just good but my experience is that my colleagues who come from C# generally don't make these mistakes either

Re: Why you might want async in your project

#168

Earlier quoted context omitted.

Show me how to cancel a network requests using only threads, with no access to the underlying socket APIs? Because that's trivial with `async`. That's not "fun", that's table stakes.

You can cancel socket operations using signals. You can eg have one or more background threads running timers which will interrupt the blocking IO if it doesn’t return in a timely manner. A lot of very important frameworks and services that are used in billions of transactions per day use this model.

Of course you can. It does mean that you need cooperation between the child and parent thread (to set up the signal handler so that resources are cleaned up) though. That's easy in a framework, kind of a pain in the ass if you're just trying to get some opaque client you were passed to do something in And that's just for IO. I mentioned elsewhere that you may want to cancel pure compute work.

You can see my point, I assume, that when your userspace program can cancel tasks natively it's much easier to work with?

Re: Why you might want async in your project

#169

For the thing I’m working on, I have an infinite number of little tasks with potentially shared smaller subtasks. How could I unleash all the processors on my computer on this workload and allow them to correctly avoid repeated calculation of results of shared subtasks? For example, I’m using an outbox: im::OrdMap > and a situation might arise where one task could avoid repeating work on a subtask because that’s alre…

Personally I wouldn't use async but instead use a pool of worker threads passing messages to an orchestrator thread using channels: https://doc.rust-lang.org/rust-by-example/std_misc/channels....

The orchestrator can then keep track of what's going on and avoid duplicating tasks and the workers don't need to worry about any global state.

Re: Why you might want async in your project

#170

Earlier quoted context omitted.

Channel with an additional thread for sleep? Waiting for a channel is not a poll.

You either wait on the channel or wait on a read. How do you manage both?

You wait on a shared channel so both read and sleep threads queue a message when ready (whichever comes first). Not sure about channels, but in other languages it would be a concurrent queue.
Post reply on HN