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
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');
}
}
// 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:
$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.
$task = Task::query()
->for(self::class)
->whereRelatable($integration)
->where('status', TaskStatus::Completed)
->latest('updated_at')
->first(['id', 'status', 'updated_at']);
Tables
Tasks:
id | relatable_type | relatable_id | user_id | name | status | arguments | result | context | created_at | updated_at |
---|---|---|---|---|---|---|---|---|---|---|
01jb9s3083y13bzw9gqq8s4rc9 | integration | 1 | Domain\Tasks\Jobs\TestJob | completed | {"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:41 | 2024-10-28 14:39:41 |
Task events:
id | task_id | status | context | trace_id | created_at | updated_at |
---|---|---|---|---|---|---|
1 | 01jb9s3083y13bzw9gqq8s4rc9 | pending | [] | {"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"} | 2024-10-28 14:39:41 | 2024-10-28 14:39:41 |
2 | 01jb9s3083y13bzw9gqq8s4rc9 | started | [] | {"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"} | 2024-10-28 14:39:41 | 2024-10-28 14:39:41 |
3 | 01jb9s3083y13bzw9gqq8s4rc9 | progressed | {"former_employee_count": 55, "purged_employee_count": 3} | {"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"} | 2024-10-28 14:39:41 | 2024-10-28 14:39:41 |
4 | 01jb9s3083y13bzw9gqq8s4rc9 | progressed | {"purged_employee_count": 50} | {"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"} | 2024-10-28 14:39:41 | 2024-10-28 14:39:41 |
5 | 01jb9s3083y13bzw9gqq8s4rc9 | progressed | {"almost_fatal": true} | {"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"} | 2024-10-28 14:39:41 | 2024-10-28 14:39:41 |
6 | 01jb9s3083y13bzw9gqq8s4rc9 | completed | [] | {"trace_id": "8d3be98c-6513-4c16-a701-06752493ea63"} | 2024-10-28 14:39:41 | 2024-10-28 14:39:41 |