This definitely matches my experience using Go at my previous organization. 1. Closures and concurrency really don't mix well. The loop variable capture in particular is very pernicious. There's an open issue to change this behavior in the language: https://github.com/golang/go/issues/20733 . 2. Yep. I've seen this problem in our codebase. I've grown to just be very deliberate with data that needs to be shared. Put i…
I run my Go development server with the -race flag as a default. If it affects performance I'll turn it off but that's very rare in practice. Unfortunately a lot of applications don't run tests against their HTTP endpoints (like only internal library stuff) which is bad bad bad, but the -race flag at least helps mitigate.
To anyone reading who cares:
1) Always run your tests with the -race flag!
2) Always write tests for your HTTP handling code too!
3) Run your dev server with -race for a week and see what happens.
This will hard crash your Go program and there is nothing you can do about it. You can't recover(). Go vet will not catch anything. The -race flag will!
package main
import "time"
func main() {
m := map[int]int{}
go poop(m)
go poop(m)
time.Sleep(5 * time.Second)
}
func poop(m map[int]int) {
for i := 0; i