What is WSGI? - #14

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay so good morning everyone welcome to another learning abandoned map session and today's presenter is tom so i'll hand over to the top okay thank you aaron so yeah so today i wanted to talk about whiskey and g unicorn so what is that sorry so the structure of this talk will be in three parts so i'll start off by saying what was years and then we'll look at two implementations uh we'll look at unicorn which is a whiskey server and uh django which is a whiskey apple we'll see what makes those whiskey implementations specifically uh so in order to kind of explain what whiskey is um i think uh the simplest way is actually to show you a simple python web application um so let's have a look here okay so this is a web application written in python and it uses uh native packages so it's using this http package which comes with python so they'll know a third things here at all and uh we'll start off by looking at these three lines at the bottom uh so what this is doing is it's creating an http server using this server address here uh so it's one two seven o one at port eight thousand and it's attaching to the server uh http request handler to find update and uh once we create that server we then serve forever uh if you look if we look closer at the request handler this is inheriting uh from the simple http request handler which comes from python and that request handler has a method called do get and do get uh basically is this is called uh whenever a get request arrives at the server that's what i'm doing is i'm overriding that method um and i'm sending a 200 response um i'm then saying to the server okay um i'm not going to put any more headers so even though i haven't actually added any headers i need to include this line to say i'm done adding headers and finally i um include the response body which is in this case either so let's see this in action so i'm going to run on python server.org name file and if i just open that browser um yeah so if i so if i go to this address i get the response either and you can see it's locked okay as a as a request i can do the same and so on okay so that's a very very simple uh web server um [Music] now um let me go back to my slides uh so this is the same thing that you just saw this is the bottom three lines and if you can look at this code you'll see there's actually this code is actually doing two things really um and you can fit the code in two parts so you can say there's a kind of application part which is this this part here which kind of tells you what's to do with requests the rest of the codes on the other hand it actually serves the application and then and we have this kind of imaginary interface between these two um parts so this is a classic case of uh something called a separation of concerns in computing uh we have this app which is basically which is really do two things at once and um when we when we see this kind of you know separation of concerns it's quite often a good idea to split those out into two separate programs um and whiskey actually gives us a standard way of doing that so whiskey stands for the web server gateway interface and it's a standard interface between servers and python web applications uh the interface is defined in pep 3333 and what what what is what this all basically means is that servers and web applications are guaranteed to work together as long as we follow the specification here so one person could write the server in isolation another person can write an app application in isolation um and they will work together as long as you follow certain set of rules um so in order to kind of so yeah i'm saying i'm talking about this specification here so what is that specification so i'll show you by i'll demonstrate um by building a whizzy web application this time and so what i'm going to do is i'm going to take this code here and i'm going to rewrite it as a whiskey web application so i'm going so it's going to be it should be much smaller than this so i'm only going to be handling on this part just the bit that handles requests so i'm going to create so i'm going to stop this server down here i'm going to create a new file i'm going to call it whiskey and so the whiskey web application is a function i'm going to call it my web app and it takes in two environment variables i'm sorry two um arguments so the first argument environment the first argument is basically the request it's the python dictionary which contains all the information about the incoming requests so it's very similar you know if it works with django it's very similar to you know the request objects which you haven't in views yeah it contains everything by the request and start response is a function itself which takes in two arguments the first argument is the status code of the response and the second argument is a list of headers we're just going to keep that empty for now and the response body is actually what the app returns and the app returns um according to specification it should return a list of byte streams uh we're just gonna have one um one element in that list and that element is going to be the response body and there we have it that's actually the entire that's the simplest um whiskey web application um which copies the behavior from this python applications this is just going to take in any any get requests uh actually any any any request at all in this case and it's going to just reply over the 200 no headers and odd body will be high there okay so um yes that's just what gone through so how do you actually run this now uh well we need a whiskey server i'm going to use a third-party implementation uh called g-unicorn and so i'll just demonstrate this so we have this uh wiz gap so in order to run it using the whiskey server or using unicorn i'm going to write in my terminal and type in unicorn i'm going to specify the address under which the server is i'm going to set the log 11 to debug so you can see everything and finally it needs to point g unicorn to this whiskey app and the way this is done is we take the name of the module in this case it's whiskey serve we do a colon and we type in the name of the app which is in our case my web app hopefully that works yep it's booted and so now if i go into my browser by the way this sick winch thing here um that that's a signal that happens when i when i resize my windows and just ignore that completely um okay uh so that i hope that kind of shows you so what we've done just kind of recap because we've taken this original um web application written completely in python and we've actually just taken out the application bits we've written that as a whiskey app have you we've used a whiskey server to run that completely and to have the whole server running um okay so let's talk a bit more about what g unicorn uh how it works so g unicorn is something known as a pre-fork workum it uses the prefork worker model so a worker that means a separate instance of the web application and preform means that the workers are created prior to any requests being received so in our case the workers are created as soon as i boot to uniform this is as opposed to workers starting up as a request comes in now the workers are managed by a master process which does not interfere with the web application in any way so the is um sorry the master process uh all it does is it just kind of makes sure that there are workers running and if a worker were to um crash and the master will try and create a new worker basically that's what the master person starts it doesn't know anything about the application and um and gene and finally g unicorn has different worker types so the default one is called sync which stands for synchronous but there are other worker types available too so if i go back to the console you can see when i boot it it's saying it's using worker sync and it's also using one workout so this raises with a question i guess because um if we're having if we have one worker and it's a synchronous worker does that mean that our server can only handle one request at a time because if so then that's uh that's not ideal of course um so just to test that what i'm going to do is i'm going to kind of add a sleep into my app and this this sleep is kind of resembles a blocking pool so you know in real world this might be like a cool you know a cool somewhere to the internet where it might be a db operation or something something basically uh which causes the web server to wait for another process to finish that's that's kind of the real definition of the blocking um so this deep this kind of models that so we can use that for our experiments import time and uh also just going to add some print statements so you know what's going on okay let me restart unicorn okay just one worker it's a sync worker and so in my browser i have two tabs so if i just refresh the page once you'll see it says waiting and then after three seconds it's done now if i try and click two tabs if i try and make a request quickly in succession as you can see it's the requests are handled synchronously so the first request has to be finished before the second request can start to be processed so this is a bit of a worry um if if one request takes a long time that means that every other client office server has to wait for the for that first clients to finish so how can we improve this um so there are a few ways so one thing we can do is we can increase the number of workers to two so let's try restart that unicorn and we're going to add this flag so workers 2. and it says it's booted with two workers if i do this tests now then it's happening in parallel as you can see both requests are started um at the same time then condition at the same time so that's good but the disadvantage of that is that if you remember one worker is one app instance so if we have big apps um then that could take up a lot of resources so this is a kind of last resort almost um another way we can uh increase the number of concurrent requests we can increase the number of threads we can keep uh one work only but we can increase the number of threads to two so let's do that i'm going to set the workers to 1 but threads to 2 and now if i do my experiments you see the same thing so yeah the requests are happening the responses are happening in parallel and handled the requests are handled in parallel as well so that's good but the disadvantage of that is that the codes must be thread safe so as a kind of another restriction almost to our code there is yet another way though uh we can have one worker we can have one thread but we can change our worker type so unicorn comes with many worker types um and and most of these are called async types uh eventually is one example of an acing worker type so if i just come demonstrate that first so i'll keep the workers at one and threads up one before i change the work of class to eventually you can see here it's saying using worker events and if i refresh these then again either these are happening in parallel so what actually is an event load so basically event that means that your workplace is using green threads and these are pseudo threads essentially that's what the green bit means they're pseudo threads and they're very cheap to create and they're also thread safe because they're actually they're not actual real threats they're co-routines um but the big disadvantage with using i think like things like a bentley and really other async workers is that you have to write your code in a certain way um in our case we didn't have to change anything because our code is so simple i mean it's just yeah just like the simplest whiskey app imaginable really but just to give an example um eventually is um no it's a fairly popular um async worker type the most popular one right now is actually something called the g event well it's probably like the most used the most maintained one g event uh but if i wanted to demonstrate to g event then i would have to import g events version of time um and i'd have to do that for you know loads of similar python functions so that govikan gives you an idea um what you have to come to sacrifice if you want to use async workers so these kind of green threads they're they're very good but they're they kind of you only really use them if you really if you're really sure you need them basically um so yeah so that kind of sums that section up and of course you have to keep in mind that increasing workers or threads only makes a real difference if there are available resources so if the code contains blocking calls if one request takes up 90 percent of what should i say if each request takes up 90 of cpu for example then adding workers or threats will not make much of a difference unfortunately but the kind of overall point of this is not so much to show you like request concurrency and show you what that is um but really just to just come demonstrate that no the fact that we can even begin applying such features five minutes after starting to build our web app is impressive and the testaments to whiskey because what whiskey but the key thing that whiskey does it allows us to split a full server in half so that we have become the actual server bit separate and the web app bit separates and so we can create our web app in isolation and we can pick and choose whatever server we want to serve that web app in this case we choose unicorn and um as you can see it's a disappearable works quite well whereas if you wanted to do the whole if we wanted to um update the um our original app then we would need to write our you know thread code in our work currently ourselves yeah and so just to kind of round off uh we in the in this presentation i built kind of my own whiskey app uh but in fact um all the popular django web frameworks they use whiskey's like django flask bottle um they're whizzy web frameworks and you can see that in django um if you've worked on the django project recently and you go into the kind of the core folder uh you'll see this file called whiskey.py and this file contains the whiskey application here and so if you want to run the django app using unicorn this is the command you would use it with unicorn whiskey the name of the module and then application then with the application and that is in case that is in case how we deploy a lot of our django um applications so yeah i think that's from the end of the presentation so don't have any questions i've got one time thanks for the talk um just thinking back to your code um i think that you're so in a whiskey surf your your web app uh your xamarin intense two that function definition you've got two parameters environment and start response yep and you're using start response in line a where um where would we be able to see the definition of start response um is that somewhere defined in the unicorn application uh yes that's right so um the these arguments are provided by the server um yeah so they come from the server and the way this actually works is when i started unicorn right at the end of course i specify the what the module and the name of this function here and so in the unicorn source codes there's a what it what juniper basically does is it imports this just like you know it kind of does imp from whiskey serve imports my web app and so it's just a function available for unicorn and then unicorn can pass in whatever it wants and so the definition of start response yeah that is in juniper yeah and so crucially it is written in python because it's possible yes it is yeah okay thanks tom i got a question as well um actually what is included in that kind of first argument of my web app environment hmm well well uh well i mean i could show well basically um it's it's it's a python dictionary and well in fact you got a few minutes so i'll just print it and i think that's probably the simplest way so yes if i just so sorry there we go um so if i do a request here so yeah there's a whole lot of stuff um request method gets query string user agent connection cookie i mean these come from the request headers uh the the name of the server the name of server ports also hosts http host so um yeah pretty much um what what and what we know what the unicorn does is it will take the incoming http request and it'll generate a dictionary basically out of that request and they will add in maybe other values as well um so yeah so that's why i say it's very similar to like the django request request object um yeah hopefully that answers your question um yeah definitely i could see actually i think i saw query string as a key there so kind of it's passing the url it's easy i mean yeah it's uh yeah there it is yeah yeah it's um i mean yeah i mean we can even i mean it might do and i mean that's so that's updated the path yeah path info abc for example for example so yeah the environment contains everything you need to actually figure out what the url is so you know which you know which view to call in django for example um yeah nice so tom one more question for me can unicorn be used to serve a web application written in another language can unicorn be used yeah so if if instead of your my web app function uh application written on screen that yeah if that was written in say no you know some ks yeah would you recommend to handle that do you know uh i've i don't know for sure but i highly doubt it uh because i know for example that this environment is variable it needs to be a python dictionary it can't be anything else so that definitely implies that no uh yeah he needs a python you need this written python um whiskey is pretty much the python you know it's a pep it's a python thing so it only really works between two python programs okay thanks i think no more questions uh thank you again tom for the presentation yeah thanks
Info
Channel: Lambert Labs
Views: 215
Rating: undefined out of 5
Keywords:
Id: _rLEzgNiuJk
Channel Id: undefined
Length: 26min 16sec (1576 seconds)
Published: Wed Sep 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.