Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

thirdwunder's avatar

Delay execution of an event listener by a specific time

I have a event for when a model is created which invokes listener which creates thumbnails for an image. i'd like to delay this execution by a few minutes, but i cant seem to find the right documentation on how to delay the listener class with InteractsWithQueue implementing ShouldQueue. How would i add a time delay on the handle method?

0 likes
14 replies
thirdwunder's avatar

i've read the documentation there but the examples are on how to do it from a controller. my events are initiated from a model create. not sure how to implement a delay from an event

D9705996's avatar

You can use the global event method in your model e.g. event(new whateverYourEvent) to fire your event

thirdwunder's avatar

Sorry, but im new to this. How would I trigger an event on create of a model object. I was using the Laravel events system, but I’m guessing i would have to override the create function to do what’s your suggesting ?

thirdwunder's avatar

Ok so essentially I would override the create method in a model, within fit call the parent create method and then use the global event method with a delay. Am I getting this right? The example there is initiated from a controller

D9705996's avatar

Without seeing your code it's hard to tell exactly how you plan to achieve you goal but sounds ok. What I would do though is in the controller create the model as normal without performing the thumbnail creation and then fire an event from the controller that performs the isolated image optimisation (You can pass the model into the event constructor)

martinbean's avatar

@thirdwunder Events are dispatched when something happens in your application, and listeners are supposed to handle those events when they occur, not at a later date.

I think you’re instead looking for a queued job, which can be delayed (https://laravel.com/docs/5.4/queues#delayed-dispatching).

However, wouldn’t you want thumbnails of uploaded images created as soon as possible? Therefore, I’m not sure why you want generation to be delayed?

thirdwunder's avatar

@martinbean i am looking for a delayed event. The setup is that i have a csv with data in it, where one of the columns is an image url. I'm importing this url and saving to amazon S3 and recoding the import in to a photos table. While i'm doing that i'd like to create thumbnails. But since the import of the content of the csv is quite intensive, and upload to s3 can take time, i'd like to delay the creation of thumbnails to about 5min (coz thats the longest the import takes) to make sure that the image is available in s3. Sometimes if the thumbnail creation function is triggered too quickly it throws and error.

all this is invoked in an artisan command btw, so not in a controller. hence wanting to trigger a createThumbnails event from the create of the Photo model and save in the db.

martinbean's avatar

@thirdwunder That’s a very fragile approach. What if the CSV import does take longer than 5 minutes? Or fails completely?

Why not use events for their intended purpose? You want to process images after a CSV file’s been uploaded, so why not raise an event when that happens? Dispatch a `CsvFileImport event and then have a listener that goes off and processes the images in response to that.

This way, images are only processed after the CSV file has been uploaded. And if the CSV file is uploaded quickly, there isn’t a delay in processing images whilst your application waits for the arbitrary 5-minute delay to elapse.

thirdwunder's avatar

@martinbean thats a good point. For now I’ve just been exploring the different ways I can do this, and trying to understand my options. The reason I wanted to use an event per photo model created is that that way I can keep track of only the new images that are created, and not have to rerun a thumbnail creation and optimization on all images. A lot of the time the csv will have the same image a small before. So by firing an event for only 8nages that are created, I make thumbnails for only new images coz existing images would have even previously created. I wanted to send every new images in Tom a processing queue, weather 5min delay or after the whole import process is complete Unless there are better ways of managing bulk image optimization and manipulations, I’m all ears.

martinbean's avatar

@thirdwunder I’m not sure I follow.

I’d dispatch an event when the CSV has finished uploading. The event would have a listener, to process the images contained in the CSV.

If CSVs have the possibility of containing already-uploaded images, then your listener can just do a quick check and not re-process it if it already exists.

protected $listen = [
    Events\CsvFileUploaded::class => [
        Listeners\ProcessUploadedImages::class,
    ],
];
class ProcessUploadedImages
{
    public function handle(CsvFileUploaded $event)
    {
        // I don’t know how you retrieve images in your CSV files
        foreach ($images as $image) {
            if ($image->alreadyProcessed()) {
                // Don’t process already-uploaded image
                continue;
            }

            // Add a job to your queue to process the new image
            dispatch(new ProcessImage($image));
        }
    }
}

Your listener listens for when a CSV file is uploaded, grabs the images from that file (you’ll need to add that logic), and then for each new image, adds a job to a queue to process that new image.

1 like

Please or to participate in this conversation.