You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+50-1Lines changed: 50 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,6 +24,8 @@ Under a row of queue KPIs, the workspace is organised into four areas:
24
24
-**Insights** — an incident timeline (long waits, job failures, supervisor deployments), monitored tags, and recent batches.
25
25
-**Horizon controls** — pause and continue the master supervisors or an individual supervisor.
26
26
27
+
Selecting a Redis queue in the Inspector also exposes queue pause/resume controls and safe cancellation actions for its pending or running jobs.
28
+
27
29
The active workspace, graph/table mode, time window, queue filter, and selected node are reflected in the query string, so operational views can be shared directly.
28
30
29
31
To explore without a live queue, run `composer serve:demo`. This boots the workbench application with generated demo data and seeds a handful of failed jobs you can open and retry.
@@ -54,11 +56,14 @@ Live-flow behaviour is configured via `config/horizonxflow.php`:
54
56
|`GET /horizon/api/flow/queue-jobs`| Recent jobs + job-classes for a single queue (`?key=driver:connection:name`). |
|`GET /horizon/api/flow/incidents`| Recent incidents (long waits, job failures, supervisor deployments) for the Insights timeline. |
59
+
|`POST /horizon/api/flow/queues/pause`| Pause one Redis queue while retaining pending and newly dispatched jobs. |
60
+
|`POST /horizon/api/flow/queues/resume`| Resume processing one paused Redis queue. |
61
+
|`POST /horizon/api/jobs/{id}/cancel`| Cancel a pending job or request cooperative cancellation of a running job. |
57
62
58
63
### Abilities
59
64
60
65
-`viewHorizon` — required to enter the dashboard (existing Horizon gate).
61
-
-`controlHorizon` — required for mutation endpoints (`POST /jobs/retry/{id}`, `POST /masters/{action}`, `POST /supervisors/{name}/{action}`) and for `GET /jobs/failed/{id}/parameters`, which backs retrying with edited parameters. When the gate is undefined, mutations are only allowed in `local` and `testing` environments; everywhere else, define the gate in `HorizonApplicationServiceProvider::gate()` to enable destructive actions for a trusted subset of users.
66
+
-`controlHorizon` — required for mutation endpoints (`POST /jobs/retry/{id}`, `POST /jobs/{id}/cancel`, `POST /flow/queues/{action}`, `POST /masters/{action}`, `POST /supervisors/{name}/{action}`) and for `GET /jobs/failed/{id}/parameters`, which backs retrying with edited parameters. When the gate is undefined, mutations are only allowed in `local` and `testing` environments; everywhere else, define the gate in `HorizonApplicationServiceProvider::gate()` to enable destructive actions for a trusted subset of users.
62
67
63
68
### Environment Variables
64
69
@@ -70,6 +75,50 @@ Live-flow behaviour is configured via `config/horizonxflow.php`:
The Live Flow Inspector can pause an individual Redis queue and cancel one pending or running job. These controls deliberately preserve Laravel's queue safety boundaries:
81
+
82
+
- Pausing a queue does not reject dispatches or kill workers. A job already running finishes, while pending and newly dispatched jobs remain queued until the queue is resumed.
83
+
- Cancelling a pending job atomically removes its exact payload from the ready list or delayed set. If a worker reserves it first, HorizonXFlow records a cooperative cancellation request instead of reporting a false success.
84
+
- A running worker process is never force-killed. Side effects already performed by a job cannot be rolled back by HorizonXFlow.
85
+
- Cancelled jobs remain visible in the Inspector with their cancellation time and operator identifier. Repeated requests are idempotent, and completed or failed jobs return `409 Conflict`.
86
+
87
+
Mutation routes use the `controlHorizon` ability described above. Queue connection and queue names are validated server-side, raw job payloads are never accepted from or returned to the control UI, and every destructive action has an explicit confirmation step.
88
+
89
+
### Cooperative cancellation checkpoints
90
+
91
+
A running job must opt in before it can stop between units of work. Add `InteractsWithCancellation` and return from `handle()` when a checkpoint acknowledges the request:
92
+
93
+
```php
94
+
use Illuminate\Contracts\Queue\ShouldQueue;
95
+
use Illuminate\Foundation\Queue\InteractsWithQueue;
96
+
use Laravel\Horizon\Concerns\InteractsWithCancellation;
97
+
98
+
class SendCampaignMail implements ShouldQueue
99
+
{
100
+
use InteractsWithQueue;
101
+
use InteractsWithCancellation;
102
+
103
+
public function handle(): void
104
+
{
105
+
foreach ($this->recipients as $recipient) {
106
+
if ($this->cancelIfRequested()) {
107
+
return;
108
+
}
109
+
110
+
$this->sendTo($recipient);
111
+
}
112
+
}
113
+
}
114
+
```
115
+
116
+
Place checkpoints before idempotent units of work. A cancellation requested while a single non-interruptible call is executing—for example, an SMTP hand-off—takes effect only after that call returns and the next checkpoint is reached.
117
+
118
+
Queue and job controls currently support Redis queues. Database queues remain observable in Live Flow but do not expose these mutation controls.
119
+
120
+
When `flow.source` is `mock`, the Inspector exposes the same controls as a session-only visual simulation. Pausing, cancelling, and retrying update only the browser state and never call a mutation endpoint or change Redis. Mock failures are available from Live Flow's queue Inspector and Activity workspace; Horizon's separate Failed Jobs page continues to show only real failed jobs.
121
+
73
122
## Retry With Parameters
74
123
75
124
A failed job usually fails because of what it was handed: a wrong path, a batch size that was too large, a flag left on. Horizon can only push that same job back onto the queue unchanged, so the normal fix is a tinker session or a one-off command. HorizonXFlow lets you change the arguments and retry from the dashboard instead.
0 commit comments