Building a non-blocking multi-processes Web Server (Node JS fork example)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you build it back and such as a REST API or what the application of web service you need to account for requests that yield expensive processing expensive requests will block other requests from being served if you only have a single process or a single thread for execution this is when you might want to spin up another process to execute your request leaving the main process freely receiving requests right so you again emphasis on the mightier guys in this video we will build a multi-process non-blocking web server using an OGS by forking incoming requests into their own child processes for execution while keeping the main process free and happy and dandy to receive incoming requests we'll also like oh we always do in this channel explain the pros and cons of doing so since it might not always be a good idea to create multiple processes as it increases the complexity of your application advice if you're new here welcome my name is Christine and in this channel we discussed also social software engineering by example so if you're gonna become a better software engine consider subscribing and hit that Bell icon so you get notified every time I upload a new video that's it let's just jump into this video alright guys I'm gonna divide this video into three parts and you're gonna see now under the screen jump codes to jump to the interesting part of the video where you want to watch alright so the first part we're gonna explain a blocking process write a service that is essentially called is prime that one you're seeing right now right and how it works a blocking single process single threaded application that blocks and executes this thing and you cannot do anything else after while this is executing the second part you get a week and it turned this is prime function into a multi process back-end where it can receive a lot of requests and spin up processes to churnin into these the prime function and calculate if whether my function is prime or not and instead of blocking main process or the parent process right and the third part of the video we're going to talk about the pros and cons of doing so right obviously this increases the complexity and we're gonna talk about whether is wor fit to do so or not especially in this age where everything almost goes into micro services and containers and so simple just to spin up another application and instead of complex and complicating your application what I say let's just jump into this video all right part one here is this is a service that I built it's a REST API ish right but essentially what it does it accept a query parameter and you give it a number and it's gonna do send return Jason payload and it this jason tells you hey this is the number you told me it is prime or not and how long it took me to find out so if I say it like oh is my is hundred a prime is gonna say no it is not a prime and it took me just zero milliseconds to find out right but if you give it like a huge number such as this one I know this is a problem I stole it from online from one of the sides and if you hit that you can see what happens here is the process is processing a bit back in because with the way I wrote this function is that it is the most inefficient way you can think of of calculating a prompt right and it is obviously gonna take a long time to find out right and if I weren't here and like say ask the ask the function or ask the service hey is seven a prime guess what it's gonna get blocked it's not gonna get any result it's two of prime no it's not a prime right so you really don't know because there is one single process and it's busy executing this largest number all right so guess what we got a block is this good right it's not right so here's what we're gonna do we're gonna let's go ahead and look at how the sausage is made guys the code and here's the code guys right let's stop the process right now and just go through it real quick and what do we have here is a node replicate nodejs application using express framework and what we have here is we spinning an application we have a get request and if someone requested the as prime endpoint we will create a function and then we will get the request that query parameter we talked about required parameter in this channel what's the difference between this is the URL thing essentially get the number variable and since this is a string we have to parse it into an integer so tell the Java say hey it's a number call this magic function that's called as Prime and this magic function will return which your studio code actually nicely shows you this it returns three one JSON object code three information that one use so right number what the number is that one I processing is prime whether it's prime or not and how long it took me right to finish essentially gonna get better jason back send the jason back to the web application right so which is the one who made the request this is the listening part and this is the function you take the number you stamp the starting point and then you say hey loop from start from three and go and tell the number minus one obviously because it's listening and then if you found any number between those two that is divisible by by by the number alright then this is not a prime there exit right break that okay obviously this is the worst way to write there is a prime number but I just wanted to demonstrate how slow this thing out and you're gonna break here and if your function survives here that means you are a prime because you prime it we set that variable to true by default and if it's prime stem the end time and then essentially return this payload very cool stuff right very simple let's see how I can turn this into a multi process application guys and to do that I'm gonna copy this code here I'm gonna create a brand new project let's go ahead and do that and a new project Java Script playground let's call it is prime none below how about that guys create a new project in Dexter j/s and then let's paste the whole code it's the same exact code but it is the difference let's go ahead and just initialize NPM just for fun and in PM and youth - why that means just created like I should chase it for me and then we have a chat package suggesting we're ready to do this guys let's do this here's what I want to do every time I receive a get request on his prime I don't want to call this function I want to spin a process a child process and that child process will execute it as prime function that means one thing is prime function has a wrong location it doesn't live here it should live in its own file because other processes need to access that file so that's a plus for this architecture decoupling right you're decoupling the function which is this guy the web framework from the actual execution which is that kind of a good thing right so let's go ahead and create an is primed ojs function here or jail for file and then I'm gonna go ahead and copy the whole thing or cut the whole thing here and you can see just I have some sample prime numbers for me to test and we have the function its prime is this enough not yet because it's a function you need to invoke it somehow right we didn't invoke it here's what we want to do if I receive a get request here I want to do the phone I want to spin a new process is spinning the incorrect work because what we're actually doing is forking and forking is in the UNIX terms is essentially cloning or copying a process and that's that how essentially it's done so let's do this to do that we need to get access to the fork child process framework right the package and to do that we can do this fork equal require there is a package called child process here so you can either do this which will give you the fork class if you will or function and or you can use this structuring assignments to do this both of them will work alright we get the fork and here's what we want to do we're gonna create a child process equal fork and guess what we want to execute is prime s which is the function which is the which is essentially that file which has nothing in it it's just have a function which is not even invoked yet here is the trick does that trick isn't this guy we get back a child process we get access to the child process and here's the interesting about this communication that we're going to happen we have by default a process object you get this all the time when you spin up a new node application and process will point to the current executing process okay and by default you can listen you can do certain things with this parent process right it's an ojs process however this guy is a little bit different this guide is a child process and child process has the function called send okay and by default when you do child process dot send you can send information to that child process and from alright so it's really interesting that's so let's get into it here so if I have the child process here what I want to do is I spin up a process that's not enough I want to send it some information how do I do that child process that's send send you a message and that message is JSON object and I'm gonna send it basically guess what guys the number that you guys need to crunch I want you to crunch this proper this number what's the number this is the number let's go ahead and send it here and once we do the child process to send we got a listen on the child process or that number and pick it up right we will do that but here's what I want to do here I want to listen on so what you get back from that forking this machine you get the forked child process object and you can send that child process message and you can listen on messages on that fork process let's go ahead and just get that message right and what is this message this will be the response by the way guys this will be the response from the child okay once the child finished processing is going to send us that parent the information and to do that we will essentially get a function and guess what we will immediately responds with that message immediately and that message will be the JSON response that we saw essentially right so let's go ahead and delete that we don't need any of that anymore right so we establish half of the communication here we're sending the input to the process and we're waiting for a result from the child process to send us information let's go to the child what do we do in the child when you do the child here when you spin the child here is the what you get for free you get the process object I did not create it it's a global process object and here's an interesting thing between this process object and this process object there is this process object to this is a parent right it cannot send anything if you do not send you're gonna get an error right because it's it is known as a parent process it cannot send information to anything but this process object can actually send because it knows itself it's a child so by default loonies sent is gonna send information to the parent which which is essentially to the forked process whoever listened to that fourth process so that's the that's kind of the tricky part on if I listened to the message here I am gonna receive request that is coming from parent right so what is the request here message what did we send we send a number a member message dot number which is this object that we sent so here's what we're gonna do we're gonna do it cons JSON response equal is Prime and then we're gonna send it message number so weird look at that so if I sent them message number I am going to execute exactly the same function again I get exactly that payload and it is exact that payload is the JSON response so how do I send it back to my parent used you guess the guys process the sent and if you do that you just immediately send it exactly the same thing okay there's a tricky part guys I am going to usually what you want to do is to kill the process here but I'm gonna leave it to show you what's the difference right because if you've done you really need to kill the process and due process third exit if you don't do that right then the process will get orphaned and that will just eat your memory let's do this okay I think we have all the pieces lined up guys so let's go ahead and we cannot debug anymore you guys you know why if we debug we're gonna debug the main process we cannot step into the child process and debug because debugging essentially listens to one process right so what are we gonna do here instead as you're gonna do node index they're just so just go ahead and execute that and you can see that 80 81 is listening what's the difference now the difference is if I go here and I say give me hundred is one hundred prime no seven it is a prime now it's working how about give it a large number like that sweet is processing while is probably can I do something else will you cancer look at that you can you can execute all of these normally because each of them is spinning a new child process and what happening here is you get here I think we can debug here and show you some of the power but what you get here is you will get into this get function child spin up a child process send it to the information this is this into the input immediately what happens here the function will get this will get triggered right it will call that as prime function execute it take whatever time it takes give back and send back the forked process which is the child process that the object handler the parent has a handler off send it back the JSON response comes back here the parent gets triggered this gets triggered and then gets the message this is the response and we send it back this remained essentially waiting until we receive a response but that does not mean that the event loop function is blocked it's continuing waiting right for that response but it's asynchronously has no choice and then my stuff is working out despite this process still working or we don't care where is the problem let's go to a terminal and type table you can see that how many node J has applications we have that are orphaned right and the problem is because we did not kill those processes so you need to do process that exit in order to kill this processes after you're done all right guys so that's how we do multi processes we talked about the blocking with single processes we talked about the multiple processes and how you do it essentially and then I'm gonna give you the source code so you don't have to stop and copy that stuff from the source code will be in the description below let's talk about the pros and cons of this to me personally what I prefer is to avoid this as as much as possible because of the complexity that comes with it managing a multi processing application is difficult and I have worked with many project with they have like multi-threading and and in a complexity of debugging the thing becomes huge sometimes you get orphaned processes and you will get orphan processes with this design with this architecture so if you get our firm processes that means you have to add tracks on your parent which is this poor slob to check the list of processes is actually are they alive are still processing are they still working and you can see the complexity by just adding these health checks another thing is debugging debugging becomes a nightmare right if let's say if if one of the processes is hanging for some reason how do you know how do you add debugging how do you step into the process I mean you can argue that kind attach your debugger to that process if you know the process ID but it becomes really hard to do essentially okay so that's another disadvantage if you will right the advantage obviously yes you don't have you do not have a blocking application you do not have a blocking whip service your service or micro service can just execute normal you can always spin up or another process you can argue that hey I'm saying I'm not gonna spin up many processes I'm gonna create a pool of processes and and and you can a lot of process and a lot of clients don't do that such as non Postgres package where you can essentially work with a pool of connections to the Postgres database and the clients can consume one of the available processes right so so you can do that you can create a pool of available processes and only limit to your application to let's say say seven processes and only execute these seven process if you exceeded these processes has to wait and you can you can create a extensive application and configuration around that right apache does that I believe it has like a max number of threads that allows you to increase that or decrease that based on how many requests you get you application yes and you can configure that but to me I think it's a it comes back to like the complexity of the application the application becomes really unmaintainable right so to me I like the way the simple blocking one process right building one application that does one thing really well yes it is blocking so if someone else wants to consume that application while it is processing a certain request that has tends to be expensive then you can abhi get blocked but here's the thing that's why we have Micro Services that's why we have containers now you can spin up ten containers each one is single process blocking why they are own they are their own container isolated and put them behind a nice load balancer right and you want to use a layer seven Lord Lord balancer here which you can argue that adds more complexity but it gives you more visibility and context to that layer until you're like hey if you're executing this endpoint then we know that chances that you're gonna take a long time I'm gonna take I'm gonna point you to this micro service on this port based on a certain service discovery mechanism that will point you to that list of pool of containers and then you can the load balancer can just point you to one of these and then execute them and then the load balancer can keep track of how long each process is executing and you can all you might argue that you can actually do that with a layer four LED band so without the load balance of being blind of the actual context and avoid the ability to have to terminate TLS and re-encrypt at the back end or maybe you have you might argue that say I don't want to encrypt it on the back end leave it as pure HTTP and have my front and be encrypted but essentially you can you can have multiple load balancers and then it becomes really interesting to pick one architecture over the other it comes down boils down to what you're trying to do and whether it's worth it to do a multi processing versus essentially a single process with horizontal scalability all right guys leave your comments below what do you think you get you do you prefer the ability to have multiple processes or have horizontal scale scalability with application being a blocking single process right leave your comments beyond what do you think let's have a discussion and I'm gonna see you on the next one you guys stay awesome
Info
Channel: Hussein Nasser
Views: 22,891
Rating: 4.9805589 out of 5
Keywords: Non blocking web server, non block node js application, fork example with nodejs, node js fork example, blocking vs non-blocking web server, fork javascript example, forking process with node js
Id: hmTl5Y4ee_Y
Channel Id: undefined
Length: 22min 44sec (1364 seconds)
Published: Fri Sep 27 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.