Hacker News new | ask | show | jobs
by qwertox 1475 days ago
I've fallen in love with Python's asyncio for some time now, but I know that go has coroutines integrated as a first class citizen.

This article (which I have not read but just skimmed) made me search for a simple example, and I landed at "A Tour of Go - Goroutines"[0]

That is one of the cleanest examples I've ever seen on this topic, and it shows just how well integrated they are in the language.

[0] https://go.dev/tour/concurrency/1

1 comments

Having used both in production for many years, Go’s model is waayyyy better, mostly because Python’s model results in a bunch of runtime bugs.

The least of which are type error things like forgetting to await an async function—these can be caught with a type checker (although this means you need to have a type checker running in your CI and annotations for all of your dependencies).

The most serious are the ones where someone calls a sync or CPU-heavy function (directly or transitively) and it starves the event loop causing timeouts in unrelated endpoints and eventually bringing down the entire application (load shedding can help mitigate this somewhat). Go dodges these problems by not having sync functions at all (everything is async under the covers) and parallelism means CPU-bound workloads don’t block the whole event loop.

I’m not a Go programmer, doesn’t having everything async make your code riddled with race conditions? It seems like it would make ordering very hard to reason about.
No, only mutable shared state is subject to race conditions. Mutable shared state is rare, and you can use a mutex to guarantee exclusive access to it. Note also that only the implementation is async, but the programmer interface is synchronous (in other words, the programmer doesn’t need to type “await” all over the place).