1 00:00:06,090 --> 00:00:10,590 Let's quickly talk about async versus threads because they are different. 2 00:00:11,610 --> 00:00:14,830 Threads are suitable for a small number of tasks. 3 00:00:14,850 --> 00:00:18,480 Since threads come with CPU and memory overhead. 4 00:00:18,540 --> 00:00:24,810 When we spawn and switch between threads, that is an expensive request and even idle threads can consume 5 00:00:24,810 --> 00:00:25,740 resources. 6 00:00:27,250 --> 00:00:32,560 Threads also allow us to use asynchronous code without huge changes. 7 00:00:32,560 --> 00:00:34,870 So that is a benefit to threads. 8 00:00:35,650 --> 00:00:42,340 Async, on the other hand, provides us with significantly reduced CPU and memory overhead, especially 9 00:00:42,340 --> 00:00:48,460 when talking about high input and output bound tasks such as databases and servers. 10 00:00:49,120 --> 00:00:56,080 You can have a significantly higher amount of tasks than operating system threads because async uses 11 00:00:56,080 --> 00:01:01,150 a small amount of expensive threads to handle a large amount of cheap tasks. 12 00:01:01,660 --> 00:01:05,700 But again, async does not mean it is better than threads. 13 00:01:05,710 --> 00:01:06,880 It is just different. 14 00:01:07,840 --> 00:01:12,860 So use threads where appropriate as well as using async. 15 00:01:12,880 --> 00:01:19,290 But now let's start to get into the asynchronous programming by looking at a trait called future. 16 00:01:19,300 --> 00:01:23,380 And a future is at the heart of asynchronous programming. 17 00:01:23,800 --> 00:01:28,740 A future is an asynchronous computation that can produce a value. 18 00:01:28,750 --> 00:01:34,900 So let's look at how the future trait is implemented just so that we can get a feel for it. 19 00:01:35,530 --> 00:01:41,260 So it is a trait and it's called future and it's going to have type output. 20 00:01:42,500 --> 00:01:45,830 And then inside we're going to have a function called poll. 21 00:01:47,220 --> 00:01:52,920 And I'm not going to get into the actual implementation of Pull because this is a high level view. 22 00:01:53,760 --> 00:02:02,670 But from this, what we can see is that a it is a generic over the output and we have a function called 23 00:02:02,670 --> 00:02:11,010 poll provided for us and poll is going to allow us to check on the state of the current computation. 24 00:02:11,810 --> 00:02:20,510 So if we actually look inside of pull, we we can have Penn and then we'll have a mutable self. 25 00:02:21,580 --> 00:02:32,230 And then we'll have a context which is a mutable context, and then poll is going to return a pole of 26 00:02:32,230 --> 00:02:33,070 self 27 00:02:35,590 --> 00:02:36,400 output. 28 00:02:38,340 --> 00:02:44,700 And again, we don't need to worry about Penn and context in this case because this is just a high level 29 00:02:44,700 --> 00:02:48,270 overview and we just want to kind of get a feel for what a future is. 30 00:02:49,800 --> 00:02:50,520 So. 31 00:02:51,450 --> 00:02:58,830 But the poll function is actually really important because when a computation is done, poll will return, 32 00:02:58,830 --> 00:03:02,670 poll ready, poll ready. 33 00:03:03,990 --> 00:03:08,130 And when the computation is not done, poll will return. 34 00:03:09,300 --> 00:03:10,410 Poll pending. 35 00:03:12,210 --> 00:03:18,780 And this is important for us because it allows us to use a keyword called a weight, which we will see 36 00:03:18,780 --> 00:03:19,830 in a second. 37 00:03:21,220 --> 00:03:26,290 So now that we kind of know what a future is, we can start to look at. 38 00:03:27,030 --> 00:03:29,730 Facing an async. 39 00:03:30,880 --> 00:03:33,700 We actually need to import a dependency. 40 00:03:34,810 --> 00:03:41,110 So I'm just going to go ahead and delete all of this and then we can go to our cargo file and import 41 00:03:41,110 --> 00:03:44,440 in async standard and then we'll say version one. 42 00:03:44,440 --> 00:03:49,150 That way we get the latest version for this dependency. 43 00:03:51,030 --> 00:03:53,220 And now we want to import an. 44 00:03:55,410 --> 00:04:02,160 Some of the features inside of async standard. 45 00:04:04,710 --> 00:04:17,100 We want file IO Prelude and task and we want these because we're going to do an asynchronous read from 46 00:04:17,100 --> 00:04:22,500 a file and then assign the contents of the file to a mutable string. 47 00:04:23,260 --> 00:04:26,260 Variable and then we want to output it to the terminal. 48 00:04:26,680 --> 00:04:33,430 So we're going to create a function now and we actually create this function with a new keyword and 49 00:04:33,430 --> 00:04:39,100 it's going to be called async, and that's going to signify that this function is asynchronous. 50 00:04:39,400 --> 00:04:46,700 So we have an async function called read file and we're going to have one parameter which is going to 51 00:04:46,700 --> 00:04:55,210 extract, accept a string slice to the file we want to read from and then we're going to return a result 52 00:04:55,420 --> 00:04:56,710 of type string. 53 00:04:58,810 --> 00:05:00,880 So we're going to open up our file. 54 00:05:06,400 --> 00:05:09,910 Point to our path and then we want to await. 55 00:05:10,030 --> 00:05:13,780 And this is that key word that I mentioned a couple of minutes ago. 56 00:05:13,780 --> 00:05:17,530 And I will break down a weight in a second for us. 57 00:05:18,220 --> 00:05:27,910 So we're also going to have mutable contents, which is going to be the variable that stores the data 58 00:05:27,910 --> 00:05:29,410 in our file. 59 00:05:30,100 --> 00:05:38,380 And then we want to read to string and assign it to the contents variable. 60 00:05:39,040 --> 00:05:42,880 And we also want to await that. 61 00:05:43,570 --> 00:05:49,000 And then if all goes well, we want to return our. 62 00:05:49,960 --> 00:05:50,710 Contents. 63 00:05:51,520 --> 00:05:53,830 So what does a weight do? 64 00:05:53,980 --> 00:05:55,600 Because we keep talking about it. 65 00:05:55,600 --> 00:05:57,190 So what does it actually do? 66 00:05:57,220 --> 00:06:00,790 Well, a weight is actually going to do what it sounds like it will do. 67 00:06:01,210 --> 00:06:04,660 It is going to wait until the requested action is finished. 68 00:06:05,500 --> 00:06:10,750 So a weight is essentially a marker or a bookmark, if you will. 69 00:06:12,060 --> 00:06:15,810 The code will wait for a future to produce its value. 70 00:06:16,200 --> 00:06:18,390 So what is the benefit to this? 71 00:06:18,420 --> 00:06:26,190 Well, the runtime in charge of executing this piece of code will take care of all the other things 72 00:06:26,190 --> 00:06:29,850 it can do while it waits for the computation to finish. 73 00:06:29,940 --> 00:06:37,050 And then it will come back to this point, a.k.a the bookmark when the operation has finished. 74 00:06:37,230 --> 00:06:39,630 So how can we put all this to use? 75 00:06:39,660 --> 00:06:45,030 Well, we will find out in the next lecture when we start to talk about tasks.