/**
  * Process a job.
  *
  * Note: A handler implementation does not need to worry about exception
  * handling and retries. All this is automatically managed by the task
  * runner.
  *
  * @param Job $job
  * @param JobSchedulerInterface $scheduler
  */
 public function fire(Job $job, JobSchedulerInterface $scheduler)
 {
     $jobs = Job::query()->whereIn('state', [JobState::FAILED, JobState::COMPLETE, JobState::CANCELLED]);
     $repeatIn = $job->get('repeatIn', -1);
     // How far back to look
     $days = $job->get('days', 30);
     $jobs->where('created_at', '<', Carbon::now()->subDays($days));
     $job->append('Removing jobs from ' . $days . ' days ago');
     $total = $jobs->count();
     $processed = 0;
     $jobs->chunk(25, function ($jobs) use(&$processed, $total, $job) {
         $processed += count($jobs);
         foreach ($jobs as $staleJob) {
             $staleJob->delete();
         }
         $job->append('Progress: ' . $processed . '/' . $total);
     });
     if ($repeatIn > -1) {
         $scheduler->pushCopy($job, Carbon::now()->addMinutes(max($repeatIn, 1)), Carbon::now()->addMinutes($job->get('expiresAfter', 1440)));
     }
 }