How can I browse all the pending jobs within my Redis queue so that I could cancel the Mailable that has a certain emailAddress-sendTime pair?

我正在使用Laravel 5.5,并且有一个我正在成功使用的邮件,如下所示:

$sendTime = Carbon::now()->addHours(3);
Mail::to($emailAddress)
      ->bcc([config('mail.supportTeam.address'), config('mail.main.address')])
                    ->later($sendTime, new MyCustomMailable($subject, $dataForMailView));

当这段代码运行时,一个作业(job)被添加到我的Redis队列中.

我已经看过Laravel docs个了,但还是很困惑.

How can I cancel a Mailable (prevent it from sending)?

I'd love to code a webpage within my Laravel app that makes this easy for me.

Or maybe there are tools that already make this easy (maybe FastoRedis?)? In that case, instructions about how to achieve this goal that way would also be really helpful. Thanks!

Update:

我曾try 使用FastoRedis浏览Redis队列,但我不知道如何删除邮件,例如红色箭头指向此处:

UPDATE:

Look at the comprehensive answer I provided below.

推荐答案

Comprehensive Answer:

我现在使用我自己的自定义DispatchableWithControl特征,而不是Dispatable特征.

我这样称呼它:

$executeAt = Carbon::now()->addDays(7)->addHours(2)->addMinutes(17);
SomeJobThatWillSendAnEmailOrDoWhatever::dispatch($contactId, $executeAt);

namespace App\Jobs;

use App\Models\Tag;
use Carbon\Carbon;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Log;

class SomeJobThatWillSendAnEmailOrDoWhatever implements ShouldQueue {

    use DispatchableWithControl,
        InteractsWithQueue,
        Queueable,
        SerializesModels;

    protected $contactId;
    protected $executeAt;

    /**
     * 
     * @param string $contactId
     * @param Carbon $executeAt
     * @return void
     */
    public function __construct($contactId, $executeAt) {
        $this->contactId = $contactId;
        $this->executeAt = $executeAt;
    }

    /**
     * Execute the job. 
     *
     * @return void
     */
    public function handle() {
        if ($this->checkWhetherShouldExecute($this->contactId, $this->executeAt)) {
            //do stuff here
        }
    }

    /**
     * The job failed to process. 
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(Exception $exception) {
        // Send user notification of failure, etc...
        Log::error(static::class . ' failed: ' . $exception);
    }

}

namespace App\Jobs;

use App\Models\Automation;
use Carbon\Carbon;
use Illuminate\Foundation\Bus\PendingDispatch;
use Log;

trait DispatchableWithControl {

    use \Illuminate\Foundation\Bus\Dispatchable {//https://stackoverflow.com/questions/40299080/is-there-a-way-to-extend-trait-in-php
        \Illuminate\Foundation\Bus\Dispatchable::dispatch as parentDispatch;
    }

    /**
     * Dispatch the job with the given arguments.
     *
     * @return \Illuminate\Foundation\Bus\PendingDispatch
     */
    public static function dispatch() {
        $args = func_get_args();
        if (count($args) < 2) {
            $args[] = Carbon::now(TT::UTC); //if $executeAt wasn't provided, use 'now' (no delay)
        }
        list($contactId, $executeAt) = $args;
        $newAutomationArray = [
            'contact_id' => $contactId,
            'job_class_name' => static::class,
            'execute_at' => $executeAt->format(TT::MYSQL_DATETIME_FORMAT)
        ];
        Log::debug(json_encode($newAutomationArray));
        Automation::create($newAutomationArray);
        $pendingDispatch = new PendingDispatch(new static(...$args));
        return $pendingDispatch->delay($executeAt);
    }

    /**
     * @param int $contactId
     * @param Carbon $executeAt
     * @return boolean
     */
    public function checkWhetherShouldExecute($contactId, $executeAt) {
        $conditionsToMatch = [
            'contact_id' => $contactId,
            'job_class_name' => static::class,
            'execute_at' => $executeAt->format(TT::MYSQL_DATETIME_FORMAT)
        ];
        Log::debug('checkWhetherShouldExecute ' . json_encode($conditionsToMatch));
        $automation = Automation::where($conditionsToMatch)->first();
        if ($automation) {
            $automation->delete();
            Log::debug('checkWhetherShouldExecute = true, so soft-deleted record.');
            return true;
        } else {
            return false;
        }
    }

}

所以,现在我可以查看我的"automations"表来查看挂起的作业(job),如果我想阻止作业(job)执行,我可以删除(或软删除)任何这些记录.

Laravel相关问答推荐

在Vite list 中找不到文件:Resources/scss/hrms.scss.如何使用LARAVEL VITE解决这个问题?

如何在Vite和Rollup中完全禁用分块?

通过 laravel 中的 url 传递多个字符串作为参数以从数据库中删除特定数据

Laravel 9 上的数组差异助手

使用 laravel 根据当月显示注册用户列表

mysql 加入 ON 和 AND 到 laravel eloquent

如何使用 Laravel 查询生成器在 WHERE 条件周围添加括号

我在哪里放置事件侦听器和处理程序?

如何对有序的has many关系进行分页?

你如何找到 Laravel 外观背后的底层类?

在 laravel 查询构建器中使用多个 where 子句

Laravel - 超过 PHP 最大上传大小限制时验证文件大小

带有时间戳的 Laravel 5.1 eloquent::attach() 方法

干预图像:直接从带有原始文件名和分机的网址保存图像?

调整行数以形成:: Textarea Laravel 5

防止 Eloquent 查询上的模型水合

Select,where JSON 包含数组

Laravel 5 - 跳过迁移

开发中的 Laravel 和视图缓存 - 无法立即看到更改

有没有办法让表名自动添加到 Eloquent 查询方法中?