Skip to content

Tasks

What they are/do

A task is a database record that holds information about a certain thing you want to track. It's different from logging because its progress and data should be shown to the user in the application. So it's not (just) for debugging purposes. It works across requests and jobs and can be used for any command or job, or even manual tracking. Each task has multiple events that are stored in another table, allowing us to display a timeline of its progress along with some data.

Examples

  • Showing information about an API call to the user
  • Displaying an error to the user when an asynchronous job failed
  • Tracking complex jobs and batches for a single task

How to use them

Tracking jobs

Jobs are automatically tracked if you add the IsTasked interface and Taskable trait. For now, 1 job = 1 task, but feel free to extend.

php
<?php

declare(strict_types=1);

namespace Domain\Tasks\Jobs;

use Domain\Tasks\Concerns\IsTasked;
use Domain\Tasks\Concerns\Taskable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use RuntimeException;

class TestJob implements ShouldQueue, IsTasked
{
    use Queueable;
    use Taskable;

    public function __invoke(): void
    {
        // A `progressed` event will be logged with the given data
        // and the task `result` will be updated with the values.
        $this->task()->progress([
            'former_employee_count' => 55,
            'purged_employee_count' => 3,
        ]);

        // Any context is added to the main task as well as every status change
        Context::add('additional', 'context');

        // Another `progressed` event will be logged with just this data,
        // but the task `result` data values will be merged/overwritten.
        $this->task()->progress(['purged_employee_count' => 50]);
        
        $this->task()->progress(['almost_fatal' => true]);

        // A failed task event will be logged
        throw new RuntimeException('Simulated job failure');
    }
}
php
// No requirements when dispatching jobs
TestJob::dispatch();

// But you can link its task to a model for easy retrieval later
dispatch((new TestJob)->trackInRelationTo($model));

Manual tracking

You can track anything manually:

php
$task = Task::add(name: 'myjob');

$task->start();
$task->pause();
$task->progress($data);
$task->fail();
$task->cancel();
$task->complete();

Querying

You'd usually retrieve the latest task of a job or for a given name, and by a related model.

php
$task = Task::query()
    ->for(self::class)
    ->whereRelatable($integration)
    ->where('status', TaskStatus::Completed)
    ->latest('updated_at')
    ->first(['id', 'status', 'updated_at']);

Tables

Tasks:

idrelatable_typerelatable_iduser_idnamestatusargumentsresultcontextcreated_atupdated_at
01jb9s3083y13bzw9gqq8s4rc9integration1Domain\Tasks\Jobs\TestJobcompleted{"int": 42, "string": "string", "integration": {"id": 1, "type": "integration"}}{"almost_fatal": true, "former_employee_count": 55, "purged_employee_count": 50}{"job": {"uuid": "ceed7e87-9a3a-4bbe-a828-f78c22025352", "queue": null}, "trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"}2024-10-28 14:39:412024-10-28 14:39:41

Task events:

idtask_idstatuscontexttrace_idcreated_atupdated_at
101jb9s3083y13bzw9gqq8s4rc9pending[]{"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"}2024-10-28 14:39:412024-10-28 14:39:41
201jb9s3083y13bzw9gqq8s4rc9started[]{"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"}2024-10-28 14:39:412024-10-28 14:39:41
301jb9s3083y13bzw9gqq8s4rc9progressed{"former_employee_count": 55, "purged_employee_count": 3}{"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"}2024-10-28 14:39:412024-10-28 14:39:41
401jb9s3083y13bzw9gqq8s4rc9progressed{"purged_employee_count": 50}{"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"}2024-10-28 14:39:412024-10-28 14:39:41
501jb9s3083y13bzw9gqq8s4rc9progressed{"almost_fatal": true}{"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"}2024-10-28 14:39:412024-10-28 14:39:41
601jb9s3083y13bzw9gqq8s4rc9completed[]{"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"}2024-10-28 14:39:412024-10-28 14:39:41