【问题标题】:Add custom field to Laravel queued job records?将自定义字段添加到 Laravel 排队作业记录?
【发布时间】:2015-12-30 17:04:25
【问题描述】:

我有一个使用“数据库”驱动程序的名为“SendMyEmail”的工作 Laravel 5 排队作业类。数据库 'jobs' 表已正确填充了此类分派的作业。

我想在网站上显示这些工作,因此我想在这些工作记录构建时添加并保存一个名为“名称”的自定义字段的值。 (我会将此名称作为参数传递给 SendMyEmail 类构造函数..)

有人知道怎么做吗?

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案1】:

    请尝试使用此代码处理失败的工作。

     <?php
    
        namespace App\Jobs;
    
        use Illuminate\Bus\Queueable;
        use Illuminate\Queue\SerializesModels;
        use Illuminate\Queue\InteractsWithQueue;
        use Illuminate\Contracts\Queue\ShouldQueue;
        use Illuminate\Foundation\Bus\Dispatchable;
    
        use App\User;
        use App\JobHistory;
    
        class ProvisonUser implements ShouldQueue
        {
            use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
            protected $user;
            protected $history;
            protected $id;
    
            /**
             * Create a new job instance.
             *
             * @return void
             */
            public function __construct(User $user, JobHistory $history)
            {
                $this->user = $user;
                $this->history = $history;
    
                // Set up our new history record and get unique id
                $this->id = DB::table('jobs_history')->insertGetId([
                    'user_id' => $this->user->id,
                    'job' => 'Provison User',
                    'status' => 0
    
                ]);
    
            }
    
            /**
             * Execute the job.
             *
             * @return void
             */
            public function handle()
            {
                // Do other stuff here....
    
                try{
                    $JobHistory = JobHistory::findOrfail($this->id);
                    // Once the job has finished, set history status to 1.
                    $JobHistory->status = 1;
                    $JobHistory->save();
                }catch (\Exception $e){
                    // failed job, set history status to 1.
                    $JobHistory->status = 2;
                    $JobHistory->save();
                }
    
            }
            public function failed()
            {
                $JobHistory = JobHistory::findOrfail($this->id);
                // failed job, set history status to 1.
                $JobHistory->status = 2;
                $JobHistory->save();
            }
        }
    

    在我的例子中,这段代码是有效的。

    【讨论】:

      【解决方案2】:

      好的,所以您想保留排队/处理的作业的历史记录,对。

      没有任何内置支持自定义数据库字段。

      见:

      https://github.com/laravel/framework/blob/7212b1e9620c36bf806e444f6931cf5f379c68ff/src/Illuminate/Queue/DatabaseQueue.php#L170

      据我了解,这种行为是有意的,因为您不应该真正弄乱原始的“工作”表。它被设计为无状态工作。这意味着作业记录在处理后立即被删除。

      如果您想跟踪您的作业(例如历史记录),您可能只需创建一个新的 Eloquent 模型并将其传递给您的作业构造函数。这很有用,可以使原始作业和您的历史保持同步。


      好吧,让我们开始编码,好吗?

      通过输入以下内容创建新迁移

      php artisan make:migration create_jobs_history_table

      现在打开该迁移并添加以下列类型。

      数据库/迁移/ xyz_create_jobs_history_table

      <?php
      
      use Illuminate\Support\Facades\Schema;
      use Illuminate\Database\Schema\Blueprint;
      use Illuminate\Database\Migrations\Migration;
      
      class CreateJobsHistoryTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('jobs_history', function(Blueprint $table) {
      
                  $table->bigIncrements('id');
                  $table->unsignedInteger('user_id');
                  $table->string('job', 40);
                  $table->integer('status')->default(0);
                  $table->timestamps();
      
                  if (Schema::hasColumn('users', 'id'))
                  {
                      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
                  }
      
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::disableForeignKeyConstraints();
              Schema::dropIfExists('jobs_history');
              Schema::enableForeignKeyConstraints();
          }
      }
      

      说明:

      如您所见,我们添加了三种新类型,称为 user_id工作状态

      user_id 引用用户的实际 id。

      job 字段只是职位的描述/名称。

      status 字段表示状态。 0 = 尚未处理,1 = 完成


      现在我们的迁移已经准备好了,让我们为其定义一个新模型:

      app/ JobHistory.php

      <?php
      
      namespace App;
      
      use Illuminate\Database\Eloquent\Model;
      
      class JobHistory extends Model
      {
          protected $table = 'jobs_history';
      
          protected $hidden = [];
      
      }
      

      甜。现在我们可以在应用程序中轻松地与我们的工作历史进行交互。


      现在是创建工作的时候了。让我们使用以下代码来实现:

      app/Jobs/ ProvisionUser.php

      <?php
      
      namespace App\Jobs;
      
      use Illuminate\Bus\Queueable;
      use Illuminate\Queue\SerializesModels;
      use Illuminate\Queue\InteractsWithQueue;
      use Illuminate\Contracts\Queue\ShouldQueue;
      use Illuminate\Foundation\Bus\Dispatchable;
      
      use App\User;
      use App\JobHistory;
      
      class ProvisonUser implements ShouldQueue
      {
          use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
      
          protected $user;
          protected $history;
      
          /**
           * Create a new job instance.
           *
           * @return void
           */
          public function __construct(User $user, JobHistory $history)
          {
              $this->user = $user;
              $this->history = $history;
      
              // Set up our new history record.
      
              $this->history->user_id = $this->user->id;
              $this->history->job = 'Provison User';
              $this->history->status = 0;
      
              $this->history->save();
          }
      
          /**
           * Execute the job.
           *
           * @return void
           */
          public function handle()
          {
              // Do other stuff here....
      
              // Once the job has finished, set history status to 1.
              $this->history->status = 1;
              $this->history->save();
          }
      }
      

      说明:

      这里我们包含了 User 和 JobHistory 模型。 在我们的构造函数中,我们需要两个模型,并且我们设置了一个新的 历史记录。

      实际工作现在与我们的新历史记录同步!

      很好。

      在处理作业时调用handle() 函数。 在这里,我们将状态设置为 1,一旦完成。

      最后只需在控制器中调度作业:

      <?php
      
      namespace App\Http\Controllers;
      
      use Carbon\Carbon;
      
      use App\User;
      use App\JobHistory;
      use App\Jobs\ProvisionUser;
      
      class SomeController extends Controller
      {
          public function provision()
          {
              $user = User::find(1);
      
              $job = (new ProvisionUser($user, new JobHistory))
                  ->delay(Carbon::now()->addMinutes(1));
      
              dispatch($job);
      
              return view('provision');
          }
      }
      

      说明:

      我们将现有用户和新的作业历史传递给构造函数。后 我们调度延迟的工作。

      注意:延迟仅用于演示目的。

      打开您的数据库并检查您的 jobs_history 表。一旦您的作业被调度,相应历史记录的状态应该是 0。一旦工匠队列工作者处理了作业,历史记录状态应该是 1。

      我用 Laravel 5.4 测试了这个设置,并在我的应用程序中使用了相同的逻辑。

      编码愉快!

      【讨论】:

      • 我想将失败的作业置于状态 2。我该如何处理?
      • 在回答我自己的问题时,我想我会将整个代码包装在 try{} 块中的 handle() 函数中,捕获异常并将历史状态设置为 2。我会有兴趣知道你会怎么做。
      • @cartbeforehorse 我就是这样做的。
      • 如果我想修改表以包含我要跟踪的 process_id 等字段怎么办?
      • @Pratik 简单,只需将$table-&gt;integer('process_id'); 添加到CreateJobsHistoryTable 迁移。然后在您的工作文件(或任何其他地方)中,您可以简单地设置新的process_id。例如,在作业文件中,您将使用 $this-&gt;history-&gt;process_id = $process_id_here;
      猜你喜欢
      • 1970-01-01
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      相关资源
      最近更新 更多