I mentioned before that when you create a future, it starts running immediately.
It also returns a handle absolutely immediately, no matter how long the future takes.
So we're going to look at the different states of the future and how they work to not block the thread
you're on whilst still doing work and giving you back a handle with a future result in it.
Now for this the the worksheets are very handy for demonstrating this in particular for this demo,
for this example, I recommend going into the worksheet settings, which is this this wrench icon up
here and turning on use ripple mode because this will give you a little bit more insight into how and
when things are happening.
So the code we're going to look at here, here are my standard imports.
I actually don't need the duration import here.
So we'll we'll get rid of that for now just to show that it's not needed.
We do need the global thread pool because that's what we're going to create.
These futures in here for demo purposes.
Oh, there's one more place that you are allowed to do awaits and sleeps, and that is in demo code
because you actually want to demonstrate this, but you normally you would never do this.
The reason I'm showing it here is I want to deliberately show a computation that takes some period of
time and it's just kinder to the CPU to sleep this and not make it bust itself.
You know, work really hard for a second.
So we're going to simulate this being a computation that takes a second.
And this, you know, very, very reasonably could take a second.
The idea is we don't want to block our current thread while we're waiting for this result to come in.
So this will take a second and then return the value ten.
And what we're also going to do is take another future and we're going to take the result of this future
and multiply it by ten as well.
So let's have a look at this.
We'll kick it off running and just pay attention to this top part of the screen here.
So what you'll see is that we do the import and then these two come back immediately.
There's now a sleep and I hope you saw that.
And then it did the rest of it.
So forget the rest of what's running right now.
Let's have a look at what happened here.
So up here, we created a future and this future started running and this came back immediately.
When it came back, it told me that the future here is not completed.
And likewise, F2 came back immediately.
It didn't take a second.
It came back immediately.
And this future is also not completed yet.
So the first thing we've learned is that if you do something to the result of a future and you do it
using a map or a flat map, one of these combinators, this does not block either.
It comes back immediately and that's really nice.
So now we have two futures.
They both are futures events because that's what we've got here.
We've got an int here and we've taken this and multiplied it by an int.
So we've got another int here.
If we look at the value it will say this value is none and it's not completed yet.
By the time we got down to this one.
And maybe I should make this a little bit of a slower, let's make it five seconds instead and run it
again and we'll do the thread.
Sleep for five seconds here.
All right.
So let's run this again and that'll give me a bit more time to talk through this as it goes as well.
Whoops.
There we go.
So here you'll see these come back immediately.
And then there's a five second sleep and then it starts doing the rest of this.
Now, this thread was able to do other stuff and I can demonstrate that.
In fact, let's do that.
Println, println.
We are not blocked.
We are.
And then we'll do another one.
Println.
We can still do stuff.
Okay, so let's run it again and see that.
So up here generates those and it says we are not blocked.
We can still do stuff.
So our thread is still running here.
We're not blocked waiting for these.
We then wait for the other threads to catch up and when they do, you'll notice that this is the states
that we that we get.
So let's take a look at these in in depth.
We didn't block here, but we also don't have a result yet because there's no result.
This future internally is represented as an option of a try of whatever type we've said will be the
result of it.
And until there is a result, the option is none.
So there is no result yet.
Okay.
And we also see that is completed is false.
Likewise, F two didn't block either and that one is also none that doesn't have a result yet and is
completed as false.
We can still do stuff in our thread.
We're not blocked.
But when the future is finally ready, after five seconds, we come back in here and now you'll see
that we have the option has been resolved and it is a sum of success of ten.
Likewise, as soon as that was ready, the second future got to run.
Now it didn't block.
But now that this is ready, it can be swapped into the thread and do its work.
And this one came out as some of success of 100.
And so that's the states.
There is a third state, which is that let's recap these.
So the states that we know about so far is it hasn't been done yet.
Okay.
It's incomplete at this point.
This as soon as it has been completed, we get a success.
This is one of the other states so completed successfully.
And there is a third state which is completed.
But there was a failure.
And this is when something goes wrong in the future.
Right.
This is one of the things about asynchronous programming.
You set these things going and if something fails, you need to know about that later as well.
It's no good just assuming it's going to work because it might not and you can't see the future.
So that's a that's kind of funny because you can actually look into the future, but you can't actually
see what it's going to do until it's resolved.
So this form, if we have a look back in the worksheet here, this when it fails, produces a sum of
failure instead of a sum of success, and then it gives the exception inside of it.
So there are three states that futures can be in.
They can be unresolved, in which case the value is none.
They can be resolved successfully, in which case they are sum with a success or they can be resolved
as failure, in which case they are sum.
They are sum of failure and a throwable a exception that describes what's wrong.