简体   繁体   中英

Laravel Dispatch Intercept/Customize

I basically want to do this: Add custom field to Laravel queued job records?

However the top-voted answer there doesn't really address how to do this, rather it advocates for a work-around.

I know in order to actually accomplish this I need to tap into the dispatch function. The issue is it isn't being called directly in my (in this case) event listener.

According to this and this dispatch is a global helper function. Where in the source code is this registered and how should I overwrite it in my event listener in order to run handle() (that which dispatch itself calls) in my Job class after a specified delay and yet be able to add additional entries/fields to the database?

My prime reason for this is because:

1). The job is sending a notificaiton via email.

2). Emails should only go out after a delay IF the user hasn't logged in/been active during that delay.

3). AND emails should only go out if that user doesn't have another email queued up since the first was dispatched, in which case the first should be consolidated and deleted into the second email.

Therefore I need additional database fields in order to find, delete and modify entries in the jobs table.

These ideas come from an article on Medium which teaches that you don't want to spam users with emails/notifications and you need to consolidate/group/prioritize them and I'm trying to do this in Laravel.

I believe it is possible in Laravel but I am unsure how to overwrite the functionality when dispatch is a global and I don't know from where it is invoked. The Laravel docs on the Command Bus don't go beyond Laravel 5.0.

Edit: I have to use Redis now, according to this (because I am getting that beginTransaction() error in my queue):

Redis Driver > Database Driver

I think a model watcher would be best but I'm not sure if Job is an Eloquent model. I need something that will work consistently across database drivers.

When you create a job instance everything assigned to a public property is serialized and thereafter available to you during the job processing. You can pass in parameters to the job constructor and then assign them to properties like

public $foo;

public function __constructor($bar) {

    $this->foo = $bar;

}

Then in the handle function you can get the value $bar from $this->foo

Edit: If found this method within the DatabaseQueue class. Perhaps you could override to suit your needs:

/**
 * Create an array to insert for the given job.
 *
 * @param  string|null  $queue
 * @param  string  $payload
 * @param  int  $availableAt
 * @param  int  $attempts
 * @return array
 */
protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0)
{
    return [
        'queue' => $queue,
        'attempts' => $attempts,
        'reserved_at' => null,
        'available_at' => $availableAt,
        'created_at' => $this->currentTime(),
        'payload' => $payload,
    ];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM