KotlinConf 2018 - Kotlin Coroutines in Practice by Roman Elizarov

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Applause] [Music] my name is Roman I work on curtains in cotton libraries team and so here's a question for you first so who watched my introduction to curtains talk from the previous cotton conf please raise your hand oh great that's almost how are you and who didn't I really recommend to watch it it's on YouTube you can do it and here we'll talk about slightly different things so first we'll do a recap of what basics about curtain if you watched all the my previous talk you saw you saw the message there the message was curtains are like lightweight threads and this message we send we always were almost always when teach Kirkenes because threat most people family always threads curtains for most of your something new and this gives you simple mental model to work with so when we say they're like lightweight threats what do we mean we gave you an example like that so we show that creating a curtain is just like a threat so in closing you can do threat and curly braces or new curtains you can launch encouraging and just like you start our thread and when we say they're lightweight we mean that we can head have hundred thousands of them without problems while one hundred thousand threads is something we cannot do so however that's quantitative difference you know yeah we can do more of them and curtains actually give us an example of a things where when we a big change in quantity actually makes a qualitative change in this thing so actually it's not just their lightweight threads and as I show in this talk it actually lets you think and structure code in completely different way not just like you did it with threads before so to do that and this is the talk of culinary practice will take some practical challenge that we'll work on throughout this talk and assume you have a function to download some content we know location and it gets a content and that's something you can relate to in any project like whatever you do you usually work with some house as system services and you retrieve something from there so we place in your mind is downloading content with anything else you might have in your application it does not matter and its marked with suspend modifier I hope you know that means it's a synchronous it doesn't block any volker just wait for the response without blocking and our challenge is this we have lots of references to those resources and we need to write a process that takes those references you know loops for all of them then resolves them to the locations and then goes in downloads the contest contents of at that location to process them later that's the thing we want to do it looks ok and again you might already know that if you write a code like that you'll get an error you know and the ID will actually invite you to add suspend modifier to your process references function me if this function is also one running it will wait until all the contents are downloaded but the trick with this code is that it's actually sequential so we wrote some code and the code in suspended function performs sequential think it will download contents one by one one by one and if that's not really fast that can take quite a lot of time but here we have Kirkenes so we can do it in parallel how we doing in peril we just say launch you know and then in the loop instead of just waiting for each content is all what we just say let's just launch curtains to don't want it seems ok you know accordions a cheap what could go wrong here you know it's not like threads of course if we just started lots of threads we know what could be wrong with resources but we've been telling you all the time they achieve so what can go wrong to understand what's going on let's take a close look at this loop so how it works we take first reference we who is always your first location launch download from the content this location we take second reference we resolve it to a second location once you don't want we take third one and then what happens if result crashes some bug you know wrong reference something I found it's a crash throws exceptions you know the the whole process references aboard now all the currents were launched they are still there they're working doing their thing they they have leaked from our procedure now what we usually in the kind of reliable code that we might have we have somewhere in the top we catch this exception we try this process reference oh it happens again we leak more and you know this way even though curtains had sheep you know we may have unlimited number of those leaked curtains running in background will ultimately end up out of resources will overall to downstream services it's not good you know leaks are something that we don't want so what do we do the answer to this is called structured concurrency so instead of working with contents like we do with threads just launch them whenever we need to do something pearls we do it in structured way what does it mean it means that instead of writing this process references as a function that just launches curtains like whole thread will turn it into suspended function again we say okay we don't want it to complete until everything is done we wanted to work in a structured way we wanted to start doing its thing and only return after all is done but do it in non blocking way that's why I suspend and then we use a function called current scope Curtis could do limits this kind of parallel work that does something it has to wait for its result now inside we just put our code in because in scope when instead of using global scope the flange that we had to use before we just say launch and that does the magic trick for us now this launch becomes a child of this scope it is bound to the scope instead of just being run global like we usually do with threads so that's completely unlike threads we now have a child coordinate so this is a concept we don't have any threads and how it helps us it helps in it this way now if this piece of code crashes this exception goes through the scope and the scope goes and cancels all the children quarantines that it had already launched so this way there's no leak they're all canceled and not just they cancelled actually this scope would not return until they were complete so not just cancel them and let them finish whatever they were doing close your sources execute their final sections do cleanup and only then it returns so when our process reference function returns its we have a clean state again now we can safely try it we know that it had not leaked a single couraging had not worked a single job now our next topic is about the state we often have processes that involve state I mean there is lots of them so let's take an example and work with it so for example let's assume that instead of just downloading stuff taking references in the oil in their contents we want to create a long-running process some kind of a downloader process that does this don't was continuously and as an additional feature request that we have if it so happens that multiple references map to the same location result to the same location we don't want to download it twice we want to don't just once and you know save on the request to whatever back-end service that we're using so let's try to implement it if we were programming with threats our intention would be to encapsulate this state that we now have because we are have a state we now have to keep track or what locations we are downloading right it's not just a simple function anymore is there's a process we state so in object-oriented programming and threats programming with threads we're told that let's write a class right we usually cups right here class so let's create a downloader class and then it has a state we'll make a private state in this class it is going to contain him set of locations that are being downloaded and then when we this classes at to download reference is going to resolve location of this reference and then see if it's the first time we're somebody requesting this location if it's not yet in the set of locations then we go scheduled the hold and otherwise you know if it was already downloaded we just wait result somehow in process content this B code we would have written I mean I'm not feeling it's completely for purpose it just a skeleton of something we would have been written if you were programming with threads but now see what's happening here is in some sense routines are still like threads and they still involve concurrency so when we have multiple proteins it's similar to too heavy multiple threads we have concurrency we have things happening concurrently so if you have a complex application and then multiple curtains can invoke call this download reference concurrently with all the other proteins you know it's one growing process being used actively inside our application and see inside of it we work with this request that set we add to it and this also now happens concurrently so now we have this state even though is private to this download or class now it's shared in shared between multiple colleges and multiple cartoons can touch this state and I hope you all know and you can relate to the slide that was shown at the keynote dad you know when you have shared an mutable state that really ends badly you know it's something you I mean you can do it if you really know what's doing but the problem is that if you forgot something you forgot a proper centralization for that proper locks then then you have a box that's really hard to track down you know it's ditch races the code may work normally in your QE but the unfailing production you get weird crash locks from the customers it's also the problem happens when you start sharing mutable state and in this case Carlton's there's something on the surface no different than with threads we're program with threads we have to remember about sharbo mutable state and we when we program with curtains we have to remember about chart variable states that is dangerous don't do that but you see with threads we don't have my choice when a program with threats that's all we can do in the problem like that is to have this red middle state you have to write synchronization etc etc but carotenes they do give us a choice with curtains we don't have to have shared mutable state and that's the change of the way we program with curtains so instead of shared mutable state we can share information in our code by communicating between curtains and the chorus gives us as we'll see this power instead of working with synchronization primitives that we have to use with threads we can use communication primitives and instead of writing classes to encapsulate our state we can just write curtains to encapsulate our states we don't have to do it the way we did it before the weekend but we don't have to so how do you so instead of reading let's just launch accounting and have this immutable state be part of this curtainless you call it inside the curtain you see this way since it's confined to this curtain it's not shared it sits inside this guy you can access it from outside it's only this curtain that can touch the stage and then when we this curtain adds something to the set it's its own set it's not shared with any other curtain so it's safe but now we have a problem we somehow have to know a list of references to work on now and remember we wanted to have a long-running process that's just citizens program processes references so we have to somehow tell this curtain you know this is a references you should be working on so what do we use again in threats we've used a synchronization primitive we would have made this process resources function that synchronized this synchronization primitive any code for when we program with curtains we can use a communication primitive for that and that communication primitive is called a channel so a channel is lets us transfer information from outside world to inside our curtain without worrying about sharing mutable state which almost like a simple pipe you send on one side receive on the other let's see how it's used so to work with this channel we have to get a reference to this channel from somewhere so we declare our down water instead of declaring as a class we write a function we say let's write a function that creates it on water and this function is going to take a channel as a parameter because this particular curtain is going to be receiving from this channel it's a receive channel a channel we can receive from so the references is a receive channel that's a parameter to our curtain and inside the function is implemented to launch so its launches a quarantine and we have this convention that whenever a function launches in your curtain we declared an extension encouraged in scope it's it's really nice convention that makes our code self-documenting so now when I see look at this function I don't even have to read documentation okay said body it's convention we use it whenever the function is defined as an extension on curtain scope that means this function is going to launch in you a synchronous process that's convention videos very convenient because launch is defined also as an extension cards in scope so we can just use it from inside so it will launch according in whatever outside scope this function is called from now we just put our code inside and inside of the code channel works like sequence of elements we can just use a for loop to get references from that's are being sent to the sky routine and write whatever code we want so we can take reference resolve location we can add it to our set of requests and if it's the first time then we somehow have to shadow the download and we don't want to do download right here because we did all it here we'll lose Pro lism remember we want it to download in parallel so how did how we shed all this parallel download know we have curtains right so we can launch a curtain to download that's okay so we launch a new protein to them award you know proteins that ship what could go wrong here you might be thinking what you already told us what could go wrong right will the looked at the previous example where we launched new quarantine for all the thinking we just lose them in case of exception but not here here we have our bases covered because launch also defines the scope for colleges so whenever we launch from inside of it that's becoming a child and it works nicely so if that thing crashes it also cancels all the downloads it had launched so no it's not the problem with early concurrence is something else so think what else it can be one other problem we can hear interesting the problem we shouldn't be looking at the launch itself we should look at what the launch does you see curtains may be cheap but it doesn't mean that the work they do is cheap like in this inside that launch we'll be doing some download process that creates network connection access to some back-end system and that's all resources and you know there's limited amount of those ratios we can create I will really can't afford to create hundreds thousands of connections anyone who can now assist with other low downstream systems that are responding to these connections so whenever we do something concurrently and it'll it happens always when we start doing something concurrently we have to limit concurrency I mean you should never be doing like a limited Congrats what do things like concurrently because without limit that usually causes problem in your code or in downstream systems that you work with so we have to figure a way of limiting concurrency of the things with you so how did the way we do it is have a name and the name for this pattern is called workable so instead of just launching unlimited number of curtains that would do download let have a limited number of them and number that we control not the not just random number but some configuration parameter how much concurrency we want in our code so let's create those curtains that's going to perform the actual downloading work and now when references come in to the download is through the channel we'll use another channel to send the location that needs to be downloaded to this work sample so let's implement it now we see the down lawyer coding it's used to have only one parameter just references channel now it has the second one locations so we added in additional parameter to a function now in addition to references we have location but because now the downloader is it was receiving receiving for FS but it sends locations so locations is essential if the channel we sent to we send locations to now how changes the code now the code inside the dollar is straightforward when it's the first time we see this location we just send it over location channel store were careful great now we need to set up this worker for somehow so let's use the same pattern let's define a function let's use the same convention let's do an extension of carrot in scope and because the worker receives locations we define a parameter as receive channel so that's location this it's receiver locations from now let's write its code it's also Kuragin so we just launched a card in here nicely and we use loop for locations and you see the trick is here is called fanning out remember that we wanted multiple workers and you might think oh my god I'm now there's multiple workers now looping over this channel but the fact is channels are specifically designed for this custom partner whenever you use a for-loop to work our channel it works is fan-out fashion means each worker receives just one who has or other words we each request gets received by a single worker so it's automatically distributes the work workable channels as the engines are specifically designed for this kind of usage they work in fan-out fashion so now inside the worker the code is really simple the worker can just invoke our suspending function to download the content from this location and process it but now here's the problem we don't know what referenced it was we only told our worker what locations know what it doesn't know what reference because the other curtain had been resolving the references to locations moreover we wanted to optimize the thing so if multiple references result to the same location we just want to download once and then process result as if we did it multiple times so what do we do how we finish our course or sexually works and the code is not read so let's take a look at our architecture what is the piece in this architecture that actually knows about mapping between references and locations is this Islam lawyer is this curtain that actually resolves references to locations and knows what is doing so let's we should deliver the results back to the downloader so because it knows what references it was how do we deliver that you know the drill there are channels for that right so but what do we send we send something in Kotlin we create a data class for that right so we have a data class with location and content and now in a worker we just say okay please send your results here here is the same channel you would use to send allocations and content you've downloaded so now the worker code can be finished it's not ready more it compiles you know it just sends the location send content it had downloaded to this channel so now a picture looks like this downloader sends locations to work your whole orders will reply back with contents over another Channel so now we see down water now has three errors going in and out so it has two channels in one channel out we have to modify the function correspondent right we had third parameter that's content that's this downloader is going to be receiving so that's received channel now let's finish this code inside will loop in your references but um now we have two channels to receive from right so now downloader can receive references over one channel or it can receive content from another channel so how I let you write that we can't look just for references if you will program in with threads you know we'd say okay we'll just have two threads or two carotenes you know one with reference in other words contents channel but then we're back to square one now this beautiful set of requests is variable has to be shared between two accordions and we're back to the help of shared mutable state we don't want to be thinking about share bones I want to structure our application that we don't need any share unreadable state and for that we have a select expression so select expression of this trick that allows a structural code that works with multiple channels without using a shared mutable state so the way it works like this will write select and we put a number of clauses inside and we can say if something is received over references channel do this and if something is receive or contents channel do this and since select is an expression and in this particular example we don't need any result from it we see that results is going to be unit means it's like with unit return function we don't want any result from this particular select expression so now what happens with our download our code we updated a state a little bit because we don't just need a set of locations where the law also heap have to keep track of what references do want triggered the download of this location so we say we may keep a map off locations to a reference now inside we just look forever because that's what our downloader going to do is going to be long-running process it just looks forever and then it it uses a select and we write a code if something if a reference request is received then what do we do we resolve application we see if we all do requests in it what's references we've mean been record so far and if it was not then we send it to a work careful we say here is look at new location to download started and otherwise we just record that all here is location where all the downloading soldiers were Kirk another reference for it so we have this non-trivial piece of code the logic is pretty non-trivial that works with this immutable state this beautiful map offer requested locations the beauty of it that inside this code there's no concurrency so we don't have to worry shall I use concurrent hash map what happens if I first check and then act you know that we don't have any of those problem because everything inside the coding happens sequential so no concurrency no need for synchronization we just write simple sequential logic of it it's easy to verify that it's correct there's we don't have to stretch your mind to see why it would work on why it will fail so now all we have to finish is the other clause so what happens if we receive with the results from the worker poll and worker worker send us location and the content it's easy because this curtain knows this map it can loop for all the references recorded the mustn't run process the results for this references so that's kind of complete the code of down water it's all sequential no synchronization it's easy to check that it works now let's put it all together so we wrote these pieces but they're now separate functions so how we actually put those separate functions into something we can easily use let's take a look that's architecture in this architecture will join with just one input channel that's references that somebody some other parts of our systems request and there is some internal structure inside that's our input so let's write a function to encapsulate all of that okay this function starts some curtains so again convention define it's an extension curtain scope it only has one input the received channel of references is receiving from and inside it just creates the other channels it needs it creates a channel for communications between worker and downloader and it just creates workers and creates downloader that's it we've encapsulated this whole setup into a single function now from outside world we kind of hidden the whole detail of this machinery in this nice process reference function it's encapsulated all we have to know from outside it all the internal functions can be private now like the only public functions pop function we needed this process references that sets up all this infrastructure to do the actual good currency of limited downloading now when we look at this picture and when we actually start to apply the thinking throughout our systems will start to images partners everywhere will see these same constructs repeat ever and ever again so we see were careful that's a pattern we often needed to to work with limited concurrency tasks we see the objects that encapsulate States and receive messages that's part and called an anchor and these partners because cotton as a language has really nice abstraction facilities they easy to abstract into functions that are ready to use I said manually writing so I can show you low level way how we construct those partners from pieces but many of those pressures can be abstracted away for example we have in cotton library an actor obstructed nicely away and we don't have were careful yet but we'll be adding it later and there is actually any other patterns that exist and that appear we're currently in the systems but that's the topic of whole another talk I mean that's maybe talk I'll be doing our next coloring conference you know what kind of patterns are there how to use them here what I wanted to tell you that when you start thinking differently about the code when you structure it in a way that you don't share you know you your code start look different then the code you have written with threats that's the main message here so let's take a look at the curtain scope for now so we started with structure concurrency and then let's look at it again so our process reference function is an extension of corrosion scope but where does it start from well at Luke's our application at large what's the first scope who should be using where it appears like what be the root scope in which every everything works so where does it come from how we structure applications so it's properly we never lose curtains in transit discretion let's take a look at how we usually write applications in our applications in real applications won't grant applications either its back-end on front ends we usually M have some classes with a life cycle if we using MV people for example pattern for your application that's usually the solution presenter classes we create them we destroy them in VM architecture that that would be our V model classes on back-end systems who have connections we have request classes all of them have lifetime and while they leave they may need curtains to hold them doing the work and we want we usually want to be sure when the lifetime of these things and they don't forget don't leak any curtains don't leave any grudges behind so this is enforced by just implementing curtain scoped interface by those classes this is a mark that they think is going to to be a scope for new curtains is going to control when they are destroyed how implemented curtain scope is actually trivial interface all we have to do is implement one property to give a context for all the curtains we start the way we implemented is this we create a job object the job object is is a lifecycle of a curtain so whenever we say curtain life cycle or lifecycle that's that's called in a job in the curtain library and actually the the very first prototype of the curtain library we used the name lifetime for the job so it's very first prototype this this interface was called lifetime but then we play with it didn't really like the lifetime we did it sometimes it looked well like in this example but that sometimes it is so we named it to job and now is in diversion they were about finalizing 1.0 with the cotton 1.3 it is going to be fine it's finally is going to be job so we create a job to represent the lifetime of all the curtains we create now because the class will write anything has a lifecycle means it can be disposed or may be closed it doesn't matter how this been called I mean it can end you know it has an end to inside so did you touch this pose was a different frame was called it doesn't matter in curtains this is called cancel so when they think is disposed we cancel the job that's for curtains cancel it means the end of its lifetime and now all we have to do in our curtain context implementation say ok we want all new curtains to be launched in the context of this job and that guarantee is that whenever the life chairman is it also cancels all the jobs that it had launched so far what's nice think about it that is you can do other convenient thing here for example we can add a default dispatcher here so we know the thing is running as a part of UI and it's activity tracked here is UI we want all our carbons to be bound to a main thread so we just specify it right here so just one place we put it and then we don't have to always remember oh I should not forget to watch my curtains in UI thread just one place we encapsulate all our defaults for all our curtains in just one place and we can add other elements we might need so now if inside this class with lifecycle I have a function that does something and it needs to launch new curtains it just works because now for my class implants curtains one who just launched it launches extension curtains scope we just works properly or I could use my own functions that I defined that are defined as extensions encourages calm that's why a convention that whenever function want you to incur it if we define an extension on a curtains go the way week when we use it from inside our lifecycle classes classes with lifecycle they work properly they work in the context of the appropriate job and this way we never leaked Chanukah origin that's why we would destroy our form our view shutdown application all the whatever background activities they were launched will get cancelled and that's something you that's something you don't get with threads that's that's the way how Co routines are fundamentally different from threads they get in the way you structure your code and you do it in a structured way so the fear is lots of confusion and I've made multiple eyes on forums and people asking like how's this curtain scope now relates to suspend function so I can do suspend function I can do extensions come what's the difference what should they do so let me give you like really short and brief rule of thumb what you do what when you write a suspend function it means that it does something in waste verse completion without body that's a suspended function it's everything it does is contained in its lifetime so I invoke it and it does not return until it's done ending done doing whatever it was doing that's suspended function and suspended means it's not plucking so I can use it from UI thread and my UI is not going to freeze when I define a function as an extensional Kuragin scope it means it launches new protein and returns immediately that's again a convention and you can do something about convention is that doesn't wait for them returns but in this scope that says extension on it had created some new background curtains that now work in this scope that's a session and to avoid confusion I never define functions that are both suspend an extension encourages well that's easy I mean it's it just makes code easier to understand it's either it's a spending function that waits or it's non suspending function that extension on curtain scope that does not wait just you know readers quickly launches something and that's it's so as soon as you keep to this style there's no confusion and you also have this in the we saw the skirt in scope curly braces that works like a bridge between the two so in suspending function I can use current in scope and launch a bunch of currents inside my curtsy won't complete until they all complete because suspended function only finish when all they were doing completes that zero should not suspending function student by convention leave anything behind they should when they return they've done doing whatever they would you so what's the takeaway so we've started with the this idea that curtains are like like a thread and it's again is a mental model for people who are familiar with threads but in fact you know curtains are not like threads that's where quantity leads to completely new quality their quality of ly different concept that lets you structure in a code in a completely different way so you when you using curtains you should rethink the way you structure code you see because you have so many curtains like in threads you have few of them and you have no choice but you share it we will state and because there are few threads you can keep them in your head you can figure out who touches what but car cane is a lightweight applications when you start using them might have thousands tens of thousands of curtains if you do shine we will state with curtains you'll just get lost you know there's no way you can track it so we think the way a structure called a wood shareable immutable state and embrace the structured concurrency [Applause] [Music] any questions we have mice here so I mean if you have any questions about cartons searching anything you're welcome to come we have five minutes for questions anyone yeah hello yeah you showed that the button that the Oakridge scope and then job and blah blah blah can it be obstructed way so I as a developer don't see this I just put one something and and this job and and and this Gator and Saturday is hidden from me because now it looks like whenever I write by my my scope I need to put some boilerplate yeah this one yeah usually yeah that's very good question so see whenever you write real application you usually have some particular key texture for example if used MVP then you know you have you don't just because any architecture is also kind of boilerplate so for example let's take you have MVP and you have a bunch of presenters applications you don't write with presenter from scratch user you have some base presenter class that's you encourage all your presenters from so you do it once in your base presenter and that's it you're doing only in type of complication you have one kind of usually a lifecycle containing objects and you implement this just once per application so it's not a boilerplate it's just part of your core library and then whenever you create a new presenter you don't have to remember about that all your presence is automatically implements scope and you can just launch cartoons from from there now if you worried for example that oh I don't want my presenters to to the fact that they have a Curtiss could be part of the public interface you can also create a protected variable site that is an instance of Curtis called called scope and then instead of launch you'll be saying scope not launch and in the release version of proteins library in 1.0 like top-level one she is now deprecated and will be removed in 1.0 so so you will not be able to say launch without specifying this code that's again big difference from threats and threats you can choose your threat and that's it launch a global risk Ardennes we will be requiring that you always specify scope so you're always structured you always have to say what scope this car team wants them yeah I in example with Lincoln Corkins you mentioned that if we will put has been function in court in scope and one of them will crash course in scope will take care of it yes is there a way to report air or from origin to color code yes actually the when the the exception that the crash exception actually gets aggregated by proteins corporately reported to whatever color so any will just flow through the call stack normally so if one of my child it doesn't matter where it crashes if the incarnate scope a cellphone child the all the exceptions will get aggregated so the first exception will be the root cause of your failure and if while shutting down the rest of your work other exceptions are encountered they will become suppressed exceptions to the route 1 and then this root cause gets thrown outside so whatever your error have been code that you have outside the quality score will catch it and will be able to report to locks or whatever so and that's also good questions thank you it's very important difference between structured concurrency and the way to do stress and then if you do structured concurrency you never lose exceptions never there's never a case that thread crashed and just bring something to console nobody knows about it with Russian concurrency exceptions are always always percolate to the top and gets handled at the top then no exception gets ever lost hi thanks for the talk so I saw that we are sending a lot of data back and forth between the coroutine so how cheap actually is communication between co-routines so let me show our architectural picture right so yeah so we have a downloader and the additional click this we have lots of communication flowing back and forth though the cost of it really depends on what you're doing so if you're doing like really cheap thing inside the worker like adding two plus two now it's definitely going to be very to send messages over channels because remember channel is not just the communication primitive channel is a concurrent communication primitives I'm channel can bridge Koreans from different contexts you know can talk to multiple so channel is a concurrent communication concurrency is never cheap so but on the other side if your workers do some real work like they go to back-end system at all or something then channel subvert you you will not notice element you will not be able to measure they added you know performance a park over the channel if the work you do some real work like download is something from a back-end thank you so my question is assuming I have a suspending function and I want to call launch or a Singh or any other function that needs a scope as a as a receiver I see two possibilities I make my I can make my suspending function an extension of coroutine scope or I can call the co-routine scope top level function yes there there any difference between them and when should I use which you should also let me show you again so whenever you want to launch concurrent things from the from the suspend if I'm sorry there is also slides let me here it is so whenever you want to launch concurrent things from one side suspending function you should use curtain scope primitive that's that is what designed for it's a bridge between suspending functions and functions that extend on the curtain scope so by cars with the limits structurally the limits all the concurrent work all the children currencies that you're launching it won't complete until all the curtains you launch are complete so it makes sure you never leak any of the background tasks you know it will it waits until all the children complete and only then returns so if you open some resources files network connections and you have final sections to close them you know you are sure if you use courage and scope that until you know it won't return it in all those final sections complete so that so that's why you either write a suspended function or your readiness extension you don't means that you so that curtains cope with the primitive views okay thank you thanks for a dog that's laceration yeah so how we can get the content back so I see the communication internally inside the coroutines but how we report the result of the work back to let's say UI threat or something oh so I mean I will have the channels in the same way for communication from the corrosion back to sure so let me let me show you so I've obstructed this part away so I have some process content I didn't show what it does right but assume you'll want to show you I so you want to show you I do have two choices you can either just access UI from there because again if you're all curtains are bound to the your main thread then they can simply go and touch you I write from this function if you want to encapsulate it if you want this thing be again this depends on architecture if you want this thing like you're using some architecture and you want your business logic the abstracted away from UI so you can plug in different device so you don't have this thing this piece then you also give it a channel where report results to and then it's very easy on your UI level to start the core team that receives from the channel updates UI so but they then this think is fully self-contained it has an input channel and an alpha Channel you send it some work and receive over all the channels result and gave no shared mutable state you never share any beautiful state you just send it this subsystem some work and it of just some time you know reports your back results and also can multiple channels or like multiple entry points inside the application that can access the content of this the channel is a multicenter monitor receiver abstraction so I mean if you need to you can send it from multiple places and but when you receive it works in fan-out fashions so I mean only one there's also if you go read documentation like there's also broadcast channels there's way more to this I just my goal was to show you know basic things if you're interested in more now all the information leaves on cotton leg website in preparation 120 release go with it they're way more details on how this can be using what primitives are there thank you very much channels are part of 1.3 right yes thank you thank you much [Applause]
Info
Channel: JetBrainsTV
Views: 62,646
Rating: 4.9354262 out of 5
Keywords: Kotlin, KotlinConf, KotlinConf18, KotlinConf 2018, Roman Elizarov, coroutines, mutable state, JetBrains
Id: a3agLJQ6vt8
Channel Id: undefined
Length: 48min 46sec (2926 seconds)
Published: Mon Oct 15 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.