AsyncIO in production - War Stories
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 118 | |
Author | ||
License | CC Attribution - NonCommercial - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/44824 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
| |
Keywords |
00:00
Point cloudGoogolComa BerenicesContent delivery networkUbiquitous computingProduct (business)MetadataPhysical systemCore dumpInternet service providerInformation securityService (economics)Server (computing)Computer networkInternet der Dinge2 (number)Content delivery networkInformation securityService (economics)Internet service providerServer (computing)Software10 (number)Meeting/Interview
00:54
Core dumpPhysical systemMetadataInformation securityService (economics)Internet service providerContent delivery networkSanitary sewerComputer networkInternet der DingePoint cloudProduct (business)Ubiquitous computingServer (computing)Web 2.0Physical systemServer (computing)MetadataInternet der DingeSoftwareSoftware developerInformation securityInheritance (object-oriented programming)Product (business)Field (computer science)InternetworkingProjective planeCore dumpPoint cloudConnected space
02:45
SoftwareComputer networkError messageDomain nameProcess (computing)Presentation of a groupBranch (computer science)Product (business)CodeJSONXML
04:21
Group actionError messageComputer networkDomain nameParallel portLoop (music)Task (computing)Event horizonLoop (music)InternetworkingProcess (computing)Cartesian coordinate systemLevel (video gaming)Thread (computing)Presentation of a groupContent delivery networkWeb pageSingle-precision floating-point formatDirected graphMultiplication signoutputMedical imagingComputer animation
07:04
Event horizonModule (mathematics)CoroutineIterationContext awarenessElectric generatorPauli exclusion principleTask (computing)Plug-in (computing)Interior (topology)Thread (computing)Similarity (geometry)Independence (probability theory)LoginEmailException handlingLoop (music)Task (computing)IterationProcess (computing)BitContext awarenessException handlingType theoryMobile appCartesian coordinate systemCoroutineObject (grammar)Function (mathematics)Software testingFitness functionSynchronizationFrequencyCore dumpIndependence (probability theory)Point (geometry)Module (mathematics)Thread (computing)Software bugAdditionData managementProduct (business)ImplementationCodeoutputFunctional (mathematics)1 (number)Operator (mathematics)Projective planeEvent horizonLogic2 (number)Multiplication signState diagramSystem callSoftwareÜberlastkontrolleSound effectSoftware developerError messagePauli exclusion principleMathematicsComputer animation
17:25
Wrapper (data mining)Library (computing)Standard deviationCodeSoftware testingLoop (music)Context awarenessTape driveDependent and independent variablesClient (computing)Content (media)Streaming mediaContext awarenessEndliche ModelltheorieExpressionCodeSynchronizationLoop (music)Repository (publishing)Module (mathematics)Presentation of a groupWrapper (data mining)Cartesian coordinate systemStandard deviationResource allocationLevel (video gaming)IterationLogicConnected spaceStreaming mediaSoftware testingWeb browserMultiplication signGoodness of fitVideo gameData managementLine (geometry)LengthMultiplicationRevision controlProduct (business)Graph (mathematics)Semiconductor memoryServer (computing)Computer configurationSoftware developerMobile appImplementationThread (computing)Elasticity (physics)Event horizonState of matterINTEGRALDatabaseError messageOperator (mathematics)Library (computing)Task (computing)Inheritance (object-oriented programming)CoroutineExtension (kinesiology)WritingMathematical optimizationProcess (computing)ArmSingle-precision floating-point formatCore dumpoutputTable (information)
27:17
Scheduling (computing)Service (economics)Module (mathematics)Limit (category theory)Task (computing)Process (computing)BenchmarkSocial classCartesian coordinate systemMultiplication signInheritance (object-oriented programming)Element (mathematics)IterationQueue (abstract data type)Scheduling (computing)Service (economics)BitSemiconductor memoryPoint (geometry)Crash (computing)Set (mathematics)Block (periodic table)BefehlsprozessorView (database)DatabaseOperator (mathematics)Physical systemLine (geometry)TelecommunicationFunction (mathematics)Configuration spaceScaling (geometry)DataflowProduct (business)ÜberlastkontrolleEvent horizonLoop (music)SoftwareMessage passingDependent and independent variablesService-oriented architectureCodeBit rateMedical imagingState of matterInstance (computer science)Thread (computing)SynchronizationQuantum stateSoftware developerStability theoryElasticity (physics)
37:09
Scheduling (computing)Message passingFunction (mathematics)Interior (topology)Service (economics)Modul <Datentyp>Process (computing)Thread (computing)Stack (abstract data type)Task (computing)ImplementationServer (computing)InformationPhysical systemProjective planeTask (computing)System callInformation securityFunction (mathematics)Message passingRevision controlService (economics)1 (number)Thread (computing)MalwareSoftwareDirect numerical simulationProcess (computing)EmailModule (mathematics)Multiplication signCartesian coordinate systemTelecommunicationPoint (geometry)IterationElasticity (physics)ImplementationDisk read-and-write headComplete metric spaceSoftware bugoutputSlide ruleWhiteboardElectronic mailing listComputer architectureStructural loadQuery languageStapeldateiService-oriented architecturePattern languageSynchronizationBenchmarkArithmetic progressionOrder (biology)PlanningDatabaseResultantUtility softwareTwitterNatural numberLogicRobotDirected graphEntire functionSoftware maintenanceRight angleEndliche Modelltheorie
Transcript: English(auto-generated)
00:02
Hello everyone So it's my second year of Python as a speaker I'm very happy to be here And I guess you all came here to learn about my failures, right? Okay, so let's begin with a short introduction
00:23
So I work at Akamai. We are Content delivery network and also cloud and security services provider We move tens of terabits of traffic We have really a lot of servers and you can do really cool stuff with them
00:43
Like if you've ever watched Apple's keynote or played fortnight you definitely used Akamai's network without even knowing about that so we We tend to believe that we move between 10 to 30 percent of all web traffic
01:04
It's really difficult to calculate the right value So our systems are really distributed really Servers are the network is really vast and also recently we've launched a quite new
01:21
Product which is iot edge connect which is basically MQTT on on steroids. So we are also Very interested in the iot and Me personally Currently, I'm leading development of one of the most core Akamai metadata systems, which is responsible for
01:43
safe and secure Reliable metadata updates in our network and I'm super happy to be here Because my bachelors and masters Were about projects Which I which I did for CERN so
02:02
CERN is based in Geneva. So not that far from here and I really fell in love with Switzerland So I'm really glad I can be here And you know working on metadata upgrades for such a big network is really fascinating and
02:21
There's so many challenges and actually Something from from my field specifically so ten days ago. We saw a big outage On the internet caused by a bad metadata upgrade Do you know what was the outage about?
02:43
Yeah So that was Cloudflare, so Cloudflare is our competitor and you know But failures do happen and I Believe that it's not failures that define a company and it's how failures are dealt with and how transparent
03:06
transparent The company is about them So I believe that people at Cloudflare did a really great job dealing with that failure and Do you by chance have anyone from Cloudflare in the room?
03:22
No one Okay, even if there's no one Even if there's no one here, I think they deserve a big applause because Yeah, because failures do happen and it's how we how we embrace them so
03:40
You know, I Think It was the first or I've heard it first from Brian Cantrell during one of his presentation when he's usually very emotional and he's shouting a lot and he said that production is a war it's truly a war and
04:04
There's no There's a lot of victims and everyone's your enemy and you know failures do happen in production We are not able to test every single branch every single situation that our code might
04:22
Encounter so it's really difficult. So it's really Important in my opinion that we are open and transparent about failures so that we all can learn from them So that's why I'm really thankful for I'm really thankful Cloudflare that
04:40
They were so transparent and open about their own failure and you know, we have failures too and when you're a CDN and You have a failure. There's always these big flashy headlines Like taking the internet down
05:01
Okay, so let's move to the To an introduction about a sink. This is an advanced level presentation So I won't go into too many details But I want to lay the groundwork just to give you two definitions so that we are on the same page. So
05:21
What's a sink? If we have like a single worker doing a single task like Gopher which for some reason burns books So you have one gopher and you have a pile of books and we want to burn them then, you know, it's a serial sequential
05:43
synchronous execution so if we have many workers and we can divide our big pile of books into smaller piles then we have parallel execution and A sink is about having a single worker
06:01
Doing a lot of things at the same time. So with This beautifully edited image, yeah, you can see a single gopher Which basically does or is in the process of doing a lot of things, but he does it or
06:24
Only one thing at a time, so there's no parallel thing and I think it's really useful when we have many similar things to do but For some reason we cannot process them immediately. We need to we need to wait
06:41
for some research resources or or other things Okay, and the second thing is how I think How asynchronous execution how asyncio is implemented in Python so it uses an event loop So basically if you run an asyncio application in the main thread
07:02
You're supposed to have an event loop, which is basically a loop of tasks with tasks Which asyncio? iterates Constantly, so the tasks are being scheduled. They are being put inside that loop And later they are being checked whether the resources are available and the processing can can continue
07:26
So a bit of history So asyncio didn't invent Asynchronous execution in Python. So before asyncio we had async core modules async chat and
07:42
and similar but Someone in September of 2012 submitted the Python idea entitled async core included batteries don't fit and It was true that
08:01
Using or having asynchronous execution of code in Python was quite troublesome So later that year Guido started with PEP 3156 And then there was to leap period and in the March 2014
08:22
Async I was released in Python 3.4 as a provisional API That provisional API means that you would actually Need to be mad to start using it in production because a lot of things might change and it's just Will deploy it and we'll see how the community
08:44
reacts and also you know the like the most complex bugs can be they usually appear only in production and People start to use it. So yeah, and the API was provisional and The next release the syntax changed. So we we got async await keywords and
09:06
also some additional tools like asynchronous iteration asynchronous context managers and then with 3.6. We've got asynchronous generators and asynchronous Comprehensions and I know that we are currently at
09:21
3.7 but I guess my My knowledge stopped a bit at three three point six when I switched projects So how async IO code looks like Let's say that we have an application
09:41
Which processes some tasks and What it requires for processing of these tasks is some network IO So we can run it using async IO it fits So we have a loop We need some data to to start our task and then what we do we
10:02
just We wrap our coroutine with a task and we put it inside an event loop So this is what the ensure future is for If we are if we are smart We can actually get some data beforehand for the execution
10:20
And later we can use one of the helper functions of async IO which is async IO gather and we can basically schedule a lot of asynchronous tasks at the same time so that they will populate our event loop and they will be
10:40
Worked on asynchronously but the thing is that in async IO applications you usually should have the main thread which does the the work and with the main thread if you need to make some operations arithmetic operations any
11:02
Logic operations then you you are blocking that main thread So async IO is not magic you have one thread and you're working in it So if you have something which Runs longer than milliseconds seconds minutes, then you you should use
11:20
thread pool executors, so basically What you want to do is to create a pool of threads or processes and then you can just delegate running a specific function to to that executor and of course when you are dealing with things that
11:40
Execute a lot of time then you want to timeout at some point to Just not block all your execution if something gets stuck so nowadays you can use either the wait for helper from the async IO or you can also Use this really
12:02
Neat context manager which will timeout The inner call for you Okay, so why does it all exist what's you know, what's all that about well
12:22
Handling tasks Asynchronously, it's quite useful if you have independent tasks and of course you could use threads for that, but I know with With Gil in CPython if you have a lot of threads if you need to process a lot of tasks
12:40
Then you will start getting congestion from Gil with the amount of threads that you're using so for 3050 100 threads you will start observing them the Gil effect so with async IO you you you are not limited by Gil and
13:02
Also, like I mentioned before async IO didn't invent Running the code asynchronously in Python. So before async IO there were modules like tornado twisted Which were already asynchronous. It's just they were doing that in their own way. So also
13:23
because It started to to be popular to run asynchronous code then core developers decided that Maybe if we made some tweaks and modifications to see Python will have better performance
13:41
For async execution Okay So the first story a story of synchronous asynchronous code okay, so we had one of our first project that we use async IO was
14:03
Executor type of app which basically Received some dead tasks data and it had to process it So what we did in the beginning We implemented everything and we had this nice Like main application loop, which we would just get some
14:26
Get the task pre-process it lock it and then we would run them and the thing is that the the problem that we And encountered was much later
14:40
So we we had this up inside the run tasks method We had basically the the loop which we which you saw before So we would get data who'd run tasks and for each task we would await And it was I think after a year ago that our application was used more and more and we found out that
15:05
Actually that application runs synchronously and not asynchronously and so if we received some tasks The idea was that we are not blocked and that we can just schedule them for execution and we can just take
15:22
Another ones as as much as as we have Available slots in our, you know executor So here we are Awaiting the run tasks method and then we are awaiting every single execution. So basically we wrote a
15:41
synchronous code using async IO Yeah, so So what you want to do in? In such scenario you want to use ensure future which will just wrap your coroutine With a task object and it will ensure that your task will be will be run and it will be put into
16:05
the event loop So in the implementation of the run tasks method we also ensured that our task is is scheduled and run and
16:21
then we were super happy all tests passed and then we went to production and Well new class of errors. So our task was destroyed while pending and also sometimes we received this huge errors in our
16:42
stdout which were not logged by by any standard logger that we had An exception in one of our tasks and it was never retrieved So basically what we did we moved from a synchronous slow application to a super fast application
17:02
Which loses data and throws hundreds of hours? Yeah So one thing that we've learned is that you always need to await your futures your coroutines so even if you write your coroutine like as a
17:22
self-contained thing that basically writes its output somewhere or It's right or it writes its error state Then you also still need to like keep keep a reference to To that and also check whether the the task was actually done
17:41
Because the event loop will get rid of it if no one is interested in what's happening with it so what what we end up doing is We're always when we are We when we are scheduling our task, we always keep a reference to it and then we Just check whether it was done and there's of course some
18:04
error handling logic, but It's a simplified example. So, you know always await your awaitables Okay, another story a story of dependencies nightmare
18:21
so After you know Learning from the previous application about all possible mistakes that we could make And when you start with asyncio we wrote another application which was an API using tornado and
18:40
tornado and tornadoes ioloop was at that time wrapper for asyncio ioloop So if you used tornado and if you used Postgres you wanted to integrate Database operations so that they are asynchronous, too
19:01
So there's a really nice wrapper called mamoko which integrates with both tornado asyncio and psychopg and also, actually if you have like Application which is supposed to be really performant what you want to use is a module called uvloop
19:22
Which is wrapper for libuv, which is basically a replacement for asyncio standard implementation Which is mostly in Python. So for that For all the operations on the on the loop itself They are moved to to a C extension so that it's much faster
19:45
and also, it's quite hard to write an async test and in the early days you had to like Write a lot of setup code So there's this neat module async test which basically
20:01
Sets everything up for you and it's easier to to write tests Okay, so what did we learn? We learned that Tornado Uses ioloop which is a wrapper for asyncio loop. So first level of wrapping
20:21
Then mamoko is another wrapper And also between 2016 and 2018 I think there was not a single commit made to the mamoko repository So basically we used a module which was pretty dead When I when I was preparing for this presentation I saw
20:43
Some movement in the mamoko repository. So maybe it's been brought back to life What we've learned also is that Uvloop is really great but some modules sometimes depend on implementation details of asyncio
21:04
And for example async test does that so if you use Uvloop, you cannot use async test and Actually, the async test module at that time was developed by a single developer. It was not Super stable it had problems with resource allocation
21:24
And it was not compatible with uvloop. So if we wanted to use it we We couldn't run it with the loop that we would like to use in production The Other thing is that we started in python 3.4
21:44
So everything was done At that time using asyncio coroutine and yield from expression So we had to move We have to migrate all that syntax Into async await because async await was much better integrated with c python and actually there were some
22:06
Low level optimizations which would Which were suggested which were recommended to to use but we didn't also have this problem
22:21
Because like I said before tornado was using Asynchronous model much before asyncio So when it started there was no yield from expression There was tornado gen coroutine and yield So in some places we had yield in some places we had yield from
22:42
And it was really really a mess another story a story of a synchronous http client So Basically
23:01
Another application which we wrote using asyncio Like the the main logic was here so what it does is basically creates an http http connection Then it connects to some api and then it constantly iterates over
23:24
the data that comes in the stream so I would say that this code is Good but and ugly at the same time because it's good because it uses asyncio And it's quite quite performant. It's much much faster than
23:46
than threading It's quite ugly because with all the context managers you actually end up with half of the line length or or or even less and at that time and I don't know if
24:02
If it's already available like to have a multiple context managers async context managers just Put into A single one so that the indentation doesn't go too too far So also the code was ugly
24:20
Because there was no A eater method for asynchronous iteration so we had to use the dander version And there was also no annex method so another dander method and The code was also quite bad because
24:41
When we deployed it to production we we saw something like that, so this is a graph of memory usage of that application So you can see that for some time Everything's fine And then the memory usage starts going high
25:03
and the reason was that The server api we were using was an http one So the api the api was designed in a way that we basically open a stream
25:22
and and then in a In http request we would constantly get some Monitoring data from the from the server and this is not how you're supposed to use http so after days of of debugging we
25:40
we Like narrowed down the issue to our asynchronous http client And what we did we so so so the library Uh Doesn't have an option to limit how much it prefetches data. So it creates coroutines for
26:02
For prefetching data and if our processing, uh wasn't able to keep up with it. It would constantly fetch more data unless the memory was full so we contacted the developers of that app and they told us that Uh
26:20
You're using an http client for something that's not http so we're not going to fix it or accept your your fix So in the end, uh, we had to switch to a module which had an option to limit prefetching data And unfortunately, there was no such module available for asyncio at that time so we had to switch to
26:47
The threading implementation another story
27:00
So this is a story of an elastic search pushers async bump So Who here worked with elastic search A lot of the people yeah, so you probably know that elastic search is super fast if you configure it correctly
27:22
Uh Yeah but you know even at some point if you If you're like pushing your your your performance and your application is really is really fast You'll actually get to the limit of your cluster Of your elastic search cluster. So there's a lot of benchmarks that you can benchmark your cluster with
27:46
and when you approach When you approach those limits from benchmarks, there's basically nothing more you can do so We had an application which would get some data in a super
28:02
Fast fashion. So let's say it was an asynchronous queue Then it would process it a bit and send to elastic search So, you know great. We have the entry point is Asynchronous the out the output was asynchronous because we used an asynchronous module for
28:24
communication with elastic search but the thing was that We when we pushed it to production and we really Put a lot of traffic into it We saw this
28:41
Yeah, so again the memory usage went really high and the application Was was crashing at some point But apart from that we also noticed this So this is a cpu usage for the for the application
29:02
So we started suspecting that For some time after we start the application the flow from the from the asynchronous queue was Quite stable for some time And after that if there was some congestion on the network or anything else going
29:23
We would like get a little lower traffic for some time And then everything that was congested It was like waterfall pushing to to our data queue and message brokers are really
29:40
fast and can like survive a lot And our application also was super fast But we we reached the elastic search limit So when we started getting uh 429 In the response code from elastic search, which is too many requests. We started slowing down
30:03
And but up to that point everything was fine But then after Um, like half an hour more then we started seeing that our memory usage grows really high So we started monitoring how many tasks are we creating the task to process data and push to elastic search
30:26
And we also started monitoring how much time it takes to process a single event And we found out that Our application was indeed super fast, but at some point When it already created like 10 million of tasks
30:43
to execute and to to process the Event loop itself would become so slow uh That we would never recover from that state So I mentioned that in asyncio we have this event loop. So there's no magic we put task there and then asyncio iterates
31:06
on that loop and if you put like 10 millions or 100 Millions of elements then your iterations will become slower and slower And after some time we had so many asynchronous tasks to process
31:22
That the the system would never process them because even if the traffic was lower it Would not been able to To recover and to keep up any longer So what we had to do Is this is something which is called
31:40
async bomb So there's a really Great module called io jobs Which basically allows you to limit how many tasks are you creating and how many it actually allows you to define two two limits how many tasks you're allowed to run asynchronously in any given time
32:01
and How many tasks can wait? In your buffer so that you don't Like overflow like and that your application doesn't crash and then you use that scheduler which basically Is a set of queues And end blocks if any of the limits is reached
32:25
Yeah, so That's that and after that We have we had a story of um asynchronous service communicating with a synchronous threaded service um so
32:40
No, we are we are living in the microservices world and almost everything is microservice right now and We usually tend to believe that if we create our service it is totally independent from any other services and
33:01
It might be true If you're not doing something like that So if you have an asynchronous service Which requires for its job? communication with a threaded service Basically what you end up with is a cluster of services
33:21
Which behave like? one big threaded synchronous service Because our application Was again fast performant low latency And stuff but for every single task we had to communicate with with some With some other service, which was threaded and synchronous
33:43
And you know, there's actually a rule that if your microservice Depends on some another microservice then it's not really a microservice and unfortunately, we We've learned that the the hard way
34:01
So what we observed Was this? I'm, really pushing Ray usage of these images, right? So what what we observed was this and actually this this history happened like
34:21
really either during the previous one or really Really soon after so when we fixed the other one we saw this And we started to believe that maybe the applications are contagious Or some or or or something like that but
34:44
This was actually a more general problem like the the problem with with elasticsearch was like a specific instance of this problem so So we implemented Uh
35:01
like the the the fix which we used for the previous application, so the The asynchronous limits for for tasks And all was done and we we didn't see that but on the other hand like the limits for the
35:21
For the previous application were really high so we could process like Um 50 000 asynchronous tasks at the same time and it was fine and for this application when we set The same limits we would observe that memory would go high and then after sometimes it would drop
35:42
And also the cpu usage would sometime sometimes ramp up really high and then after some time it would either crash or Uh or or go down so that was not like the the the main fix so then like there the the other service was not maintained by us, so we contacted with
36:06
their developers and We've learned that the other service basically is Is a view for for a database So basically it has like 20 threads and if you want some data it uses a thread and
36:26
It performs some SQL operation and gives you the data back So we couldn't have like 50 000 asynchronous tasks which would basically wait for 20 threads to get some data
36:42
from So I think it's really We've learned that uh, first of all you cannot if you're running an asynchronous application Like you really need to know what other systems you depend on and also if somewhere in the line there's a system which is
37:04
Which doesn't scale very well, which is quite slow then it might not make sense to Have like a super fast asynchronous Application which would basically for most of its time Wait for the for the slow system
37:23
Okay, so up to this point I told you only bad stories and our problems with elastic search with asyncio But we also have some good ones like after learning that we
37:41
Went back to the drawing board And we had yet another service to implement so we made sure that it's a Really really small service which does one thing and it does it good so
38:02
We received the task to Reimplement a system that was causing problems What a system would do it would get some data in batches Let's say like 20 millions of entities to process For each entity it would make a dns query
38:23
and then push the results back to to some other system So we used amqp for communication for that system and And one thing was that The implementation at that time was synchronous it was using
38:46
Threads and it actually had this really nice benchmark which would calculate how many threads You you you should use to to have the the best performance The problem was that in order to process 20
39:02
million Messages it would need 12 hours, which was too much So what we did we? Implemented it in asyncio Because we had amqp At the front and at the back what we had to do was dns queries which are
39:24
Asynchronous in their nature because dns uses udp. So it's you send something and hopefully It will return to you at some point so no handshakes just super easy
39:41
And with like this was the main logic of that application So we would use Asyncio dns query and we So we went from 12 hours to 8 minutes with asyncio
40:00
And the funny story is that when we first run the application Like it run It run great for the first five minutes and then All dns servers stopped responding Yeah, so we were super afraid that
40:21
We caused another headline Like akamai dns servers went down But it turned out that in five minutes And infosec called us It's always funny to receive a call from infosec right after you deployed a new version of europe
40:42
So they told us that we have a malware on our server and the malware is trying to bring down the dns servers Yeah, and when we told them that no it's for that system is business as usual
41:01
And there's there's nothing wrong. It will perform that way so they they told us that It's fine that dns servers will be fine with that but next time maybe we'll We should give them some heads up
41:20
Yeah, so sometimes being too fast can also cause you problems Okay, and and another story as i'm slowly running out of time Is just a story about if you have if If you thought about a lot of things that you
41:44
Can encounter if you prepare your application to be an async one if you have if you use communication which is asynchronous so entry point and The output of your application then the entire architecture
42:00
and the entire way Um In which your application is written is also really really simple Nice. So for example if we nowadays if we use asyncio We really try to use message brokers amqp ones
42:21
So that we can basically get data in an asynchronous way Then we can make some processing asynchronously and then we can push data in An asynchronous way so Using like this this this pattern it makes your application
42:40
super easy and simple and even if you use No asynchronous tasks. It's quite easy to to debug it if you don't have additional threads or Or any other things Okay So what are pros and cons in my opinion?
43:02
For using asyncio. Well, you can definitely Gain some performance if you're relying on IO if your application is IO bound so network or db and there's an asterisk for db because databases are usually
43:20
Threaded applications so make sure that you have enough workers on the db side to Uh To not bring it down or to just use it to to its fullest Well, you get better resource utilization Because you spend less time on communication and synchronization compared to
43:42
to threads You if you use asyncio you are on the technological edge which gives you new ways to solve old problems which makes you more creative And it actually makes you follow python progress and contribute because There's still a lot of features missing
44:03
regarding asyncio And what are cons? Well, there's still a lot of features missing so async iterators Have messy indeterministic cleanups Eater tools for async is missing And a lot of modules which allows you to interact with popular services like zookeeper elastic search
44:27
They are still quite young and the implementation implementations are are quite early and also for some of the models for some of the systems there's a complete lack of
44:42
modules asyncio compatible modules So, you know young implementations with many bugs and actually asyncio caused our community to become more and more divided because a lot of modules maintainers
45:01
They decided that they will not import the modules to asyncio because they they don't like it So, okay last slides So what projects are best suited for asyncio in my opinion micro services like i'm putting an emphasis on micro
45:21
project the small list of dependencies so that you understand how your how introducing asyncio Will interact with other dependencies simple http apis projects with big load, but light processing so
45:40
A lot of small tasks not not heavy ones Projects where threats are not enough where you need like 50 Thousand as in asynchronous tasks and projects where the rest of your technology stack is well understood What projects are not suited for asyncio? Projects which architecture heavily relies on threats. They are difficult to migrate to asyncio
46:05
projects with dependencies heavily using threads uh projects where processing of a single tasks take a lot of time because you don't gain anything from from landing async In these projects and projects doing uncommon stuff like communicating with legacy
46:25
http services So, okay. I don't think we have time for q a so I'm here. I think for an hour or two more because My plane leaves in the evening so you can just grab me you can have a coffee and you can share some more stories
46:43
and also you can Contact me using either my email or my twitter Which I think I have like one or two tweets So it's not some bot account It's just i'm slowly getting into twitter. Okay. Thank you very much