Transcript from the "Channels" Lesson
>> One of the problems of GoRoutine and threading in general is how to communicate data between threads. So I have one goroutine that wanna send a message to the other goroutine that can be the main goroutine or other goroutine. It doesn't matter, how we communicate data, using like local variables, in this case known as package variables is not a good idea.
[00:00:22] Because you need to lock and lock you can do that, but it's not a good idea. So we have something known as channels. That sounds scary, sounds powerful, but it's actually pretty simple. So a channel is kind of a special type of variable. So we have a slices we have structures, we have channels, okay.
[00:00:45] The channel is a wrapper over another value. It can be a string, it can be a text, it can be a workshop, anything. And a routine can define a value for that channel, and other routine can wait for a value, so it's a listener for a value. And waiting for the value means that you are going to sleep the thread until the value is available.
[00:01:10] So it's kind of a listener and it will keep the other routine waiting until the value is set through the channel. Make sense? Channels can be buffer or not, we will see what that means, but let's see a channel, pretty simple. So how do you set up a channel?
[00:01:28] Well, it's a variable with the name m1. You say chan space and the value inside the channel, that's all. And then you construct the channel with make in the constructor. You make a new channel of a string. And how do you write in the channel, with an arrow, by the way, the arrow is, you don't need to look for the unique code character for the arrow.
[00:01:55] Okay, that's because that's a new font, modern code font sizes are using ligatures. So actually, it's the less than character and hyphen. So you use that and you are saving the message. And someone else can wait for the message using this syntax, it feels weird. So let's see this here.
[00:02:21] For example, I could instead of sleeping here, I could create a channel. Let's create a channel only for that one just to keep this simple for now. So I can create the channel. How to create the channel is a variable? Let's call it channel. It's a channel that will send a bool or a string or something like that, okay?
[00:02:45] So I'm creating a channel, it's complaining because I'm not using it yet. But let's say that we can receive the channel. So we receive the channel, it's a channel of string, okay. So now I can pass the channel and it's not going to complete it, I'm not using it.
[00:03:02] So we create the channel and it's like a pipe, okay? So I'm sending you, we are going to talk about this pipeline, okay? This is a pipeline and we're going to communicate through this pipeline. So then, from here, for example, when the four ends, you can send a message to the channel, how?
[00:03:23] You don't say channel equals and you pass a message like done. No, it's not equals. You use this operator, the arrow you are sending data through the channel, okay? On the other hand, so on the main thread. So if I leave the things like this, we know that the app ends immediately.
[00:03:48] So we need to wait for something, does it make sense? So we are going to wait for, The channel. Now what? In this case, you can see that the channel. So here the channel is at the left of the arrow. We are sending data to the panel. Now the channel is at the right of the arrow.
[00:04:12] In this case we are waiting for data from the channel, and the thread will wait there until the channel finishes. In this case, with this code, I'm not actually receiving the value, but you can see it's working now. So the main thread, it's waiting for then it's complaining probably because I'm not yeah it received the channel but I'm not using it.
[00:04:33] So I can save the value, I can print the value I can even print line the value. It feels weird to see that there but it's okay, I can also create like another response and say that the response is going to wait for that and then I'm going to put in line the response.
[00:04:57] And what's the response, the string. So you can use channels, for two goals, you can send and receive data between GoRoutines. And you can use it also for one routine to wait for another routine to do something as some kind of an event listener between GoRoutines. That make sense?
[00:05:21] So it's not difficult, I mean, it's a really powerful concept is premise index point of view. You need to try it and test it and do a lot of exercises but it's actually pretty simple and pretty powerful. I mean, I'm not sure if any of you have ever experienced coding with threadings that it's typically a problem blocking, the maphrose it's here, there, it's really complicated to send data, to know when the other thread ends.
[00:05:48] So this is starting from scratch, fresh, and it's pretty simple.
>> Do the channels work just within the same package, or can they be passed between the two packages?
>> It's just a variable. So it's a kind of variable. So if you can pass a variable, you can pass a channel.
>> And I'm not sure if there's any reason you would wanna lock it down so that it's like read only, or yeah, I guess then it wouldn't be a channel, it would just be a variable.
>> Yeah, you don't have like, yeah, if you want like security, actually, if anyone has the channel, it can read for the channel or write content to the channel.
[00:06:32] You can wrap a channel in your own type if you want and yeah, I don't think you need that. But the last thing that I have is on channels for now before creating a very project that uses this, is that you can create a buffer, a buffer channel.
[00:06:52] So in this case, the buffer channel has a second argument but you can express how many of those values you wanna send over the channel, okay. And then you can even in this case, I'm sending two messages at the same time, even if no one is listening. When he said buffer channel, it's Casa buffer.
[00:07:16] Then when any when someone gets something from there, so it's like when you have some places in the city where you can like give a book for free and when you end you can return the books and stuff like that. So you go there you can see there is a book you get one and if not, you will wait there until someone gets a book into the table.
[00:07:39] So actually, it's a buffer. So in this case, if one Go routine is putting messages there and no one is listening, they're okay, they will be buffered. And at some point, the other GoRoutine will start reading the messages, and they will start pulling them from the buffer. And if you pull one from the buffer, and there is no value, it will wait, they're sitting waiting for the value.
[00:08:04] So we've been working with channels remember and Go routines. Remember just a GoRoutine is the simple way that go has to create threads, and open threads and the channel is one way that we have to send and receive data between GoRoutines. So one of the problems of channels is and GoRoutines in general is we've seen that When we, for some reason, stop the main Goroutine, everything stops.
[00:08:37] And we can get into some deadlocks. So to avoid that, we have to close all the channels before ending the program. There is a close global function, so we can pass a channel and it will close the channel, so we are kind of good citizens with that. However, sometimes it's not easy to know when to close the channel, so when everything is finishing.
[00:09:05] So, to solve that problem, we are going to create a new project, and in that project we will start working also with HTTP. So we're gonna start first reading web services or reading data from the web. And we're going to use that example also to see another way to work with routines, or to control routines, that is called weight group.
[00:09:27] That is going to help us with that problem with a deadlock problem.