 And an old school teacher tried to renovate that and you know, screwed it up. But so it was a collaboration, but it wasn't simultaneous. So the guy painted it in 19th century and it was very nice. But you know, the school teacher screwed it up. Anyway, how many of you know what this is? No one? Our place? Reddit? Okay, so how many of you use Reddit? Okay, a few guys. So Reddit ran a very, so Reddit is a social network kind of thing where people post stuff, okay? And every April 1st, they do some cool experiment, okay? And the last April, what they did was they built a thousand pixel by thousand pixel canvas, okay? And they allowed people to just put one pixel, okay? And they, you know, if you had an account on Reddit, you would be able to put one pixel in five minutes, okay? So once you put a pixel, you cannot do that again in five minutes. So this was a very cool experiment. This is a thousand pixel by thousand pixel image and people actually built this, okay? And it changed throughout the day, but you know, that's the power of collaboration. That is, you know, if you allow multiple people to work together, even, you know, if they do it one pixel at a time, they can build really awesome things. All right, so with that aside, a quick intro to Elixir. Elixir, actually, you know, we heard a lot about Erlang and Elixir, you know, in the previous sessions. And, you know, Erlang is, it's a very battle-tested framework, right? The Erlang VM has been in production for the last 30 years, okay? And it handles almost 50% of the telecommunication traffic, okay? Because it's built by Ericsson. It does that, okay? So Elixir is something which is built on top of Erlang, okay? So if you guys have used Clojure or Scala or Kotlin, right? So those languages run on top of the JVM, right? So Elixir is something similar, but it runs on top of the Beam. The Beam is the name of the Erlang virtual machine, okay? And, you know, so because Erlang is so good, you know, Elixir gets all of that stuff for free, okay? All right, so let's have a quick demo about, you know, Elixir, okay? So can everyone see this? Is this visible? Yes? All right, so this is a very simple hello world command, you know, program. You just have IO, so Elixir has something called modules, okay? And a module is just a group of functions, okay? So what you do is you define a module, it can have a bunch of functions. And the way you call it is you say module name, dot, the function name, and give it some arguments, okay? So you can think of it like static classes in Java or C-sharp, okay? Well, you know, your class is actually the module and the function is the function, okay? So here we have some, you know, simple stuff. And if I run this, the way you run it is you just say Elixir and hello, dot, exs, and it runs, okay? So nothing fancy there, right? All right, so nothing fancy there. Let's move on to something called the pipe operator. So you guys have seen the pipe operator a lot in the previous talks. But what the pipe operator does is if you look at the first line, you may have seen this kind of code in Ruby or Java or whatever language you use, right? What you do is you say enum.max, right? You're calling a function, and that gives you some result. You give it to something else, right? But to read this, what you need to first go to is the innermost parenthesis, right? So you need to go to 3, 4, that's a list. And you need to read it in the reverse order, right? So to try and understand what you're doing is you're saying, all right, I have a list with two elements. And I'm trying to get the maximum element out of those. So that's gonna be 4. And then I'm printing it, right? So which is, you know, it's gonna print 4, right? Now what the pipe operator does is it just takes whatever you have and passes it as the first argument, okay? So if you look at this, this is a list with items 3, 4, 5. And it calls enum.max with that argument, okay? And then it takes that result and calls io.puts with that result, okay? So it's kind of like the Unix pipe, okay? If you've used Unix, sort, cat, whatever, right? You just chain things together using a pipe, right? So that's what this pipe is, okay? So you'll see a lot of this in, you know, in Alexa code, okay? So what's happening here? You've got a list, you're passing it through enum.max, and then you're passing it through io.puts, which will actually print it, okay? So if I run this code, the left pane here shows you that, you know, it's printing 4 and 5, right? The 4 comes from the first line of code, the 5 comes from the last three lines of code, okay? Any questions, guys? No, just some syntax, okay? All right, okay. So now, you know, you may think, all right, Alexa looks like a normal language, right? What's so special about it, right? So Alexa, you know, we've heard that Alexa brings concurrency to the table, right? Alexa is, you know, very good with concurrent stuff, right? So let's do something concurrent, okay? So if everyone here understands JavaScript, right? So if I have some code here, which is i, i is 0, i less than 10, i plus plus, right? And I'm gonna sleep and I'm gonna print something, okay? So let's say that's 10 seconds. How many seconds would it take to finish this program? 100 seconds, right? Simple, right? 10 seconds at a time, 100 seconds, right? So we have a similar Alexa app here, okay? So what it does is, it says I have three elements, right, in a list. I'm gonna take that, and I'm gonna map through that. And I'm gonna, for each loop, I'm gonna sleep for one second. And this is just doing a diff of the start date, right? And the current date, okay? So which basically tells us how many seconds have elapsed, okay, for each iteration, okay? So if I run this, so what do you think we'll see? Minus one, two, three, right? So that's the number of seconds which has elapsed for each iteration, right? So the first iteration took one second. The second took two seconds, the third took three seconds, right? Because it's happening one at a time, right? So how do we make this concurrent? We use something called spawn, okay? So basically, let's say you have one guy, right? And you want him to set these tables, okay? And let's say he can do two tables in a day, okay? Now you have 20 tables, so what do you do? What do you do? Get more guys, right? Get more guys. So that's what the world is moving to, right? So previously we had computers with single cores, right? Just a single processor, right? Which did stuff, right? And processors became fast, and developers were happy because their code was improving with every new release of processor. But around 2000, in the middle of 2000, right? The speeds became stagnant, right? There was no increase in speed after that. But what happened was the number of cores were increasing. Initially we had one core. Now my computer has eight cores, okay? And servers have 32 cores, right? Which means you have 32 guys who can set up the tables, okay? But if you use something like Ruby or Python, you'll only be able to give one guy the work, okay? Ruby can just say, you know, do this to one guy, okay? So it's not gonna utilize all the 31 other workers, okay? The other cores, okay? So what we are doing here is, let me increase the font here. So what we are doing here is I've got 10 guys, and I'm mapping over them, and I'm spawning, right? Spawn, what does spawn mean? Spawn means you've created something, right? So we are creating a process, okay? And you can think of these as operating system processes in that they're independent, okay? But they're not really operating system processes, okay? So which means as soon as I come to the end of this, right? I would have 10 processes doing the actual work, right? So here, just to simulate work, what we have done is we're saying sleep for one second, okay? We're just saying sleep for one second. That is just to simulate some kind of work, okay? So how much time do you think this will take? One second, right? Because what's happening here is we are spawning 10 processes, and those 10 processes are doing the work for one second, right? They're not in a line, right? They're not in a line. They're not waiting for the first guy to finish, and then start, right? They're doing it in parallel at the same time, right? That's concurrency, right? So this is gonna give us, so if I run this, it doesn't really print anything, right? So let me just put some debug statements here. Start, end, end, okay? So there's a problem here, right? Can someone spot what the problem is? It says start and end, and in the loop, when we spawn processes, we are actually printing out the difference, right? So it should have printed 10 lines, right? Minus one, minus one, minus one, sorry? Okay, that's a possibility, but in Erlang, you know, whatever process prints, it gets printed out to standard output, okay? So that's, the main process is exiting, right? I mean, before it finishes, the main process shuts down, right? Because so what this guy, what the main process is done is, so what the main process is done is, this guy says, all right, set up the 10 tables, and it says I'm done and he leaves, okay? And those other 10 guys die, okay? Because there's no main process, right? So this is a small hack where we're saying, let me give them two seconds to finish, right? So I'm sleeping in the main process for two seconds, and hopefully that should give them enough time to finish, okay? So this is, again, a hacky solution, right? This is not a good solution, but if you see, it prints minus one, minus one, minus one, right? So this all finished within one second, right? So think about it. If you have a thousand pages to crawl, right? And if you, crawling pages is actually a IO bound thing, right? Because you know, most of the time is spent downloading data. So if you have 10 cores, you can actually run it as 100 processes, okay? So you can finish 1000 in maybe 10 seconds, okay? So that's the kind of, you know, that's the kind of power Erlang gives you, okay? It gives you very simple parallelism, okay? All right, so, but you know, this is kind of a hacky solution. So what we'll do is we'll look at something else, which is built into Alexa called AsyncStream, okay? So again, you know, this is built into Alexa. This comes with Alexa. You don't have to, you know, get a different package, okay? But what this guy does is, this guy, what this guy does is it takes a collection, right? So we have 10 things, and it loops over them, creates one process for each of them, okay? But you can actually wait for them. You don't have to, you know, use a hack to wait in the main thread, okay? So what we are doing here is we're saying one to 10, send them through the timer sleeve one second, and get the date diff, and we're actually sending that result to the enum map, okay? Which is then getting printed at the end, okay? So now if I run this, how much time do you think this will take? Two seconds, okay? So this is gonna actually take two seconds, and you'll see minus one and minus two, because Task Async Stream actually allows us to control the amount of concurrency you have, okay? So here we're saying max concurrency is five, okay? Which means, Task Async Stream, what it's gonna do is, say you have a thousand URLs, and you say download only five of them at a time, and it's gonna make sure it has only five processes at a time. As soon as one process finishes, it starts another process, okay? So you can actually control that by changing this argument. So if I say 10, now we should only get minus one, right? So then we have minus one, just minus one, okay? So anyway, this is another powerful utility which comes with Elixir, okay? All right, so that was a quick tour of Elixir. Any questions you guys have? Yes, no? All right, so another quick thing to be able to understand sockets is you need to understand receives, okay? So Elixir, let's say you start an Elixir app, okay? Typically it has around 50 or more processes running at the same time, okay? And those are, you know, Elixir internal processes which do some bookkeeping, some processes, store configuration data, stuff like that, okay? Now, let's say you have five processes, okay? And you're crawling some websites, right? Now, you want to get the data from that process, okay? So the way Elixir works is, Elixir and Erlang, they work through something called message passing, okay? Which means if you have two processes, they cannot share any memory, okay? So if you've used Golang, right? Golang also has something called GoRoutines. And most languages, you know, even when you have multiple threads, they can access the same memory, okay? With Elixir and Erlang, that's not a possibility, okay? You cannot share any data between two, two different processes, okay? So all the communication happens through messages, okay? So what we have here is, what I'm doing here is, I'm spawning a process, okay? Which has just some code called receive, okay? And when you spawn a process, it gives you a PID, okay? A PID is like a process identifier, okay? And if I show you how a PID looks, so you see that is a PID, okay? PID 0.91.0, something, okay? It's a unique identifier, which allows you to address that process, okay? So let's say you want to send a message to that process. You need to send it to that PID, okay? As soon as you send it to that PID, it gets that message, okay? So it's kind of like our mailboxes, okay? So Elang actually uses the term mailbox, okay? Which means you have multiple processes. Each have something called a mailbox, okay? When you send them a message, the message goes into their mailbox, okay? And then they can, on their own, you know, on their own time, read the message and do something, okay? And maybe write you back a message, okay? So that's what this is. So what we're doing here is we're saying, we're spawning a process, we got a PID, right? And then we are sending our PID a message, which says add three, four, okay? It's just a message. It can be anything, okay? And what this guy is doing is as soon as it starts, this guy says receive a message, okay? So this guy is trying to, this guy is sitting near the mailbox, okay? And this guy is saying if there is a new message, okay? And as soon as there is a new message, opens that message, right? And it matches it on these two things, okay? It says does it match this pattern, right? Is it an add kind of message? Is it a subtract kind of message? Or, you know, if it doesn't match any of those two, it says I don't understand what this is. Okay, this is not in my language, okay? This is probably written in Latin, okay? So that's what this is. And what we are doing here is we're just sending it a message called add three, four, right? And if you run it, you'll see it says sum of three and four is seven, because we are sending it a message add. If you had sent it a message subtract, it would have said subtraction of three and four is minus one, right? If you had sent it some garbage, right? Fubar, right? It would have said unknown message fubar, right? So that's basically how processes work, right? Process is a guy who has a pin, okay? And you can send him a message and he can respond to it, okay? All right. That's all we need to understand our Phoenix stuff, all right? So any questions? Guys, any questions? Yes, no? All right. So Phoenix is a web framework, which is kind of popular in the Elixir space, okay? So it's like Rails to Ruby, right? Phoenix is to Elixir, okay? But it is very lightweight. It's not as heavy as Rails or Django and it's very productive and it's very fast, okay? So when you render stuff, you typically send responses in Phoenix in the order of microseconds, okay? So usually you send a response within microseconds, okay? That's how fast it is, okay? And it comes with a data access library called Ecto. It's like an ORM, okay? If you used Hibernate, Enhybernate, Entity Framework, right? So it's kind of that. And it doesn't do asset management, you know? So there's no Elixir tool for that. Phoenix uses an NPM tool called Brunch, okay? You can even use something like Webpack or your own, you know, asset management tool, okay? But you know, the real strength of Phoenix is it's WebSocket support, okay? So many people come to Phoenix because it has, you know, very good WebSocket support, okay? And Rails 5, the latest version of Rails, actually has been inspired by Phoenix, okay? So it has copied a lot of features into the new thing called Action Cable, okay? All right, so, demo time. So to create a new, all right, so before that, I actually forgot to show you guys this thing called Mix, okay? So Mix is a build tool which comes with Elixir, okay? You don't have to install it, it's a build tool, okay? Like Make or Rake or, you know, what do you have for Java? Maven, probably, right? So it's a build tool, okay? Which allows you to get dependencies, right? And build the final Elixir package, okay? And to create a new app, we've actually seen this kind of thing before, to build a new Phoenix Mix app, you just say Mix New, and let's say you wanna build a crawler, you just say crawler, and it will, you know, create a crawler, okay? It creates these files, okay? It's a simple scaffold, okay? Now, so this is the typical structure for a Mix app, okay? So you have the config directory, the depth directory which gets the dependencies, and the lib directory which has your code, and the Mix.exe which has the dependencies, okay? So here, we have only one dependency, which says we only want a dependency called HTTP Poison, okay? So it's a HTTP client which allows you to, you know, make a web request, HTTP requests basically, okay? So we got that, and what we have here is we have some simple code which has, there is a module called crawler, which has a function called run, and what it does is it says HTTP Poison get, and it gives it a URL, and it gets the response body and prints it, right? That's it, very simple. So if we run that, we can actually run it using this syntax. If I say mix run minus e crawler.run, it's gonna print my IP, okay? So it's actually made a request, got back the response and printed the body, okay? And if you want to actually see the response, the full response, you can say inspect the response, right? And if I run it again, you'll see that's the full response, right? So you have a response, you have some headers, you have a body and stuff, right? So it's very easy to use packages with mix, right? You just add a dependency, and you just say mix steps get, and you know, you have it running, okay? So to create a Phoenix application, once you've installed Phoenix, all you do is you say mix Phoenix new, you know, some Phoenix app, okay? So let's say this is a hello app, right? Hello app. And this sets up everything, okay? It installs the dependencies, it installs the branch stuff, and you know, at the end of this, you would have everything set up, okay? So I've actually done that in an app called hello. All right, so here is our Phoenix app, okay? Which we just created, okay? Now if you look at it, it has a similar structure to a mix app, right? You have config, lips, depths. There is an extra folder called assets, which has your CSS, JavaScript, images and stuff, okay? All right, so you guys may have used MVC frameworks in the past, right? Rails, Django, Spring, right? So Phoenix is also a typical MVC framework where it gives you some controllers, some templates. So views are actually called templates in Phoenix, and then the model stuff is actually in a different directory called the name of the app, okay? All right, so here, just to get a hello page up, all I have to do is go to the index.html page, just type out hello, right? Hello world, right? And once I have that, if I go back, so I actually didn't refresh the page, okay? So Phoenix also comes with something called auto reload. So you just strip up these tags, save it. It has auto reloaded. So if you have two monitors or something like this, you just save your code and it keeps refreshing with your latest HTML and your latest Elixir stuff, okay? So this is very neat, right? So that's a hello world Phoenix app, okay? That's a very simple thing, okay? So real quick, let's have a quick rundown of how things happen, right? So when you start a Phoenix app, the way you do it is you, so the way you do it is you say mix Phoenix server, okay? You just say mix Phoenix server, and this starts the app on port 4000, okay? And if you see, there are lots of red lines there, right? And what that says is the database hello dev isn't present, okay? But surprisingly, the app is still working, right? The app is still working, right? So that's a supervision in action, okay? So here we're not really using the database on this page, right? But let's say your database restarted, right? In stuff like Rails or Django, you will actually have to, you know, before every request make sure your connection is up and then send the request, okay? But here, you can just let it fail, okay? If your database goes down, your repository process, which is a separate process crashes, okay? And the supervisor, which is part of Erlang, brings, tries to bring it up, okay? It will restart it. And since I don't have that database, it keeps doing that. You can tweak how many times it tries to restart it, and, you know, different parameters. But, you know, it, so this, so Erlang has this philosophy called let it crash, okay? So Erlang says don't write very defensive code, okay? Things are gonna go bad, right? Your database is gonna crash, or there's gonna be a network split, right? There's gonna be a network connection error, right? Then you don't have to write, you know, lots of defensive code, right? So in the morning, in the keynote, Francesco was saying, in some app, there was 25% of code, which was just defensive coding, right? Just to make sure, all right, the database is up, right? I can ping this URL, stuff like that. In Elixir, you don't have to do that. You just let it crash, and the supervisor will restart it, okay? All right, so, all right. So now, let's look at, so what I've done is, I've actually created an application called socket D, okay? It's a Phoenix application, and if you look at the directory structure, right? It's a typical structure, right? And what I've done is, I've gone to the web directory, and page controller, actually let me get rid of this, okay? So a quick rundown of how things happen, right? So in Phoenix, when you start an app, when you start the server, whenever it gets a request, it goes to something called the router, okay? You may have used something like a router in Reels or Django, right? So here, what we are doing is we're saying, when you get a request for, when you get a get request for slash, send it to the page controller's index action, right? So this is your typical MVC stuff, okay? And here, in the page controller, all you're saying is render a template called index.html, okay? And if I go to the template page index.html, you'll see it has some html, right? It has a button and a div, right? So if I refresh this, you'll see there's a button and some black box beneath it, right? Yeah, very simple stuff, right? Just some html, all right? Now, let's go to the JavaScript part of it and that would be in the assets directory and the js file, right? So here, so by default, it loads the app.js in the layout. So what we have here is we're saying, load phoenix.html and load a file called socket.js, okay? So phoenix.html, so when I said phoenix has first class support for web sockets, phoenix has, you know, Alexa code for web sockets on the server side. It has JavaScript code on the client side. So you don't have to fiddle with web sockets, okay? Phoenix actually has a very nice abstraction which we'll see in a minute, okay? So that's what we are doing. When we say import phoenix.html, we are importing some, actually phoenix.html is a different thing, but here, all right? So what we have here is we have a file called socket.js and this again is being imported from phoenix, okay? So how many of you guys have worked with ES6 of you, right? So this is the ES6 syntax, okay? So phoenix comes with ES6 out of the box, okay? So what we are doing is we're saying import the module socket from the phoenix JavaScript stuff and now we are creating a new socket, right? So this is actually creating a web socket connection from the browser to the server, okay? At the URL slash socket, okay? And so this is actually the initialization stuff. This is where we are actually connecting to the socket, okay? So at this point, we have a web socket live between the client and the server, okay? So how many of you know what a web socket is? Almost everyone, right? So a web socket is a live TCP connection between the browser and the server, right? Where it's not like your typical HTTP where you send a request and get a response, right? The server at any time can send data to your client. The client can send any data to the server, right? So it's a full blown connection, right? So what phoenix gives you is phoenix, phoenix adds something called a channel abstraction on top of sockets, okay? So this is basically, if you look at HTTP, right? If you think about controllers and routes, right? You know that when a request comes to a particular path, right, it goes to a particular controller, right? So that's, this is a similar concept, okay? So where it says, if the web socket request comes on a specific topic, right? So topic is similar to the path. It goes to a specific channel, okay? So a channel is an abstraction, okay? So you're gonna have multiple channels on the same web socket, okay? So here what we are saying is I have a channel called, with the name Infosys, okay? And I'm just creating a channel and I'm joining to that channel. And so at the end of this, at the end of this, I'm actually trying to join to a channel, right? So all right, and the rest is a very simple JavaScript code. What we are doing is I'm getting that black box, okay? In a variable called out. I have a function called print, which is a pinch to that out, okay? And all right, we'll look at this stuff in a minute. But I have a button called ping and when the ping button is clicked, right? When the ping button is clicked, it prints ping and it pushes a message to the channel, okay? And that message has a name called Dan, okay? Right? So that's the important stuff, okay? So now if I load this, if I click on ping, you'll see it has printed ping and it has printed Pong, right? So where is that Pong coming from? Let's take a look, right? So with whatever web application you have, you always have two things, right? The client part, the server part, right? Here, we've just looked at how to send a web socket, you know, how to create a web socket connection, send it a message, right? Let's look at the Elixir side of it, okay? So the Elixir side of it lives in a lib socket dweb, something called channels, okay? And here, we're saying, if, this is like the router, okay? This is like the router, where we're saying, if you get a message, if you get a message on a topic which matches info, colon, whatever, right? Send it to this channel called info channel, okay? And the info channel is very simple. What it does is it says, it allows everyone to join, okay? So if you think about a chat room, right? Let's say Slack, right? You don't want anyone to join any room, right? Maybe you have some rooms where you say, you know, only these guys can view these rooms, okay? Maybe there's a public room, right? So if you want some kind of an authentication, authorization scheme, you would do it here, okay? You would say, when someone tries to join, you would say, is this guy authorized? If then you would say, okay, socket, okay? If not, you would just throw an error, okay? That's the join part. As soon as it is joined, you have a live connection, okay? And whenever a message comes from the client to the server, it calls a function called handle in, okay? And it tries to match on the first parameter, okay? So if we take a look at the JavaScript code, a JavaScript code is sending a message called ping, right? And on the server side, what we are doing is, whenever I get a message called ping, right? What I'm gonna do is, I'm gonna print it out on the console, and I'm gonna push it back to that socket, okay? So push is a function which allows you to send a message to the client, okay? So it's the same name, okay? So here, you're saying channel.push from JavaScript. From the Alexa side, you just say push on that socket, that message called pong, okay? And finally, what we've done is, we've said when a channel receives a message called pong, this is your typical jQuery kind of syntax, right? We say channel, when you get a message called pong, just print it, right? Print actually appends it to the black diff, right? Clear, guys? So what we've done is, as soon as you open a JavaScript browser, you set up a web socket, right? So if I actually open up the console, you'll see at the end it says join successfully, right? At this time, I actually have, so let me open the web socket request, and how many guys know how to look at web socket messages in Chrome? All right, awesome. So this is, at least you'll learn this. All right, so in Chrome, there is this thing called the network tab, which everyone knows, but if you go to the web socket URL, okay? If you click on it, now web socket messages aren't HTTP requests, right? So if you send 100 HTTP, 100 web socket messages, you won't see 100 network requests in your browser, okay? So you actually need to go to the first request, which created the connection, and go to something called frames, okay? And why is this guy not showing us anything? Well, okay, so it is. So if you look at this, all right. Okay, so anyway, so you look at this, all right. So this is not, so if you look at this, these are the messages which are being sent, okay? This is the wrong web socket connection. So if you look at this web socket connection, what happened is, as soon as the browser loaded the JavaScript, it tried to create a connection, right? Using the web socket. So it joined the Infosys channel, and as soon as the server, as soon as the client joined, the server said, okay, you look good, right? You can join, right? And that's what the server responded with, right? So if you see, the green arrow is the message going from the browser to the server. The orange arrow is the one coming from the server to the browser, okay? And what Phoenix JavaScript does is it sends heartbeat messages every few seconds, okay? So that's why you see a lot of heartbeat messages, okay? But where is our ping message? So let me clear all of this, okay? And I'll go here, click on ping pong, right? And now you see, it actually sent a message called ping to the server, and the server sent back a response called pong, okay? It did that again, and it got another pong, right? You guys with me? Yes? All right. Okay, what's the time? We are very close. Wow. Okay, so anyway, so that's, I actually had another demo, but let's move on to our, we'll look at two more demos, okay? Okay, so that was the ping demo. I actually have another page there called stats HTML, which is a similar page, okay? But if you look at the JavaScript, what I'm doing here is if the loaded page is the stats page, what I'm doing is I'm saying, whenever I get a stats message, I'm going to get the out element and add the stats.proc count to my out, okay? I actually replace it, right? So I'm just saying inner HTML equal to process, right? So I'm just replacing that, okay? And if you look at the server side, right? So the channel, if you look at the channel, I have two functions here. So all right, so here is some new stuff. What we are doing here is we're saying, whenever a new connection is made, right? Send a message to myself, okay? So self actually means myself, okay? So that process and send a message called emit stats, okay? And when I get the message emit stats, I'm going to broadcast something called stats from my server, okay? And the stats, if you look at it, it's sending out a map or an object, which is one property called proc count, which is actually the length of processes, okay? So this is actually going to show us the number of processes running in our Erlang VM, okay? So now it says 241, right? But I'm gonna put some load on this guy, and what, okay, I'm putting load on a different guy, all right? So furcur, right? 4010 is the URL, right? If you look at the process count, it's increasing, right? So what does this tell us? What does this tell us? All right, okay, so what this tells us is for every request, for every request, Elixir, the Cowboy web server creates a new process and it handles that in a different process. So every request is handled by a different process in Elixir, okay? So if you send it like a thousand requests, it will create a thousand processes, which will handle those, okay? So very quickly, all right, so with all that done, our Elixir app is actually pretty simple. So here what I have is, this is a different app, and on the homepage what I have is, I have a canvas element, okay? So canvas is an HTML element, which allows you to paint stuff, okay? And I have some JavaScript here, which is similar to the previous one, okay? And so I'm gonna start the server and if I go here to the browser, right? So that's a canvas, you can't actually see it, but there's a canvas, okay? So when I draw over it, it allows me to draw, okay? And if I draw on a different pane, right? It copies those, so let me refresh these ones, okay? So now we have blank canvases. So you can think of this as two different users, okay? And if one user draws, the other user sees it, okay? So how's that happening? So how's that happening? We have some simple JavaScript code, which, you know, this is some canvas setup, okay? So we are setting up the canvas and we are connecting a socket and whenever, and we are connecting to a special channel called canvas lines, okay? This is a channel which we created. And what we're doing is we're saying, channel on receive lines, whenever I receive lines. So the way, you know, we're doing the canvas stuff is, whenever you draw something, it's capturing all the points, okay? All the x, y coordinates. And, you know, considering that as a single line, okay? And as soon as you stop drawing, it will collect that and send it as a line to the server. The server then sends to all the connected browsers the same line, okay? And the client then just replace that, okay? So on receive lines, we're just calling them function receive lines. And what this guy does is it says payload lines, gets the lines and for each line, it just renders the line, okay? And what does the render line do? It takes the line and it moves the cursor to the first coordinate, right? And for each point, it just draws using the canvas, you know, API, it draws a line, okay? So that's what this goes. So most of this stuff is just the canvas interface, okay? And the actual Phoenix stuff is what we had earlier, okay? So we have the socket, right? We're connecting to the socket and we have a channel called Canvas Lines. And when we receive a message, we just draw the line, okay? And whenever we want to send a line, we just push the line to the channel, okay? And finally, the elixir code for this is very simple, right? So what we have here is, we have a channel called Canvas Lines. Whenever, okay, so this stuff is irrelevant. So whenever I get a message called new lines, I get a payload. The payload is actually the coordinates of all the lines, okay? And I just broadcast it from this socket to everyone. So broadcast from is a function which does not send it to the browser which sent it the message, right? So let's say you have 10 users, right? And Jack actually drew something, right? And it sends those lines. You don't want to send it back to Jack, right? Because he's the one who actually is the source. So broadcast from does not send it to the socket which it got from, okay? And it sends it to the rest of the guys, okay? So the code for this is pretty small. And if you see, we are not doing anything special here, right? We're just letting Phoenix handle all of it, okay? So we are a bit over time, but that's it guys. Thanks for listening.