I broke up with WSGI to be with ASGI
How scandelous, I know! But believe me, leaving the warm comfortable embrace of WSGI to be with the more attractive, I know is a better option for me in the long run ASGI was no easy feat. So why and how did this happen, you say? Let me share with you the story of WSGI and I.
WSGI and I met back in 2016. I was doing an internship back in Cairo, Egypt, before I moved to Vienna (Yes I also have no idea why I would voluntarily put myself through this drastic climate change, it baffles me too). We instantly fell in love. Oh how easy it was for me to understand how WSGI worked and as a junior developer/intern just paving his way through what can be a daunting, in the start, journey, WSGI was exactly what I needed.
Let me tell you what WSGI was like… In a single threaded situation, it would receive a request and block execution until a response is returned, but that would only serve a single request at a time, you ask? Not to worry, WSGI got you. Production grade WSGI applications can work in multithreaded and multiprocess environments, creating a thread for each new request to serve more requests at the same time or even spawning other processes. I am not going to lie, I did see some shortcomings at that point. Thread manipulation was an expensive operation and the number of processes I could have was always be limited to the number of cores I had on my server, so there really was a limit. A limit to how many concurrent requests I could serve at a time. But, I was so intoxicated in the WSGI high that I always rationalized against these antagonising thoughts by thinking, would it really be that bad if there a bit of delay when trying to access a modern day fashion blog (Don’t judge,that was the extent of the projects I was working on back then) and if I ever really needed to shave off that delay, I could always scale horizontally. As a junor developer/intern, all my needs at the time were met. Everything was perfect!
Fast forward to 2018, I was working on a project for a startup in Lisbon, Portugal (I know I know, It baffles me too) that involved scraping a lot of website pages for content (like 500k req/day a lot. no names mentioned ofc *cheeky emoji insert*). Working on developing this project was the beginning of the end of WSGI and I. All those limitations I was able to look past before, came back to bite me in the … lets say server costs and performance. I was confused and for the first time started doubting my commitment so I reverted to doing what made the most sense at the time. I went to Stackoverflow for guidance, and what I found bedazzled me. Since most of my operations were I/O Intensive and not CPU Intensive, I could really make use of multi-tasking. Or in lamens terms, switching the execution flow from one thread to another if that thread is just waiting for a response rather than blocking the execution until it returns. A whole new world of fancy daunting terms opened up, co-routines, asyncio, event loop, co-operative multi-tasking… etc etc. However, it meant different syntax and possibly saying Goodbye to WSGI.
I was not ready! I did the next best thing…
Without fully understanding the extent of how it functioned, I picked Celery with a pool option of gevent upon the recommendation of a colleague of mine because it would exactly serve the purpose of handling the switching of execution flows for me with minimal effort from my end while still holding on to WSGI for just a little longer. Now I am not saying this was the best solution out there although it was a pretty good darn one. It was a game changer for my specific use case. I was able to utilize it to achieve the performance that I was looking for, and my bosses were happy they did not have to throw more money in resources (or in hiring someone more, hmm how do I put this delicately, senior -.-). My interest was captured and I starting looking into gevent and the concept of greenlets, and this led me down the rabbit hole further, and then I started looking at co-operative multi-tasking. I was growing more and more interested, and this is when I laid my eyes on ASGI. I was still sceptical.
ASGI promised me everything WSGI gave me plus access to the promised land of asynchronuous Python.
Now I want to make it clear that I am aware that this is just scratching the surface and there are many more, possibly even more important reasons, to move to ASGI. For example, Technologies like web sockets, two way communication channel between client and server, or HTTP/2 … etc etc
So bear with me for a couple more minutes, cause I am about to give you the no cap no fuss gist of all this… (excuse my quintessential millineal vocabulary, I am on my 4th cup of coffee today)
In this scenario, assuming each Server worker handles a single thread, then only 4 requests can be processed at a time. Meaning that in this scenario since we are getting 5 requests at the same time, the thread that did not make it to the race, will have to wait till one of the Server Worker clears up.
In this scenario, a single server runs a single process which is controlled by the event loop. The event loop acts as a task manager and it creates tasks that execute the client requests, and once the task is completed, it gets destroyed. An async server may have hundreds or even thousands of active tasks that the loop switches the execution context between using a concept called co-operative multitasking.
Co-operative multitasking in very simple terms means that when a task needs to wait on perhaps an I/O event, instead of just waiting like a sync worker would do, it tells the loop that it is blocked and returns control to it. The loop would then find another task ready to start and would start it until the initial task is ready with the response and then control would be given back to it again, and so on.
Now at this point, all I know is that ASGI is a better fit for me moving forwards from here, but I do not want to rush anything. ASGI was understanding enough to agree to provide me with everything WSGI had offered me to ease my transition out of this relationship, and ASGI and I are taking the time to get to know one another.
Hope this was atleast a semi interesting read for you, atleast that was my intention. Please let me know your thoughts down in the comments and feel free to fact check me on anything I mentioned
Till next post…