1 00:00:06,590 --> 00:00:09,090 - So what most people in Go don't realize 2 00:00:09,090 --> 00:00:13,130 is that accessing a map is not inherently synchronous. 3 00:00:13,130 --> 00:00:14,630 Don't get that for free. 4 00:00:14,630 --> 00:00:15,800 You don't get anything for free 5 00:00:15,800 --> 00:00:18,040 when it comes to synchronization and orchestration. 6 00:00:18,040 --> 00:00:19,790 You're responsible for it. 7 00:00:19,790 --> 00:00:24,500 And because so many people have had data races with maps, 8 00:00:24,500 --> 00:00:28,200 the language now has build into the run time 9 00:00:28,200 --> 00:00:31,370 data race detection for map access. 10 00:00:31,370 --> 00:00:33,030 Now you might think whoa, whoa, whoa, whoa, 11 00:00:33,030 --> 00:00:36,080 that means that we've added an extra code to our map access 12 00:00:36,080 --> 00:00:38,420 in order to detect races at run time? 13 00:00:38,420 --> 00:00:40,430 Yes we have, I've told you over and over again, 14 00:00:40,430 --> 00:00:43,970 Go cares about integrity over everything. 15 00:00:43,970 --> 00:00:46,680 And there's a cost to integrity, which is performance. 16 00:00:46,680 --> 00:00:48,861 But they've really made sure that this little bit 17 00:00:48,861 --> 00:00:53,861 of race detection with map access isn't going to hurt you. 18 00:00:54,190 --> 00:00:56,350 So let's take a look at how that works. 19 00:00:56,350 --> 00:00:59,600 Now I've created a global variable game called Scores. 20 00:00:59,600 --> 00:01:01,610 You shouldn't be doing this in production code, 21 00:01:01,610 --> 00:01:03,490 I'm trying to teach you some mechanics here. 22 00:01:03,490 --> 00:01:06,290 We're using the make function to make a map 23 00:01:06,290 --> 00:01:10,930 that's set, that's usable, right, in it's zero value state. 24 00:01:10,930 --> 00:01:12,170 Now I've got a wait group, 25 00:01:12,170 --> 00:01:13,940 looks like we're gonna launch two go routines 26 00:01:13,940 --> 00:01:16,350 by looking at the add call on line 18. 27 00:01:16,350 --> 00:01:18,360 And we go ahead with a go routine, 28 00:01:18,360 --> 00:01:20,710 a separate path of execution here 29 00:01:20,710 --> 00:01:21,910 that as 30 00:01:22,980 --> 00:01:25,900 going ahead and adding that right there 31 00:01:25,900 --> 00:01:28,410 we've got scores A plus plus, so look at that. 32 00:01:28,410 --> 00:01:30,530 So we're incrementing, right? 33 00:01:30,530 --> 00:01:33,770 We're incrementing the key at 34 00:01:33,770 --> 00:01:36,249 the key A, we're incrementing it to int. 35 00:01:36,249 --> 00:01:38,217 So at the end of the day what's gonna happen is 36 00:01:38,217 --> 00:01:42,120 we're gonna be able to increment this zero, one, two, 37 00:01:42,120 --> 00:01:45,340 there we go, but at the same time, okay, 38 00:01:45,340 --> 00:01:49,430 the integer for the key of B, we're incrementing that. 39 00:01:49,430 --> 00:01:51,960 Plus, plus, one, two, three. 40 00:01:51,960 --> 00:01:54,060 We've got two separate paths of execution 41 00:01:55,000 --> 00:01:58,780 accessing the same map at the same time 42 00:01:58,780 --> 00:02:00,790 and trying to do a modification to 43 00:02:00,790 --> 00:02:04,184 even though it is it's unique key, 44 00:02:04,184 --> 00:02:07,210 because the map is a complex data structure, 45 00:02:07,210 --> 00:02:08,260 it doesn't matter. 46 00:02:08,260 --> 00:02:10,070 These are two go routines trying to 47 00:02:10,070 --> 00:02:12,430 write to the same piece of data technically 48 00:02:12,430 --> 00:02:13,680 at the same time. 49 00:02:13,680 --> 00:02:15,470 This is a concurrent write. 50 00:02:15,470 --> 00:02:17,080 This is a data race. 51 00:02:17,080 --> 00:02:20,500 Now prior to the version of Go we're running on here, 52 00:02:20,500 --> 00:02:22,580 this code would have ran in production 53 00:02:22,580 --> 00:02:24,440 and you would have had data corruption everywhere 54 00:02:24,440 --> 00:02:26,670 and we wouldn't have known it until after the fact. 55 00:02:26,670 --> 00:02:28,920 But watch what happens here now, 56 00:02:28,920 --> 00:02:30,770 when I run this code here. 57 00:02:30,770 --> 00:02:34,070 Let's make sure we're in example five. 58 00:02:34,070 --> 00:02:37,190 Okay, there we go, build, no problem. 59 00:02:37,190 --> 00:02:38,023 And 60 00:02:38,023 --> 00:02:39,520 I run five. 61 00:02:39,520 --> 00:02:44,470 Look at this, the run time detected a concurrent 62 00:02:44,470 --> 00:02:45,860 map write 63 00:02:45,860 --> 00:02:48,450 between the two go routines. 64 00:02:48,450 --> 00:02:49,980 Look at that right there. 65 00:02:49,980 --> 00:02:53,330 And we also get this back trace right here. 66 00:02:53,330 --> 00:02:54,520 Look at what it's saying. 67 00:02:54,520 --> 00:02:57,910 Line 22, let's look at what line 22 is. 68 00:02:57,910 --> 00:03:01,490 Hey, that's one of those map writes right there. 69 00:03:01,490 --> 00:03:04,480 And it's showing us right there on that line 22, 70 00:03:04,480 --> 00:03:08,830 that we've got that concurrent map write going on. 71 00:03:08,830 --> 00:03:11,100 This is some really powerful stuff 72 00:03:11,100 --> 00:03:14,870 and what this is is giving it to us at run time 73 00:03:14,870 --> 00:03:16,990 and making sure that this program shuts down 74 00:03:16,990 --> 00:03:19,660 before it really causes damage to data. 75 00:03:19,660 --> 00:03:21,590 I can not stress this enough 76 00:03:21,590 --> 00:03:24,430 that integrity is our number one priority. 77 00:03:24,430 --> 00:03:25,780 When your program loses integrity, 78 00:03:25,780 --> 00:03:27,670 that software must go down. 79 00:03:27,670 --> 00:03:29,850 You either call panic, or you call OS exit. 80 00:03:29,850 --> 00:03:33,500 And this has become such an important part of Go, 81 00:03:33,500 --> 00:03:35,940 that they've moved into the run time, 82 00:03:35,940 --> 00:03:37,970 the ability to detect 83 00:03:37,970 --> 00:03:40,330 these concurrent writes, right? 84 00:03:40,330 --> 00:03:42,770 Or get concurrent writes here, 85 00:03:42,770 --> 00:03:45,050 into the map even if we were doing read and write, 86 00:03:45,050 --> 00:03:47,500 into the map where we have a data race. 87 00:03:47,500 --> 00:03:51,500 So yay for Go about really being focused on integrity, 88 00:03:51,500 --> 00:03:53,900 and I don't care about maybe the little bit of performance, 89 00:03:53,900 --> 00:03:56,960 the few clock cycles, whatever this is gonna take 90 00:03:56,960 --> 00:03:59,190 to get it done because integrity's gotta 91 00:03:59,190 --> 00:04:00,540 be our number one priority.