WEBVTT 00:00.000 --> 00:09.760 So, continuing to dive deep into go, and there are many new packages, which I told you this 00:09.760 --> 00:15.360 morning about if you missed a watch a video, and one of them was synchest, and it looked 00:15.360 --> 00:19.760 to me like a very interesting package, and then we're not just spontaneously offered to 00:19.760 --> 00:24.720 come back to force them after five years, six, only, what year did you last present in my 00:24.720 --> 00:25.720 bedroom? 00:25.720 --> 00:26.720 In my bedroom? 00:26.720 --> 00:27.720 Yes? 00:27.720 --> 00:28.720 Okay. 00:28.720 --> 00:38.160 It looks like yesterday, and she was so great with her last apartment, was it about controversial 00:38.160 --> 00:39.160 topics about go? 00:39.160 --> 00:40.160 Was it that one? 00:40.160 --> 00:41.160 Yeah. 00:41.160 --> 00:43.160 Go as object oriented. 00:43.160 --> 00:45.160 Yes, that one. 00:45.160 --> 00:49.640 And she was so great that I just invited her back, so I'm very proud of her 00:49.640 --> 00:56.640 class for Rona. 00:56.640 --> 00:57.640 Thank you. 00:57.640 --> 00:58.640 Thank you. 00:58.640 --> 00:59.640 Hi. 00:59.640 --> 01:08.040 So, as Marty said, my name is Rona, and I love introducing myself. 01:08.040 --> 01:15.040 I also give go workshops around various topics, and there's a pipeline usually to 01:15.040 --> 01:18.440 my talks, not my workshops, my talks. 01:18.440 --> 01:19.440 And it works something like this. 01:19.440 --> 01:30.920 So, I prepare for a workshop, something happens, and then I give a talk. 01:30.920 --> 01:35.720 And yeah, so what I'm trying to say by this is this is not a promotion to my upcoming workshop, 01:35.720 --> 01:41.680 which I'm giving with Jonathan Amsterdam, which I'm giving with Jonathan Amsterdam, a number 01:41.680 --> 01:42.680 of the go team. 01:42.680 --> 01:48.400 And this is a great opportunity to thank him for helping me put together this talk. 01:49.400 --> 01:54.080 And yeah, it's important to say this because that would be wrong and super confusing for 01:54.080 --> 01:55.080 everyone. 01:55.080 --> 02:03.800 But it really is just a backstory of this talk, so not a promotion. 02:03.800 --> 02:05.680 So what happened? 02:05.680 --> 02:07.320 What happened that I'm giving this talk? 02:07.320 --> 02:09.840 Well, I need to consider these two functions. 02:09.840 --> 02:11.560 So we have these two functions. 02:11.560 --> 02:17.920 One is, do you know that luck by the way, back row, if you cannot hear me, do something 02:17.920 --> 02:18.920 like this? 02:18.920 --> 02:27.600 Well, so that means that you cannot hear me because you just did the thing, interesting, 02:27.600 --> 02:28.600 very interesting. 02:28.600 --> 02:29.600 Okay. 02:29.600 --> 02:37.920 I see you, so I need you to consider these two functions, one is, and Martia, one is 02:37.920 --> 02:46.160 do know that luck, that just logs that do know that luck was in vote. 02:46.160 --> 02:54.400 And one is do that luck, which logs that it was in vote, and that locks. 02:54.400 --> 02:59.880 It that locks because we create a channel, and then we try to read from that channel in 02:59.880 --> 03:04.520 this and there are no messages in the channel, so it's just going to block forever, which 03:04.520 --> 03:05.520 is fine. 03:05.520 --> 03:11.360 Now, let's create a test that runs both of these functions into different go routines using 03:11.360 --> 03:13.240 a weight group. 03:13.240 --> 03:19.800 So since do that luck, that locks, weight group weight is going to just wait forever. 03:19.800 --> 03:22.240 So far, so good. 03:22.240 --> 03:28.320 I'm probably not telling you anything that you didn't know already. 03:28.320 --> 03:34.360 So we run this test with a timeout, and it will result in something like this, panic this 03:34.360 --> 03:40.400 time down, after 100 milliseconds, and of course, if we didn't provide a timeout, it would 03:40.400 --> 03:45.880 just thank forever until terminated. 03:45.880 --> 03:52.360 So let's fix this test by replacing the calls from to do that luck, instead we're going 03:52.360 --> 03:59.640 to call, do know that luck, it's like do no wrong, yeah. 03:59.640 --> 04:07.360 And it runs, and it passes, and everything is good in life, let's make it more interesting. 04:07.360 --> 04:19.240 Let's have do no dead luck, start a new go routine that calls do dead luck. 04:19.240 --> 04:33.720 Now I have what's called a go routine leak, but my test still passes. 04:33.720 --> 04:34.720 Delivey? 04:34.720 --> 04:40.000 Or more generally, like, for me, I don't know about your applications, but my look something 04:40.000 --> 04:46.680 like, you know, like, generate a bunch of, you know, go routines, do some stuff, everything 04:46.680 --> 04:54.240 is out of control, I never said it was good at it. 04:54.240 --> 05:01.440 They launch a bunch of more go routines, and all of my tests pass, so like, yeah, anyway, so 05:01.440 --> 05:05.040 I spoke to John, and it was like, so what is the right way to teach people, because 05:05.040 --> 05:09.480 I was going to basically teach people how to profile, like, detect this stuff, and then 05:09.480 --> 05:15.920 you said, when I watched the stintest talk, just use stintest. 05:15.920 --> 05:25.960 Now, here's a problem with stintest, I cannot pronounce stintest. 05:25.960 --> 05:35.000 So we are, we are all for our great start, but anyways, testing slash stintest package 05:35.000 --> 05:45.400 was introduced into go 125, just recently kind of sort of, and it runs test inside a bubble, 05:45.400 --> 05:48.240 and a bubble has a few features that are pretty, pretty cool. 05:48.240 --> 05:55.080 I also live in a bubble, so I know something about that. 05:55.080 --> 06:04.320 And yeah, basically, the bubble knows about the go routines that were created within it, 06:04.320 --> 06:11.040 she is very useful, because I can do something like this, this very naive thing here, that's 06:11.040 --> 06:19.440 all go routines, finish stintest, and I'm just going to create here, like, launch here 06:19.440 --> 06:28.840 two calls to go, do whatever in this case, do no deadlock, which we know deadlocks in 06:28.840 --> 06:31.920 a different go routine. 06:31.920 --> 06:42.200 And there is no weight groups or anything, and it just fails, and it fails immediately. 06:42.200 --> 06:45.800 Jonathan had a point. 06:45.800 --> 06:47.840 That is the right way to do this. 06:47.880 --> 06:55.960 So yeah, I could stop here, and basically let's just, but there is more to cover. 06:55.960 --> 06:56.960 So what do we see here? 06:56.960 --> 07:02.600 We see here that, even though I didn't use any weight group, I didn't track my go routines, 07:02.600 --> 07:11.680 and I'm just letting you let go, whatever, and something just got stuck, and didn't return 07:11.680 --> 07:23.800 the bubble knew about it, or when the test function finished, we basically had some 07:23.800 --> 07:30.520 form of tracking of what is happening, and the deadlock was detected. 07:30.520 --> 07:32.920 We didn't have to wait for a timeout. 07:32.920 --> 07:39.160 Unfortunately, by the way, that's not always going to be the case, even with stintest. 07:39.240 --> 07:45.640 And yeah, and everything, you know, failed quite quickly, so they say that time is money. 07:45.640 --> 07:51.480 I say they say that time is money, because that has not been my experience. 07:51.480 --> 07:54.440 So, the features of the bubble. 07:54.440 --> 07:56.080 So what is this dark magic? 07:56.080 --> 08:00.600 Well, the bubble waits for Goretyn's credit inside of it to finish, that's kind of, you know, 08:00.600 --> 08:01.600 obvious. 08:01.600 --> 08:06.000 Quoting from the docs, tests waits for all Goretyn's in the bubble to exit before 08:06.040 --> 08:13.480 resuming, if the Goretyn's in the bubble become deadlocked, the test fails. 08:13.480 --> 08:18.960 Now there are caveats, though, to this, and we need to learn a new term that's durability 08:18.960 --> 08:19.960 blocked. 08:19.960 --> 08:24.240 So it's not just blocked, it's durability blocked. 08:24.240 --> 08:28.840 And a Goretyn is durability blocked when it, and I'm quoting here from the blog post about 08:28.840 --> 08:40.600 stintest, when it can only be unlocked by another Goretyn in the bubble, exactly. 08:40.600 --> 08:49.000 The list of durability blocked operations are, or is a sender receive on a new channel, a sender 08:49.000 --> 08:55.680 received or receive blocked on a channel created within the same bubble. 08:55.680 --> 09:01.600 The select statement where every case is durability blocking, so yeah, that's a recursion. 09:01.600 --> 09:02.600 I'm testing you. 09:02.600 --> 09:09.400 Yes, durability blocked, test case that is durability blocked, there we go. 09:09.400 --> 09:17.960 Time sleep, sync, condition, weight, and, of course, weight group weight. 09:17.960 --> 09:20.000 So far so good. 09:20.000 --> 09:24.680 However, there are blocking operations that are not durability blocked, for instance, and 09:24.720 --> 09:28.160 a very, very important one is the I.O. 09:28.160 --> 09:34.000 So I'm going to quote Damian Neil, Neil's talk about this, now he is the one who is responsible 09:34.000 --> 09:40.120 for all of this magic, so he should know. 09:40.120 --> 09:44.840 Channels, so basically, not durability blocked are channels that are created outside the bubble 09:44.840 --> 09:45.840 that makes sense. 09:45.840 --> 09:52.240 I.O., Cisco, Sigo, and pretty much anything that is not go. 09:52.240 --> 09:58.560 And unfortunately, also mutexes, which is kind of, to be honest, plus you, mutexes, which 09:58.560 --> 10:08.840 is kind of less you, which is, this was hard felt like, I see, I also have allergies, 10:08.840 --> 10:15.920 and it's winter, so it's a bit disappointing, really, like the thing about the mutexes, 10:15.920 --> 10:21.080 there is an explanation why didn't go in, essentially like it was hard to not hurt the 10:21.080 --> 10:27.400 performance as a mutexes that are supposed to be quite fast to do this. 10:27.400 --> 10:32.120 So yeah, so unfortunately for now, mutexes are not, you'reably blocking, and that's kind 10:32.120 --> 10:34.960 of important, and I'll show you in a second what that means. 10:34.960 --> 10:42.280 So, for example, okay, let's talk about I.O. first, so for example, we have this example 10:42.280 --> 10:50.920 of a test of go, listen and serve, whatever, yes, I didn't test, I didn't check my errors, 10:50.920 --> 10:59.280 I don't know, I told you, not very good at this, anyways, so I create a guarantee in a 10:59.280 --> 11:04.240 white form for some I.O. the bubble cannot know if I.O. is coming or not, cannot really 11:04.240 --> 11:11.360 fail this test, that makes sense, you know, you're going to have to provide a timeout, 11:11.360 --> 11:14.920 essentially, to kill this test. 11:14.920 --> 11:19.920 So yeah, so in this particular case, it is not very useful, that being said, if you have 11:20.000 --> 11:27.240 a server and you have, you know, you're testing the raceful shutdown, it is amazing. 11:27.240 --> 11:31.040 So we still need a timeout. 11:31.040 --> 11:38.360 Now let's talk about mutexes, because that kind of, that is kind of painful to be honest. 11:38.360 --> 11:46.640 So I created here a function called due deadlock with mutex, guys in the back still can 11:46.640 --> 11:50.960 hear me, right? 11:50.960 --> 12:03.080 Well now they're not doing the things, I don't know, so, anyways, I did, I basically try 12:03.080 --> 12:09.160 to lock mutex twice, obviously the second time is just not, it's just going to hang forever 12:09.160 --> 12:12.880 or until terminated. 12:12.880 --> 12:21.480 So yeah, so I try to run this within a test and it's just going to hang and it needs a 12:21.480 --> 12:22.480 timeout. 12:22.480 --> 12:29.480 So far, so good or bad, if you decide. 12:29.480 --> 12:34.280 So yeah, so just always run the synthesis with a timeout, I mean technically like always 12:34.280 --> 12:41.840 run test for a timeout, just makes sense to be safe, you know. 12:41.840 --> 12:47.720 Now stick this also comes with, I said it correctly, yeah, with a weight function and the 12:47.720 --> 12:56.160 way that Damien explains it, it's kind of like running runtime goes cad in a four loop until 12:56.160 --> 12:59.800 kind of can't make any progress anymore. 12:59.800 --> 13:05.520 So it's yielding back the CPU, like, you know, over and over and over and over again 13:05.520 --> 13:10.040 until everything is kind of run. 13:10.040 --> 13:15.080 And the way that the documentation explains it is weight blocks until every go routine 13:15.080 --> 13:21.600 within the current bubble, other than the current go routine is door of the blocked, which 13:21.600 --> 13:26.360 we already covered the definition of door of the block, super easy stuff. 13:26.360 --> 13:33.760 So consider this example, we start a go routine with a worker that iterates over a channel, 13:33.760 --> 13:37.240 that channel has a buffer for one message. 13:37.240 --> 13:44.440 So right into it once is not blocking. 13:44.440 --> 13:51.360 I have a variable process, which is an integer and on every read from the channel, we place 13:51.360 --> 13:54.680 the red integer inside process. 13:54.680 --> 14:00.680 So essentially, we read from the channel, we put it in process. 14:00.680 --> 14:07.280 We write 42 to the channel and would like to see that process is set to 42 or fill the 14:07.280 --> 14:08.280 test. 14:08.280 --> 14:13.920 However, since the channel has a buffer, there is no guarantee that what we wrote to the 14:13.920 --> 14:18.000 channel has already been read, that would be an unbuffer channel. 14:18.000 --> 14:21.000 So we need to sync here, something. 14:21.600 --> 14:26.000 Well, sync test weights for the rescue. 14:26.000 --> 14:29.000 That's what it does here without it. 14:29.000 --> 14:31.000 We're going to have a race. 14:31.000 --> 14:39.720 And also, so this test is a flaky in the flaky sense that 99% of the time it will fail 14:39.720 --> 14:46.000 is sometimes succeed, not the other way around, not like most of your CI. 14:46.000 --> 14:50.000 So yeah, so if we run it, this is what it's going to look like. 14:51.000 --> 14:52.000 Okay, impressive stuff. 14:52.000 --> 14:54.000 So that's sync weight. 14:54.000 --> 14:56.000 But that's not all. 14:56.000 --> 15:01.000 Sync test comes with time travel. 15:01.000 --> 15:10.000 You can travel back into how who here has been born after a January 1, 2000. 15:10.000 --> 15:15.000 Yeah, so welcome to the year 2000. 15:15.000 --> 15:17.000 This is going to be first time for you. 15:17.000 --> 15:22.000 The rest of us, yay. 15:22.000 --> 15:24.000 Okay. 15:24.000 --> 15:29.000 So yeah, every bubble starts with a start time of January 1st, like midnight, 15:29.000 --> 15:37.000 January midnight, UTC, January 1st, 2000, white, okay, welcome to white, okay. 15:37.000 --> 15:41.000 And yeah, if you're older, obviously, welcome back. 15:42.000 --> 15:50.000 In this code, I start a sync test and I log the time and then in a loop, 15:50.000 --> 15:56.000 I sleep for a second and I log the time. 15:56.000 --> 15:58.000 Do this three times. 15:58.000 --> 16:01.000 And this is what the result would look like. 16:01.000 --> 16:02.000 So this is kind of fun. 16:02.000 --> 16:08.000 So first, you will notice that this test did not take three seconds to execute. 16:08.000 --> 16:16.000 That is because time has a fake clock inside the bubble. 16:16.000 --> 16:18.000 Yeah. 16:18.000 --> 16:22.000 And you will notice also that the time is white, okay. 16:22.000 --> 16:27.000 Now this, I really appreciate this is excellent trolling here me out. 16:27.000 --> 16:29.000 I don't know why they selected this date. 16:29.000 --> 16:34.000 But they do know that forensic anthropologists of the future are going to look at this material 16:34.000 --> 16:37.000 and say, well, they knew about time travel. 16:37.000 --> 16:41.000 I think that they could go back farther than 2000. 16:45.000 --> 16:47.000 Brilliant stuff. 16:47.000 --> 16:48.000 Brilliant. 16:48.000 --> 16:49.000 Anyways. 16:49.000 --> 16:58.000 So more about stuff that you can do with time manipulation. 16:58.000 --> 17:01.000 So here is some time sensitivity of functionality. 17:01.000 --> 17:03.000 I created a function, retry. 17:03.000 --> 17:05.000 It takes a function that returns in error. 17:05.000 --> 17:09.000 It also takes how many times you're supposed to retry this thing. 17:09.000 --> 17:15.000 And in interval, like how long you're going to wait between those retries. 17:15.000 --> 17:19.000 And yeah, and it's kind of like what you would expect for range. 17:19.000 --> 17:24.000 And if there was an error, sleep, and then you know, do it again. 17:24.000 --> 17:29.000 And times of Allah. 17:29.000 --> 17:30.000 You can read code. 17:30.000 --> 17:31.000 I know you can. 17:31.000 --> 17:32.000 I know you can. 17:32.000 --> 17:33.000 You can. 17:34.000 --> 17:35.000 Um. 17:35.000 --> 17:39.000 So yeah, finally, if whenever succeeded, we're turning error now. 17:39.000 --> 17:45.000 Our test calls retry with n equals 3 in a way time between retries of 10 seconds. 17:45.000 --> 17:50.000 Because who knows, maybe, you know, this function that we're calling here, particularly. 17:50.000 --> 17:55.000 It just returns errors new, but maybe we're just calling an external resource. 17:55.000 --> 17:58.000 And that's, you know, we don't want to bombard it. 17:58.000 --> 18:01.000 So you're not going to wait 30 seconds for this to return. 18:01.000 --> 18:05.000 But here, it's kind of fun. 18:05.000 --> 18:09.000 It's not going to take 30 seconds to run a test. 18:09.000 --> 18:10.000 No. 18:10.000 --> 18:11.000 Sorry. 18:11.000 --> 18:15.000 First and foremost, the test retry without sync test. 18:15.000 --> 18:18.000 Um, it's going to look something like this. 18:18.000 --> 18:21.000 So, uh, create a function. 18:21.000 --> 18:25.000 10 seconds, retry time sleep. 18:25.000 --> 18:27.000 30 seconds. 18:28.000 --> 18:34.000 Uh, we have some channel here that we close for signaling to know that, you know, 18:34.000 --> 18:38.000 uh, retry is actually finished. 18:38.000 --> 18:41.000 Um, and so on and so forth. 18:41.000 --> 18:44.000 And then what's in test? 18:44.000 --> 18:47.000 And it takes 30 seconds as you can see. 18:47.000 --> 18:49.000 Which is. 18:49.000 --> 18:52.000 I was sitting a while in front of the computer. 18:52.000 --> 18:55.000 I didn't just write this number there. 18:55.000 --> 18:57.000 Right, this way. 18:57.000 --> 19:02.000 Um, so with sync test, it looks like this. 19:02.000 --> 19:06.000 So, first of all, you will see, you will notice that it's shorter. 19:06.000 --> 19:11.000 Uh, we use sync test weight for the syncing to prevent the race. 19:11.000 --> 19:16.000 Uh, we just sleep 30 seconds, which is effects 30 seconds. 19:16.000 --> 19:21.000 Again, at the end of the 30 seconds, so like in the meantime, 19:21.000 --> 19:27.000 sleep, uh, for 10 seconds that happens three times was actually invoked. 19:27.000 --> 19:29.000 All of this was done for you. 19:29.000 --> 19:31.000 We just ran it. 19:31.000 --> 19:35.000 And yeah, this is how long it actually took. 19:35.000 --> 19:38.000 So, 300 milliseconds. 19:38.000 --> 19:40.000 This is quite nice. 19:40.000 --> 19:48.000 Um, so here are the stuff that I was able to test with, with all of this. 19:49.000 --> 19:52.000 Um, I was able to test race full shutdown. 19:52.000 --> 19:56.000 I was able to test, uh, a cash with, uh, TTL. 19:56.000 --> 19:59.000 So time to live with, like, entries that expire. 19:59.000 --> 20:02.000 Uh, and then I looked at that. 20:02.000 --> 20:05.000 And I was like, okay, I want to make it a little bit more complex. 20:05.000 --> 20:09.000 So I created a server, a server that, uh, handle session. 20:09.000 --> 20:11.000 And those sessions have time out. 20:11.000 --> 20:16.000 And then I created a recording, a recording that maintain the times. 20:16.000 --> 20:20.000 And that maintains the timestamps of those requests that are made to the server. 20:20.000 --> 20:23.000 So I have requests through the server and their timestamps. 20:23.000 --> 20:25.000 And then I sleep between them. 20:25.000 --> 20:30.000 And therefore, when I run this recording, I don't write out of memory. 20:30.000 --> 20:33.000 Just quite cool. 20:33.000 --> 20:38.000 Also, so they may actually set any stock that time only moves forward. 20:38.000 --> 20:44.000 Now, I, I'm going to show you in a second that he actually built a time machine, 20:44.000 --> 20:48.000 where you can have time going backwards, but not further than 2000. 20:48.000 --> 20:54.000 Um, and, uh, yeah, so something that I, I was thinking about, 20:54.000 --> 20:58.000 I was thinking about was like, is there a reason why I would use two bubbles? 20:58.000 --> 21:03.000 Like, essentially, and reset the time, uh, and have, uh, and have, 21:03.000 --> 21:09.000 and what I figured out was, I'm sure we have these services that communicate with each other. 21:09.000 --> 21:12.000 Maybe their clocks are in sync. 21:12.000 --> 21:16.000 So you can actually simulate time going backwards forwards, 21:16.000 --> 21:18.000 whatever you need to within a test. 21:18.000 --> 21:21.000 Just, you know, test your protocols etc. 21:21.000 --> 21:23.000 So that's pretty cool. 21:23.000 --> 21:27.000 Um, and, uh, yeah, and those are just, you know, 21:27.000 --> 21:30.000 uh, these, uh, fun examples that I came up with, 21:30.000 --> 21:34.000 um, you probably have your own ideas of what you can do with this. 21:34.000 --> 21:41.000 Uh, thank you very much, and now I will finish with a demo of time going backwards. 21:41.000 --> 21:46.000 Well, I would finish with a demo if I could move this here. 21:46.000 --> 21:49.000 I don't know where I'm going. 21:49.000 --> 21:54.000 Is this not, uh, where is the other screen? 21:54.000 --> 21:56.000 Do you guys see anything? 22:00.000 --> 22:02.000 No, okay. 22:07.000 --> 22:09.000 One day I'll get there. 22:10.000 --> 22:12.000 There it go. 22:14.000 --> 22:17.000 Look at time going backwards. 22:21.000 --> 22:23.000 With the time now. 22:23.000 --> 22:26.000 Thank you very, very much. You were great.