- So what most people in Go don't realize
is that accessing a map is not inherently synchronous.
Don't get that for free.
You don't get anything for free
when it comes to synchronization and orchestration.
You're responsible for it.
And because so many people have had data races with maps,
the language now has build into the run time
data race detection for map access.
Now you might think whoa, whoa, whoa, whoa,
that means that we've added an extra code to our map access
in order to detect races at run time?
Yes we have, I've told you over and over again,
Go cares about integrity over everything.
And there's a cost to integrity, which is performance.
But they've really made sure that this little bit
of race detection with map access isn't going to hurt you.
So let's take a look at how that works.
Now I've created a global variable game called Scores.
You shouldn't be doing this in production code,
I'm trying to teach you some mechanics here.
We're using the make function to make a map
that's set, that's usable, right, in it's zero value state.
Now I've got a wait group,
looks like we're gonna launch two go routines
by looking at the add call on line 18.
And we go ahead with a go routine,
a separate path of execution here
that as
going ahead and adding that right there
we've got scores A plus plus, so look at that.
So we're incrementing, right?
We're incrementing the key at
the key A, we're incrementing it to int.
So at the end of the day what's gonna happen is
we're gonna be able to increment this zero, one, two,
there we go, but at the same time, okay,
the integer for the key of B, we're incrementing that.
Plus, plus, one, two, three.
We've got two separate paths of execution
accessing the same map at the same time
and trying to do a modification to
even though it is it's unique key,
because the map is a complex data structure,
it doesn't matter.
These are two go routines trying to
write to the same piece of data technically
at the same time.
This is a concurrent write.
This is a data race.
Now prior to the version of Go we're running on here,
this code would have ran in production
and you would have had data corruption everywhere
and we wouldn't have known it until after the fact.
But watch what happens here now,
when I run this code here.
Let's make sure we're in example five.
Okay, there we go, build, no problem.
And
I run five.
Look at this, the run time detected a concurrent
map write
between the two go routines.
Look at that right there.
And we also get this back trace right here.
Look at what it's saying.
Line 22, let's look at what line 22 is.
Hey, that's one of those map writes right there.
And it's showing us right there on that line 22,
that we've got that concurrent map write going on.
This is some really powerful stuff
and what this is is giving it to us at run time
and making sure that this program shuts down
before it really causes damage to data.
I can not stress this enough
that integrity is our number one priority.
When your program loses integrity,
that software must go down.
You either call panic, or you call OS exit.
And this has become such an important part of Go,
that they've moved into the run time,
the ability to detect
these concurrent writes, right?
Or get concurrent writes here,
into the map even if we were doing read and write,
into the map where we have a data race.
So yay for Go about really being focused on integrity,
and I don't care about maybe the little bit of performance,
the few clock cycles, whatever this is gonna take
to get it done because integrity's gotta
be our number one priority.