Hacker News new | past | comments | ask | show | jobs | submit login
[dupe] Understanding real-world concurrency bugs in Go (acolyer.org)
79 points by mcguire 64 days ago | hide | past | web | favorite | 16 comments

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.

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.

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.

> 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://twitter.com/stjepang/status/1006202765499125760

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.

> Everyone is left to implement them over and over.

This is a good summary the state of developing anything Golang

"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.

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.

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

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.

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

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

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

Scala was not on my radar in 2012; take that for whatever it's worth to you.

Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact