CompletableFuture: The Promises of Java

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right welcome to the session on completable futures the promises of Java my name is Venkat Subramanyam we're going to talk about first of all a little bit about what are completable futures why we really need them and then we'll talk a little bit about how its implemented in Java how we can use it and along the way I'll also compare and contrast this to something else that we have in Java which is the streams API as well so let's get started well one of the first things I want to start with is some lessons that we can learn from JavaScript I know that sounds really odd but it's true we can actually learn from JavaScript as well so JavaScript has gone through a phenomenal growth over the past several decades and one of the things that Java programmers have learned real the hard way is callbacks in fact they have a special name for it it's called a callback hell if you ever think callbacks are a good idea I have a suggestion for you a workup close to a Java C programmer and utter the word call back and watch them begin to cry uncontrollably because this is how really painful it is to use callbacks well the JavaScript world has moved on to use promises so what is really a promise a promise is an object that would have one of three different states it may be in a state which is called a resolved estate when it has completed it could be in a rejected state where it has said that you know I don't have a good result an error condition or it's in a pending state so it's got to be in one of these three states but if it's an offending state it could potentially resolve or reject but if it's in reject or result state it would never ever change after that a promise itself has two channels of communication this is the data channel through which data would come through an error channel through which an error would come through but it'd be one or the other and you treat failure like it's data and one of the really nice things about promises is it's really easy to compose promises and that's one of the nice things about it let's just spend a minute on this to understand how this is going to work so when you have a promise let's say you have a promise well a promise contains actually two tracks so to say you can say that is right I caught a left track or a top track and a bottom track depending on how you want to say it and you have these two tracks and you have these tracks filled with functions so suppose a promise eels our data let's say this is a data we guard and you pass this data through a function and if this function is successful you get another data from it and that will go to another function if that were successful you'll get another data but instead of a data something goes wrong over here then immediately this function would route you through the bottom track or the left track if you want to call it that way with an error now when you have this error over here you can pass the to yet another function if that function tried to you know restore sanity but it couldn't it blows up again well you have another error and then this could continue for a while where you're gonna be in this error track but let's suppose you call another function and the function is able to recover from this error well then you suddenly jump over to the track over here and the next function potentially could be returning data for you so this is an example of how things progress through promises so on the left you have function that gave you a promise and that generated a piece of data and you pass it through another function that generate another piece of data that passes through another function that failed for whatever reason you have an error and then the next function also blows up and you're always in this blowing up stage and then this says I can handle it now you are back over here and then you're able to continue on the good track so this is an example of how promises propagate data and error through them and of course this could you go back and forth this is just one example potentially you may have just branch off right here and you could be dealing with data here so you could be going across the tracks anytime you want to so think about it as these two tracks and everything is going well you're on the right track something goes wrong here on the Left track something keeps going wrong here on the left track suddenly something is better you back on the right track and you could be zigzagging your way through and that's basically how the data propagates through these promises chain in the case of JavaScript now I know what you're thinking is we thought we are coming for a Java based session while you're talking about JavaScript well here's the beauty javascript has promises and when I started looking at completable futures in Java I was very intrigued and confused I was thinking what in the world it is and honestly it took me a little bit of time to figure out that completable futures in Java are absolutely nothing but promises in JavaScript if they had called it promises everyone will understand it so they said no we'll give a completely different name so nobody would have a clue so completely futures really are javascript promises that's why it called it the title as the promises of Java because that's what completel futures really are so completely future in Java is really a sample of promises in JavaScript you have what are called stages so what's a stage a stage really is you could say this is a stage a stage is a segment of the pipeline where you are performing some action a function and then you go to the next stage in the next stage the next stage and you have this completed future full of these stages let's understand this with a little example once the stage completes you are ready to run the next stage and it can keep moving let's look at some examples of this let's create a completely future and play with it this is going to be somewhat of a you know trivial example to begin with but let's give it a try and see how this is going to work so what I'm going to do here is to create a function and and this is going to be completing feature that's what I want to return from here it's a completable future of integer type we'll call that that one so this is going to be an integer type of completable future and I'm gonna call this as create for now so we'll take a start with baby steps so what do we want to do here I'm gonna say this is going to be a completable future obviously so completable future and in this case of course I'm gonna create an example to return a completable future of let's say a sink over here and and what am I going to provide as a response in this particular case so I will go ahead and say that when you call this one this is going to simply return the response of a compute method so nothing really really exciting at this point let's go ahead and write this method called compute it's going to simply return some response right here what just returning to do to begin with again nothing really exciting at this point that's what we are starting with so this is a complete little future we want to start with as an example right here so what am I going to do here so we'll go ahead and start with a little completable future object and and what I want to do is to start running these calls through this async future and run through it let's go ahead and take a look at this real quick what the method name here is so we'll say there's going to be completed will feature object and that's going to be the class this was introduced as part of Java eight and this is the funny part Java eight introduced both streams uncomputable future a lot of us got excited about streams and we kind of didn't really pay much attention to completely futures but this is something really exciting that that we have available in here so if you look at the static methods this contains there is a method here called you know supply async that's what I'm really trying to call right here and and we'll call the supply async and you can see that it takes a supplier which doesn't take any arguments really and that's what I want to go ahead and call this apply async and run that code so what is this going to really do at this point well this is gonna be really trivial but we'll get started with this I'll call the create method and then I'm gonna say then accept and we'll put sense to these methods in just a little bit I'm gonna take some data given to me and I want to just print out this data that's given to us so let's start with this little baby steps right in here so all I'm going to do is call this create method that we created right here and invoke the create method and ask it to perform this operation and of course that's going to be a static method as well I mean that static context and it printed the beautiful two as a response but what does it really do for us to understand this let's go ahead and ask the question right in here output let's say in main of course and we will ask it for the thread that's executing this particular code I'm gonna thread our current thread and you can see that in this case this is going to be obviously the main thread of execution no surprise over there but the question is what thread is going to execute the compute method so if you look at the compute method right here and ask for the current thread you will notice that that's automatically in the fork/join pool common pool thread so when you create a completely future as you did on line number 11 it is executing the compute method in an asynchronous manner in a completely different thread now obvious question we have right now is where does the print execute and this is where the fun part really is so to understand this let's go ahead and take this and call it as a print it where I'll create a separate method right here called a printed and the printed method takes a value and it's going to simply display the value right now so when I run this you can see the two being displayed but out of curiosity I want to know where the printed method is actually actually executing so if I say print it : and then say thread current thread over here and run this code there in it's going to display the thread exit of execution and and what does it tell us as the thread that's executing it so notice the printed ran in the common pool thread as well so why is that the word I want you to think about is the word non-blocking so in other words an asynchronous processing you want to be in a non-blocking situation suppose you ask for a cup of coffee from somebody and they say I'll make it to you in a minute obviously don't want to wait for the coffee you want to go do other stuff and then the coffee is ready they could give it to you so the idea is you want to be in a non-blocking mode so when it ran this code you'd notice that in this particular case it ran that piece of code in the in the common pool thread but don't assume that is the case all the time why not because the reason s it is quite possible that by the time you are coming to execute this the thread may already be completed and the main can might as well execute it and that is another beauty of this particular approach is the threads can be really different to illustrate the point let's go ahead and create a completable future right in here is equal to and we'll just assign what create gives us to that for a minute let's go ahead and sleep here for just about a second if you will and then I'm gonna call this completable future and that I'm gonna ask it to go ahead and you know consume the data that it is returning for us and then I will go ahead and say you know sleep for another second so we can just display the result after this so what's gonna happen at this point well in this particular example what it really did is that it's going to take this completable future and we have fired it off and it's executing in the background then we take our sweet time take a little siesta come back and call the den except at this point and ask it to execute that code at this moment so when I execute this code what does it really do notice the surprise over there the print it now ran in the main thread not in the pool why is that this should make really good sense because this thread was executed it finished its work there is no reason for the thread to waste its effort and wait for you and you took your time and now you came and connected to it remember this completely future is in the pending state at this point and then of course it could resolve or it could reject it well by the time you got to that highlighted piece of code the completed future is no longer pending it is resolved so because it's resolved it immediately ran on the main thread you don't have to block for a result that's already ready so the point about non-blocking is not to create a thread the point of a non-blocking is not to block so if the result is already there why bother creating another thread my TAS will execute it so it's pretty darn efficient as you can see so these things happen for you pretty nicely behind the scenes so you saw the thread of execution and how that works really nicely you can also change the pool in which this is executing so as you saw here when you ran this code the things that you saw here we're running literally in this common pool thread which is nice and I like common pool thread but there are times when you don't things in a common pool thread you may want to run in your own custom pool after all so what do you do if that's what you really want to do so to understand that at that point let's come back to this example notice again the common pool thread is what you're seeing right there but what I'm gonna do in this example is again don't take this example literally but I'm gonna create a fork/join pool right here so I'm gonna say for join join pool and and I will just say fjp here is equal to new a for join pool of 10 let's go ahead and say I'm creating a for join pool now when I create this in the supply async as a second argument I can provide the for join pool that I want to use and you can see now it's no longer running in the common pool it's running in the custom pool we just created so that's how easily you can tell it where to run it by default it uses the for join pool but a common pool on the other hand if you provide a different pool it uses that particular pool as you can see so that gives us an idea about how this is all working now let's talk a little bit about the methods we are looking at well we know that Java 8 has the idea of streams and we have completest most of us in this room I would assume are fairly familiar with streams API so what are the things you use in stream you use for each in stream which takes a consumer if you remember right and then of course you also have a map which takes a function you also have a filter well that takes a predicate let's not worry about it for now so we these are the functions you normally use in the screams API for each use as a consumer a map uses a function if you remember what the method of the consumer is the method of the consumer is called accept isn't it just keep that in mind what is the method of function you recollect that is called apply just keep that in mind as well so so these are the concepts you are familiar with in streams and when it started playing with completable futures I was a little bit confused because you know I would like these transformations to happen but why are these methods looking a little deaf and little weird and there's a reason for it now before we go any further with this let's understand this with a little bit more example right here we call the compute method right in here we call the printed method right in here we created a complete future as you can see right in here as well and then let's go over here to use this one in this particular thing we'll just go ahead and say and then and we will accept it and print it notice that result of this was a value of 2 so what did the then except do it it really printed the data for us so you can kind of get the picture now so this is equal in two then except so just like you are for each method of the stream API you have it then except in the case of completely future and now you know why they called it then except because it is going to be a consumer so because we're passing a consumer do it they decided to call it as then except you may wonder why didn't they just call it for each the reason for it is the stream may have a 0 1 or more data on the other hand a computer future can at most have one data or error right so this is basically one of the key differences between the two is that a completely future can have utmost one data or error on the other hand stream can have as many data as you want it's going to be a stream of data coming through so it doesn't make sense to use the word for each because there's only one what does it mean to say each in that context so that is why they called it been accept so you can see that it's going to accept a consumer as well so that makes really good sense except for one small difference when you're taking a stream and calling a for each remember a for each is a void method it doesn't return anything to you its end of story that is something we heard about completable future a completable ok this is the irony a completely future never completes so in this is like Thor in the movie you're gonna see Thor again I'm sorry jános in the movie right the parent of the land you you're done with this Avengers but Thanos is back again in the next one so it's kind of like that it never never ends so just to illustrate the point notice I go here and say then one well why run because I don't have any more data so all I'm going to do is simply do a run and there's gonna take a runnable and now what am I gonna do here I'm gonna say all done so when I run this code you will notice that it says all then but the beauty of this is you can say then run and then you can say output right here and then you can simply say and not really right so you can keep going with this how much ever you want to go with this and it'll keep on going now one thing I challenge you never to do please wait for this to be over because that is never gonna be over so keep on going right so there's absolutely no end to it and that is the one of the ironies of the global future so it's kind of like a train you get on to the Train and when you want to get off you do get off never ask the question word is the scream girl because that's gonna be a long route so complete future is a pipeline you can get on the pipeline you can exit when you want to and I know what you're thinking you're thinking I wonder where that completed future is going well just don't worry about it right because it's never going to finish it's gonna keep on going so that's an example of computable future you can just keep through this pipeline and you can keep executing it so what you can do here is you can do some operations with the data but then you can do some logging with the data and you can say you know what I send the data to the data base and it can do a logging so then run can be very useful for that purpose so he can provide that very nicely so that's an example of how you can draw this nice pipeline so we saw them accept but one of the things you do in the case of a stream API offer so I talked about then run already one of the things you can do in the streams API is you can perform a nice map operation remember what the map does it performs the transformation of data well it's quite cool we want to transform the data the map function will transform zero one or more pieces of data but here I want to just transform one piece of data that's all I want to do so how do we really do that well that's where then apply comes in and notice the word apply from here so that should really make sense because we are performing a transformation we want to provide a function to it and that's why this is called then apply so you can see how that kind of nicely matches that call and we can use the den apply function let's give it a try how does that then apply really look like so I'm gonna go over here and say a dart then apply and given the data I want to take the data and times two remember we've been returning a value of two two times two is four and as a result of course we're gonna display a value of four in the end and that's where the transformation of the data happens so if you were to subscribe to an asynchronous service maybe this is a web server that's gonna give you a stock price and you're registered with the stock price service and said give me the stock price when you have it and none you're not blocking when the stock price arrives to you you can take the price of the stock and you can do stuff with it maybe you want to take the price and discount it or maybe you want to add a surcharge to it which is more likely than what we normally do and then you want to then perform operation with it and maybe send it off to another service for transactions you can do that pretty nicely as you can see so that is an example of how you can go through this transformation and so that then apply can happen similarly you can also do it then apply one more time and you can take the data right now and you can perform data +1 obviously these could be two different methods you are interested in using so 2 times 2 is 4 4 plus 1 is 5 and you can see the result of 5 being displayed right there so that's a series of transformations you can apply to the data that you get from the completable future and so that nicely flows through as you can see this really helped me to comprehend what I'm doing because these names really didn't really connect to me in the beginning so as I started really looking through them I said why are these called then apply then accept so hopefully the the reason I gave I gave you is a little bit easier to know keep that in mind there's a really good reason for these names to have these these things like then apply and then accept a end of that but obviously we are looking at a pipeline of operations that we are performing and you can see the pipeline that we created right now so that works really well but on the other hand let's go ahead and take a look at one slightly different example what if we want to create a pipeline and then come back and deal with propagating the data this is a little fun unfair example here because in this example as you can see I just created the data at the source that is not very realistic so what are we going to do let's go ahead and take a look at a slightly different example to see how this would work so I'm gonna go ahead and say over here completable future one more time but this time I'm gonna create a method called a process so the process method takes a completable future and and this completable future will just still keep it as integer if you will and and this is gonna be a future I'm gonna pass through this particular function welcome back to that function in just a minute so now I'm gonna say completable future of integer we'll go ahead and say the future is equal to new completable future notice I created an empty future object right in here then I pass it to the process method and ask it to do some processing with it well the process method is going to form the pipeline for us so notice what I'll do here I'll take the future given to us and I'll say then apply and given a piece of data I want to take the data and and multiply it with two then I say then accept and I'm going to simply take the data and I'm going to just print it out system dot out print line and we will just print it as you can see in here this is going to just form the pipeline that's all we did once you form the pipeline you can take the future and you can say complete and you can pass the data that you want to pass to wait and and based on what you really want to do you can pass it do this so I said complete isn't it so you can ask you to complete it so notice how this is going to work somebody could give you a complete future you could draw up a pipeline of the future and be ready for it and in this case you can say given this particular data whenever the data arrives I will take the data and double it I'll take the data and increment the data afterwards and then of course when the data is pushed through the pipeline I can then process it and print it again I want you to think about this in that scenario of a remote call or an asynchronous call you might send a request to a web server and say give me the stock price for Google and then you could set up a little pipeline as to what to do when the data for Google arrives stock price for Google arrives and you can pass it through a pipeline at that point so this is an example of how this is all going to work so that seems really reasonable so far but I know what you're thinking you're thinking wait but you never talked about things going wrong yet and in real life things always go wrong so how do you deal with it I don't have to admit this is not something I'm too happy with I'm not happy with the name they gave for this at all but before we talk about the name they gave for it let's talk about how to really handle it remember what I showed you in here this pipeline up to this point in this presentation unfortunately I only showed you the happy path all I showed you was the den and then and then and then but what if things were to go wrong what are you going to do about it well this is where the unhappy path needs to come in so what I'm going to do here is I'll go to the future and you could do this at any point you want and here's the name that I'm not happy with at all it is called exceptionally and this is really a sad way to say it right this is actually not exceptional at all right but I think they had a very dry sense of humor so they called it exceptionally right and then what do you do here in this case you get a throwable and before we implement the throwable want you to closely take a look at what we did here if the function that's dealing with exception gave you another exception you stay on the unhappy path which means this function either blows up or this function quietly returns a result to you that is something you have to be very careful about you cannot write an exceptionally function and return a data because then you're signalling I'm okay I handled it so if you want to say this is really broken you got to blow up one more time so notice what I'm gonna do here I'm gonna take this exceptionally and I'm going to go ahead and say hey over here I'm gonna then say a handle that's what I'm gonna call it right here I'll call it as handle and I'm gonna pass the throwable all the way to that particular you know handle function what does the handle function do so in this case the public static let's say in this case integer so int and handle and and this takes a throwable if you will so throwable and it's go ahead and say throwable and what am I going to do with tildes throwable I'll first of all print an error right here and then I'll print out the throwable then what am I gonna do I'm gonna quietly return a hundred so that means I reckon this problem and if I found an exception maybe I would substitute another value for it right so you are saying this particular example the way I have it right now you had a problem you come in here to this with the error and this guy says I took care of it and bounces you right back to the happy path that's what I'm doing at the moment but of course the question is how do you signal the error how do you tell something really went wrong so let's first of all run this code real coy notice it still gave us a value of five and the reason is you completed with the two so what happened when you completed with the two when you complete it with the two the future resolved with the two so you step over that exceptionally and arrive at the dem apply little hard to see this but you gotta kind of put a pair of glasses where Mannino easier when you get old like me because it's already I can see two lines here but the point really is that for the young people you have to squint your eyes to see it so this is the top line and this is the bottom line right so in this case that exceptionally is right in here and the dents are right in here so if everything went fine you're going to kind of hop over that right you're not going to get into there exceptionally and then you're going to get to the then apply and you're gonna take that path so if you're thinking if that is true can I have exceptionally over here that will be absolutely exceptional code to have that as well as well you can put as many of them as you want to so you can have these series of things filled up anywhere you want to so when I run this code no tears it was successful it by personally exceptionally came to the then apply and then apply and then accept so we passed it to so it bypassed this and 2 times 2 is 4 4 plus 1 is 5 so it printed 5 but I want to say that something really went wrong how do I do that well if you want to say that something really went wrong this is even better name in my opinion they really were playing with us so you can say future dart completed exceptionally right so this is even better isn't it so here I the reason I like this method really is I'll tell you in a second so what am I going to do new runtime exception and I'm going to simply say something went wrong right that's always very useful so we'll say something went wrong and give that error message so this is going to blow up with a runtime exception called something went wrong so when it runs this code what is it going to really do well in this case it's it's complaining so a complete exception not completed exceptionally complete exceptionally and notice it says error something went wrong but then the result is 201 why is it 201 look at the line well let's look at the line number look at line number 12 line number 12 printed that message and remember what handle exception does it returns a hundred so the next line says 100 times 2 is 200 200 plus 1 is 201 and that finish the reason I love this message is as programmers when you start programming completable futures this is only programmers will know so when the boss comes around and says how are things going you simply tell the boss I am completing it exceptionally right so they and the rest of the programmers know what you're talking about this is our secret communication from Rwanda right you can just wink to your developer I complete exceptionally so so this is a nice way to communicate so you're saying it pretty much you know through board on that particular point so the whole idea behind this is that you are just passing through this exception and saying handle this but what do I do if I really want to blow this up well at that point I'm gonna come down here and rather than returning a hundred I'm gonna simply throw new runtime exception and say this is beyond any repair right so I can blow this up even more and notice now it does not display 201 why is that because this completed exceptionally so it dragged into this exceptionally block that blew up one more time and because you blew it up it will not come to any of the den block and because there is no exceptionally after this it's simply exit at this point so in other words what we have right now is that we started up here and we had an error right in the beginning we came to this bottom track and we stayed on the bottom track never to go up because we had no recovery from this particular exception at this point so that is basically an example of how you are able to deal with these two really nicely so that gives you an idea about how we can deal with exceptions and chaining so this is all working really well except in Java 8 there is one huge deficiency and and the deficiency is that when you start a completable future I want you to go back to this example for a minute here and and notice in this example if I compute this with successful case and when I run this code notice it printed a value of five so that worked really well on the other hand if I blew it up and run this code you can see it printed that something went wrong but what if for some reason I never get the data from the server and what's gonna happen when I run this code and notice it does not do anything so this could leave to a situation of a live lock isn't it so what's a live lock light lock is where you're waiting for an event that will never happen so this before I answer what to do with that I want to talk about a philosophy a philosophy of life and I'm gonna say in life and a life and programming don't do or anything usually I can just stop with this actually but I'll continue so in life and programming don't do anything without timeout this is a very important rule to follow right now now give you an example I always tell young people about this if you're trying to find a perfect love a wisdom even trust me on this one you want to look for a perfect love but time out on it otherwise there's a chance that we will die alone very old so this is something really good I mean this is built into the Indian culture just to emphasize this is why we have arranged marriage so the parents tell us you know go find the love but if you don't you're going to marry whom we tell you to do I think that's very wise so the point really is that it gives you a little time out to deal with right so you always I'm just kidding but only a little bit so the point really is that that you want to always perform a time out on things well sad part is in Java 8 they did not have timeout which means you just don't know how long you're gonna wait for something to finish and that's simply not acceptable well I'm using Java 11 over here but they fixed it really quickly in Java 9 so in Java 9 you have a timeout available let's think about how timeout will work in the scenario so notice I have a complete over here but I'm going to call this process but I'm gonna sleep for about two seconds of the time well okay let's say three seconds I'm gonna sleep for it then in the end I'm going to sleep for let's about say five seconds it's gotta be a little slow but that's okay and then eventually I'm going to you know say that this is completed let's go ahead and say here's a sleep function let's go ahead and run this when it runs this code what does it really do so in this case of course after a three-second delay I'm gonna complete it and as a result you will notice that it's going to display the value of five obviously that's what you would expect it if you don't mind I'll run this on the command prompt it's a little bit easier to see this on the command prompt so we'll go ahead and go to the place where I have this code and then we'll run it on the command prompt so let me get rid of this so you can actually see this a little bit better so what I want to show you here is just how this code is going to behave with the timeout with the sleep and see how this is going to work so let's go ahead and fire this up I'm gonna just run this code right in here and you can see that at the end of the three second delay you got the data output as you would expect well that worked really well on the other hand if I were to blow up after the time clearly this is gonna blow up shouldn't be any surprise also so you can see that's working also and you can see the error message up here after that delay but on the other hand what if I don't do anything at all well unfortunately in this case we're gonna just keep waiting and when eventually the program you know finishes are if it's gonna run for a very long time nothing exciting happens unfortunately and so as a result that's not acceptable so what are we going to do to fix it so what we're gonna do to fix it let's put the complete again but as soon as I create the completable future I'm going to say future dart and I'm gonna say complete on time out and I'm going to say give a value of 500 and then I'm gonna give it oh let's give it about force at let's say three seconds so I'm gonna give it about a three-second delay and let's make this a two seconds of you know delay so at the end of three seconds so let's go ahead as a three time unit dart seconds so this says complete on time out with a value of 500 after a delay of three seconds how does this really work you have told this future you have a window of three seconds if you finish within three seconds we are good because remember once a completely future results it'll never change its state so once it has resolved in the time if you come to resolve it again that will be discarded and so as a result that will become a no up on the other hand if you took more than three seconds and you have not still completed then this is going to complete with the value of to five hundred and say here you go take it let's make sure that's actually true let's run with this code a two-second delay later we got a value of five as you would expect and the reason for that is we complete it successfully on the other hand if I fail after two seconds you will expect the exception to appear because once it rejects it's not going to change its state that's working as well on the other hand if I don't complete and if it don't you know blow up within the duration of time then what is it going to do I'm gonna send a 500 through this pipeline 500 times 2 is thousand plus 1 is thousand 1 let's see if that's what it's going to do so what 3 seconds has expired and now you can see a thousand and 1 that's because you didn't finish in the time allocated it's going to go off and finish it for you now obvious question is what's going to happen to the task that you started what what what if it eventually comes back well sorry we don't care about it so that's going to be asynchronous and it just we don't wait for it we keep moving at this point and do whatever that we need to do so that is an example of of completing on time out but what if you don't want to complete what if you want to blow up if something really were to go wrong then rather than doing it this way simply say future dart our time out and in this case I'm gonna give an elements of 3 seconds and notice that now you're saying if you have finished in three seconds I'm happy with you if you're not finishing in three seconds if you didn't blow up in three seconds I'm gonna destroy this thing for you so once again let's go ahead and complete it for ourselves go ahead and run the code in this case what does it do oh let's go ahead and fix this right here so our time out so this is going to be time unit dart seconds there's an exception right there in my code let's try this again so so this is going to give us I can't find the symbol or timeout so this is going to be okay let's try this one more time so this is going to provide the value for us so that right there and you can see that it actually completed on the other hand if I were to blow up within the duration of time it is going to give me my blow up which is called something went wrong and you can see it says something went wrong on the other hand if I don't complete if I don't blow up then it's going to timeout an error at that point so once again let's go ahead and run this and see that and a three seconds goes by and it blows up with a timeout exception to tell us sorry that I waited this long you didn't finish it I'm gonna blow up at this point and call it as quits so that's so what's a lot of the story never use completable futures without using a timeout it depends on your business domain sometimes it makes sense to go ahead and complete with the result sometimes it makes sense to blow up who can say other than you what the right thing to do in your situation is but it gives you the option to pick and choose what may make sense in your scenario in your application so we saw those two but then I want to talk about do other functions in the next four minutes and talk about what those things provide for us one of them is called a combined method and this really made it hard for me because I was trying to understand what a combine really means so to understand this let's take a slightly different example and play with it so I'm gonna go ahead and say over here let's go ahead and create a completable future so it's a completable future right here and this completable future of integers is create and and what it's going to do is it's a silly example with pass and n over here and all it's going to do for us is a simply return so we'll say return a completely future dart supply a sink and it's going to simply return this value of n given to it right so nothing really exciting so let's start with that little step for now and see where it takes us so what I want to do now is to call this method create but the way I'm gonna do this is I'm gonna say create with the two but there are times when you might want to combine the results of do a synchronous operation for example a request comes into your server and you need to go get the current balance for the customer but you also want to know the credit limit they are eligible for so what would you do you got two calls to make why bother you could do them at the same time you can send one request asynchronous synchronously to say get me the current balance another request asynchrony to say get me the current limit when both of them arrive you can continue forward with your operation so in other words what I want to do is combine so what do I do to combine it so what I'm gonna do is to take this completable future that you have here and I'm gonna say then combine and what am I gonna combine it with the create over here of three so I'm asking it to combine with the two now when you combine it what it's going to do is take these values and put that together so as I was looking through this ice ask myself tell me something that I'm used to already and that you know what it is over here it's the reduce method so the reduce combines things for you in a stream API isn't it so this is very much like reduce and this is called then combined over here so the den combined will mix the result of two asynchronous operation one goes off the other goes off when the first arrives it waits for the second to arrive and when both of them already it can merge them through for you that's basically the purpose of this then combined let's see how we can use this right in here so I'm going to say then combined and then I'm going to say let's call it as a comma B and then I want to just mix them together a plus be over here and and what is this going to do it's going to give us another completable future so then I can say then accept and then of course system dart out over here and and this is going to be printing the result of both of those I know this is a very silly example but hopefully this illustrates what this is doing so this is going to get us a value of two this gets the value of three two plus three is five and that's what we are expecting this to do and notice how that got combined into the result now obviously if one takes longer than the other one this will patiently wait for that to come through and of course you can use a timeout on that as well if you really want to do so hopefully that gives you an idea about how we can use combine so combined is kind of like a zip operation right you're taking two things and you're merging them together in this case it's a reduce that you're bringing in that's why this is a binary operation you're performing right in here well that's great so far but then let's talk about compose but before we talk about compose we have to talk about something else so so before we talk about this week I'll talk something else what is that so that is we when you look at a streams API I want you to think about something for a minute if I have a one to one function meaning I got wonderful people in this room and everyone has a first name so for every person I want their first name that's a one to one operation so if you have a stream of P and you perform a map of f1 where one where it's a one to one function what is the result of this it's a stream of R we know this right on the other hand if I have a one-to-many function like I want all your email addresses and and that way I can spam every one of them so in that case I want the one to many mapping then what do you do well stream of P of map of F one-to-many 1 1 to n will return unfortunately a stream of the list of R or something like that which is not very much fun at all if you think about it isn't it so what do we if I really wanted just one list and not a list of lists what can I do well then what you do is you take the stream and you perform what's called a flat map and a flat map is going to take the fur of this function but the result is going to be a stream afar so this is the time when you would decide whether to use a map or a flat map if you have a one-to-one function use a map if you ever want to many function you might want to use a flat map rather than using a map because a map will give you a stream of a list of our stream of stream of our whatever that may be whereas this is gonna give you a stream of art well where I'm going with this is we know that we have a flat map in this case well same to a way if you really think about it this is where that then composed really comes in so what does it then compose do then compose gives you an ability to take a result that returns a computable future and return back from that so that's basically the idea is if you want to perform an operation which will in turn give you a completely future thank you I'm told it's a time out so you are you basically what you can do in this cases should I stop talking all right so just bear with me for a minute so what you can do here is you can which is one minute so what we can do here is you can take the completable future and you can return a completely future in return for it and this is where that then combined really compose really comes in so in other words you take the result you got here and simply say data and you call maybe a create again if you will notice this itself is a completable future that you're getting and in this case of course you'll use a compose and that is the whole idea because when this is returning a comparable future you want the result of this is not a completely future of computable future but a completely future of that data itself with that I complete this thanks for your time you
Info
Channel: Oracle Developers
Views: 42,159
Rating: undefined out of 5
Keywords: oracle, oracle cloud, oracle developers, cloud, cloud computing, platform, infrastructure
Id: 9ueIL0SwEWI
Channel Id: undefined
Length: 47min 47sec (2867 seconds)
Published: Thu Oct 25 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.