
Understanding real-world concurrency bugs in Go - mcguire
https://blog.acolyer.org/2019/05/17/understanding-real-world-concurrency-bugs-in-go/
======
ra7
Previous discussion:
[https://news.ycombinator.com/item?id=19280927](https://news.ycombinator.com/item?id=19280927)

~~~
arendtio
and
[https://news.ycombinator.com/item?id=19939718](https://news.ycombinator.com/item?id=19939718)
(just 10 comments)

------
dgllghr
I'm going to hazard the classic "this is an issue with the implementation
rather than the idea" defense. In my experience, creating a goroutine is
almost inevitably followed by setting up chans for error handling and clean
shutdown as well as for the actual message passing (I know I'm not the first
person to notice this and I wish I could find the great article I am thinking
of about it). If I'm using multiple chans for these purposes, I then have to
compose them together in the correct way, and that often turns out to be non-
trivial. I find myself wishing that Go had built in support for supervisors
and a mailbox for every process the way that Erlang does. These are things
that can be added to the language, and it is my belief that they will reduce
the bugs associated with goroutines and chans.

~~~
rwj
With all of the controversy around generics, this is one area where Go is
really hurt. The language provides the building blocks for concurrency, but
they still need to be assembled into something larger. There are examples of
good concurrency patterns, but the language doesn't provide the tools to reuse
them. Everyone is left to implement them over and over.

~~~
zxcmx
Oh jeez I’m reminded of ACE and TAO and all that stuff in C++, which in theory
was a great idea and _should_ have resulted in easy, efficient servers but
always seemed to footgun any projects I saw that used it.

Part of the problem was heavy use of inheritance _and_ templates at a time of
peak design pattern mania, part was just the nature of C++ and finally a dash
of leaky abstractions because “low level async is hard”.

I guess based on experiences with ACE/TAO in C++, Python twisted and a couple
of other frameworks that tried to “bolt on” deep server stuff:

I would take the language primitives not sucking over generics any day of the
week.

~~~
nicoburns
> I would take the language primitives not sucking over generics any day of
> the week.

It's not an either-or situation though: Rust has generics (and is a bit lower
level), which has allowed go-style channels to be implemented as a library:

[https://docs.rs/crossbeam-
channel/0.3.8/crossbeam_channel/](https://docs.rs/crossbeam-
channel/0.3.8/crossbeam_channel/)
[https://twitter.com/stjepang/status/1006202765499125760](https://twitter.com/stjepang/status/1006202765499125760)

~~~
zxcmx
Yeah I think this is fair and also, maybe go is close enough to right that you
could paper your way to something not awful without too much cognitive
overhead.

------
lalaithion
"More bugs in Go code are related to message passing than shared memory" and
"Go's message passing reduces the number of bugs in code" are not necessarily
contradictory statements. It's entirely possible that the code which can be
implemented by message passing would have been the most difficult to deal with
even if it were done with another concurrency framework, and would have had
more bugs in that case.

How does Go's message passing compare to an implementation in C/C++ using
shared memory? What about using a modern async/await framework, like in
Javascript or C#? What about using Software Transactional Memory? None of
these questions are answered.

------
cle
Awesome! I love to see data driven analysis like this. I don’t really agree
with some of the conclusions though, such as:

> Contrary to the common belief that message passing is less error-prone, more
> blocking bugs in our studied Go applications are caused by wrong message
> passing than by wrong shared memory protection.

I don’t think anyone has argued that in Go you’ll have less message passing
bugs than shared memory, especially considering that Go makes it really easy
to use these constructs, so they get used more. My understanding of the
argument is that these arguments are made _in relation to other mainstream
languages_. This conclusion is relatively meaningless to me and I’m not sure
how to interpret it.

------
icodemuch
I'm just learning Go now and I'm still in the middle of the whole "Go solves
concurrency" part. It's nice to get a second opinion

~~~
weberc2
I've been using Go since 2012 (I believe). It's a great language, but it
doesn't "solve concurrency". It makes concurrency quite a lot easier than in
most other languages, and _much_ easier than almost all mainstream languages
circa 2012, but there's still lots of room to improve.

~~~
kod
I don't know if you consider Scala mainstream, but pretty sure both Finagle
and Akka were available by 2012

~~~
andreygrehov
The ease of development in Go vs. Scala is day and night.

~~~
kod
Agree, it's a lot easier to write correct code in Scala.

