30 Days to Learn Laravel, Ep 25 - Queues Are Easier Than You Think

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right folks we are officially moving on to day 25 So within job controller if I scroll down to my store action in the last episode we did learn how to send an email which is great but one problem is well at the moment it's all happening synchronously or in other words we are making the user wait for however long it takes to deliver this email so if it takes maybe 2 seconds to deliver that email then the user has to wait 2 seconds for a resp response and I get it 2 seconds isn't a very long time to wait but on the other hand as it turns out it's an extremely long time to wait so yep this just won't do instead it would be nice if we could take that job and in this case the job is delivering an email to you and we're just going to throw it into the background all right we'll get to that in just a minute but for now I want to immediately respond to the user all right let's figure out how to do that all right so I'm going to close this out and our first step is once again our configuration directory and you can see we have a config file for our cues now as it turns out there are a variety of services and backends to assist with your cues and we can see a list of supported connections here so sync that's synchronous that means run the job as part of the current request sort of like what we've been doing already uh but this can be useful for testing or local development next you can run your cues using the database driver and believe it or not not I think this is a good way to go for a long time maybe longer than you think but otherwise if you need something a little more robust you could reach for beanock sqs or redus Okay so let's see right up here the default Q connection is in fact the database driver but notice it's looking for a q connection environment uh variable so if once again you go into environment let's scroll down to q and yeah you could rewrite this to whatever you want to use so if you want to support redis or sqs you can swap it out here for now though I'm going to stick with database all right let's switch back to config now if we scroll down here are the various uh connection settings for the driver we choose in this case database and you'll learn more about some of these options in the future but for now notice the table section here so of course if you're going to use a database driver then you need some place to house or contain uh all of your jobs while they're being processed and right now that table is called jobs and a migration for that table comes with the LL out of the box we've already seen it in table plus all right let's keep going down and uh yeah there's some sections here for Q batching how to handle failed jobs and once again for a database driver it's going to look for a table called failed jobs and again we already have access to that so if I switch back to table plus here is the cued jobs table and then we also have a failed jobs table that comes with larl out of the box as a migration you can review it here let's go into database migrations and it should be this one here create jobs table yep you get this out of the box okay so all of that to say if I return to job controller when it comes to mail it's really easy all I have to do is change this send method to Q so now I'm saying no don't deliver this email as part of the current request instead I want you to throw it onto a queue okay so I'm going to explain that more in just a second but why don't we try this out to the browser I'm signed in as John Doe let's create a brand new job how about lass instructor and this one pays how about 70,000 USD all right let's submit that now we've created that record in the database we can see it here but what about the email the confirmation email well let's switch over to mail track and my inbox is empty let's do a sanity check refresh do it three times for good measure nope no email hm so what is the problem here all right I'm going to try to explain this in a simple and easy to understand way but in order to do that I got to tell you a story but don't worry I'm not 80 it's not going to take 20 minutes uh it'll only take a moment or so okay so a really long time ago when I was in high school I worked at a copy and printer place called Kinka uh it was eventually bought by FedEx and today it's known as FedEx office but yeah way back then it was known as Kinkos okay so my job was Cas here so a customer would come in and they'd say hey I need 300 copies of this flyer and I would be responsible for that however when that job and that's kind of a key word there the job is making 300 copies of the flyer when that job would come in yes I could have walked around to the copy machine and performed that job for them but think about it the customer would have had to wait for me to complete that job I go over to the machine maybe somebody's using it before me I wait for them I then perform the copies and then I return to the customer and I say all right here you go a second possibility though is I say okay 300 copies and I hand it to a person whose only job is to make copies I hand it to to Stan Stan can you take care of this for me and immediately after I do that I turned back to the customer and I complete their order all right so you know what we did there that was a real life queue a job came on and I threw it to a queue and in this case that Q was the table right behind me where Stan another worker at Kinkos can be exclusively responsible for knocking out those jobs oh and by the way that term worker it's another key word all right so you see what I mean you already know what a queue is you already know what a job is you already know what a worker is because you see it in your everyday life so the problem is we've thrown a new job onto this queue hey I need somebody to deliver this email for me but if I turn around there's nobody working in the back there are no workers at the moment so let's fix that open your terminal and run PHP Artisan Q work aha notice processing jobs from the default Q all right and sure enough we had a job to deliver an email all right let's switch back to the browser come back to mail trap and there we go open our email and everything works just like before pretty cool huh so yeah if you intend to use cu's then you also need to have one or more workers to work on the Queue and that's exactly what this Q work command does all right so that means yeah uh when you push your project up to production you will need to run this command behind the scenes and don't worry there are dedicated tools and services to help with this for example there's one tool called supervisor that will ensure that no matter what this Q workor command never Falls over it's always running behind the scenes all right so let's do this let's switch over to my routes file and once again I'm going to build up a test route just so we can play around with a couple things so when we're done I will return done and I want to play around with dispatching a job because of course in real life you will be doing much more than delivering an email there will likely be a variety of process and actions you're performing that take a bit of time especially these days when there's so much interaction with AI so first step is the dispatch helper function this is really cool we call this a cued closure so why don't we just say for now log to a file hello from the que all right so as we learned in a previous episode logs will be added here storage logs l. log and let's clear this out all right so let's give this a run but before I switch to the browser I'm going to close out this qw command just for illustrative purposes I can close it out with contrl C all right so back to our demo project I'm going to go to example. testtest we get return done so now we have dispatched to job but yeah once again if I switch to my editor yeah we don't see anything just like before so I'm drilling this into you that's why I'm doing it two times now think about it we dispatched a job the job was thrown onto a queue and if it helps just think of a queue as a stack of papers and each paper represents some kind of job that needs to be performed the only problem is there's no worker to handle those jobs so nothing happens all right let's get to work think about it you're you're the nasty boss who says get to work get to work and they start working all right so they run this queued closure and if I switch back now we see the log all right so this is really helpful if I come back to my routes file so sometimes you want to trigger a bit of logic that happens outside of the current request but it's fairly basic and you want to perform it in line you don't want to complicate things all right so in situations like that the dispatch helper function is a great way to go and you can even do cool things like I can delay this so I could say delay it for 5 seconds all right let's give that a shot I'm going to close this out I already have my Q work command running so I don't have to restart it and if I switch back to the browser let's give it a refresh yeah if I come back notice one two I'm switching away to make it refresh 3 4 five there it goes so we dispatched a job that was delayed by 5 Seconds and this can be really helpful uh for example if you want to send a welcome email 15 minutes after the user signs up that would be one way to handle that all right but anyways let's head back to our routes file and discuss dedicated job classes now switch back to the terminal and hit contrl + C uh one thing I could imagine doing is What if after an employer publishes a new job we take care of translating it to a dozen different languages and maybe we want to use artificial intelligence to to handle that task well we can definitely do that but once again it takes a bit of time so let's instead throw that job onto a queue I'm going to run make job hm what should the job be named well how about translate job okay so now it'll be placed within a new app jobs directory let's have a look let's go into app and sure enough you have a new jobs folder and there we go all right so we see a bunch of traits here uh mostly you can ignore those but of course each one adds just a little bit of behavior to interact with the queue for example or to serialize your eloquent models when they are um added to the queue and retrieved from the queue but anyways for now all you need to know is this handle method is where your job logic will be triggered so for example if I just wanted to once again say logger hello from translate job I could do that and you know what this is a great way to learn so let's give it a shot I'm going to go back to my routes file and this time I'm not going to use a cued closure I will dispatch a dedicated job I'll do that by referencing the name of the class translate job and you'll see that I have a dispatch method so let's run that now we'll give it a refresh and then of course from the terminal I will start my worker get to work and now if I switch to my log file sure enough we do see hello from translate job all right super cool all right so back in my routes file yeah it doesn't really make sense does it to dispatch a job and by the way I will clean that up to dispatch a job but then provide no indication as to which job we are referring to and yeah we're getting a little Inception here get Inception we have two different concepts that have the same name we have a job listing for our application and then we also have a cued job so uh granted a little less than ideal for a tutorial but you get it okay so anyways we're going to fix this by tracking down a job listing from the database and then I will pass that into the dispatch method and let's clean that up okay so now our job listing will be passed to our job CL yeah even as I say this it's confusing but um yeah that's just how it turned out all right so I will inject this public job job but as I do this we can see my editor is squawking and again that's because we're colliding a little bit with our cued job interface so as it turns out if I go up a level it looks like there already is a job property here that refers to the CU job rather than the job listing so why don't we just rename this to job listing here all right so now yeah at this point you would reach for whatever AI service you have maybe if you have an AI class you could call a method like translate and then you would reference your job listing uh we only have a title here but yeah in real life you'd have something like a description and then youd provide a list of languages that you want to translate that to so for example maybe if we're just translating it to Spanish this could be our API but yeah the entire point is this is potentially a long running process that should not take place as part of the current request so instead we locate it within a job and then we dispatch that job onto the queue for now we will simulate that by saying log translating this job listing title to Spanish all right and let's give it a run give it a refresh and now return to level. log and oh actually I forgot to mention this this is a really good uh error that we can discuss so notice it's still displaying the old value hello from translate job instead of our new version which you see here all right so what's the problem well keep in mind whenever you run this Q work command it loads everything into memory so since we loaded it into memory we have changed the logic for our job and it's not yet reflected okay so this means whenever you make a significant change you should restart your Q worker and yeah once you push to production you will set that up as part of your your build or your deploy script make sure you restart your worker so run it again and this time if we give it another try back to my editor open ll. log and sure enough we can see all right we are translating the lawn service manager job to Spanish it works all right so that has been your introduction to Q's episode so yeah I hope now terms like Q and job and worker aren't quite so scary anymore I don't know I I find that in the early stages we we are all Masters at terrifying ourselves when it comes to terminology but yeah if you can just find a real World Cory correlation Cory what's the right word there correlation I don't know if you can find a real world comparison uh it instantly makes sense don't you think all right so let's be done with that in the next episode I want to introduce you to vit I'll see you then now [Music]
Info
Channel: Laracasts
Views: 3,126
Rating: undefined out of 5
Keywords: web development, php, programming, laravel, laracasts, jeffrey way, coding
Id: OhQ_3yaUQRQ
Channel Id: undefined
Length: 15min 45sec (945 seconds)
Published: Mon May 13 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.