diff --git a/resources/boost/skills/configure-horizon/SKILL.blade.php b/resources/boost/skills/configure-horizon/SKILL.blade.php new file mode 100644 index 00000000..d98dcb7f --- /dev/null +++ b/resources/boost/skills/configure-horizon/SKILL.blade.php @@ -0,0 +1,98 @@ +--- +name: configuring-horizon +description: "Configures Laravel Horizon for Redis queue management. Activate when the user explicitly mentions Horizon by name. Covers Horizon installation, supervisor configuration, worker processes, dashboard authorization, auto-scaling, balancing strategies, job monitoring, metrics, tags, and notifications. Also applies when troubleshooting Horizon-specific issues such as blank metrics, LongWaitDetected alerts, or misconfigured Horizon workers. Do NOT activate for generic queue, Redis, or job monitoring questions that do not mention Horizon." +license: MIT +metadata: + author: laravel +--- +@php +/** @var \Laravel\Boost\Install\GuidelineAssist $assist */ +@endphp +# Horizon Configuration + +## When to Apply + +Activate this skill when the user explicitly mentions **Horizon** by name. Examples: + +- Installing or configuring Horizon +- Setting up Horizon supervisors or worker processes +- Restricting access to the Horizon dashboard +- Configuring Horizon auto-scaling or balancing strategies +- Setting up Horizon job monitoring, tags, metrics, or notifications +- Troubleshooting Horizon blank metrics or LongWaitDetected alerts + +Do NOT activate for generic queue workers, Redis configuration, or job monitoring questions that do not mention Horizon. + +## Documentation + +Use `search-docs` for detailed Horizon patterns and documentation covering configuration, supervisors, balancing, dashboard authorization, tags, notifications, metrics, and deployment. + +For deeper guidance on specific topics, read the relevant reference file before implementing: + +- `references/supervisors.md` covers supervisor blocks, balancing strategies, multi-queue setups, and auto-scaling +- `references/notifications.md` covers LongWaitDetected alerts, notification routing, and the `waits` config +- `references/tags.md` covers job tagging, dashboard filtering, and silencing noisy jobs +- `references/metrics.md` covers the blank metrics dashboard, snapshot scheduling, and retention config + +## Basic Usage + +### Installation + +```bash +{{ $assist->artisanCommand('horizon:install') }} +``` + +### Supervisor Configuration + +Define supervisors in `config/horizon.php`. The `environments` array merges into `defaults` and does not replace the whole supervisor block: + +@boostsnippet("Supervisor Config", "php") +'defaults' => [ + 'supervisor-1' => [ + 'connection' => 'redis', + 'queue' => ['default'], + 'balance' => 'auto', + 'minProcesses' => 1, + 'maxProcesses' => 10, + 'tries' => 3, + ], +], + +'environments' => [ + 'production' => [ + 'supervisor-1' => ['maxProcesses' => 10, 'balanceCooldown' => 3], + ], + 'local' => [ + 'supervisor-1' => ['maxProcesses' => 2], + ], +], +@endboostsnippet + +### Dashboard Authorization + +Restrict access in `App\Providers\HorizonServiceProvider`: + +@boostsnippet("Dashboard Gate", "php") +protected function gate(): void +{ + Gate::define('viewHorizon', function (User $user) { + return $user->is_admin; + }); +} +@endboostsnippet + +## Verification + +1. Run `{{ $assist->artisanCommand('horizon') }}` and visit `/horizon` +2. Confirm dashboard access is restricted as expected +3. Check that metrics populate after scheduling `horizon:snapshot` + +## Common Pitfalls + +- Horizon only works with the Redis queue driver. Other drivers such as database and SQS are not supported. +- Redis Cluster is not supported. Horizon requires a standalone Redis connection. +- Always check `config/horizon.php` before making changes to understand the current supervisor and environment configuration. +- The `environments` array overrides only the keys you specify. It merges into `defaults` and does not replace it. +- The timeout chain must be ordered: job `timeout` less than supervisor `timeout` less than `retry_after`. The wrong order can cause jobs to be retried before Horizon finishes timing them out. +- The metrics dashboard stays blank until `horizon:snapshot` is scheduled. Running `php artisan horizon` alone does not populate metrics. +- Always use `search-docs` for the latest Horizon documentation rather than relying on this skill alone. diff --git a/resources/boost/skills/configure-horizon/references/metrics.md b/resources/boost/skills/configure-horizon/references/metrics.md new file mode 100644 index 00000000..6ce61013 --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/metrics.md @@ -0,0 +1,21 @@ +# Metrics & Snapshots + +## Where to Find It + +Search with `search-docs`: +- `"horizon metrics snapshot"` for the snapshot command and scheduling +- `"horizon trim snapshots"` for retention configuration + +## What to Watch For + +### Metrics dashboard stays blank until `horizon:snapshot` is scheduled + +Running `php artisan horizon` does not populate metrics automatically. The metrics graph is built from snapshots, so `php artisan horizon:snapshot` must be scheduled to run every 5 minutes via Laravel's scheduler. + +### Register the snapshot in the scheduler rather than running it manually + +A single manual run populates the dashboard momentarily but will not keep it updated. Search `"horizon metrics snapshot"` for the exact scheduler registration syntax, which differs between Laravel 10 and 11+. + +### `metrics.trim_snapshots` is a snapshot count, not a time duration + +The `trim_snapshots.job` and `trim_snapshots.queue` values in `config/horizon.php` are counts of snapshots to keep, not minutes or hours. With the default of 24 snapshots at 5-minute intervals, that provides 2 hours of history. Increase the value to retain more history at the cost of Redis memory usage. diff --git a/resources/boost/skills/configure-horizon/references/notifications.md b/resources/boost/skills/configure-horizon/references/notifications.md new file mode 100644 index 00000000..d6d3feed --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/notifications.md @@ -0,0 +1,21 @@ +# Notifications & Alerts + +## Where to Find It + +Search with `search-docs`: +- `"horizon notifications"` for Horizon's built-in notification routing helpers +- `"horizon long wait detected"` for LongWaitDetected event details + +## What to Watch For + +### `waits` in `config/horizon.php` controls the LongWaitDetected threshold + +The `waits` array (e.g., `'redis:default' => 60`) defines how many seconds a job can wait in a queue before Horizon fires a `LongWaitDetected` event. This value is set in the config file, not in Horizon's notification routing. If alerts are firing too often or too late, adjust `waits` rather than the routing configuration. + +### Use Horizon's built-in notification routing in `HorizonServiceProvider` + +Configure notifications in the `boot()` method of `App\Providers\HorizonServiceProvider` using `Horizon::routeMailNotificationsTo()`, `Horizon::routeSlackNotificationsTo()`, or `Horizon::routeSmsNotificationsTo()`. Horizon already wires `LongWaitDetected` to its notification sender, so the documented setup is notification routing rather than manual listener registration. + +### Failed job alerts are separate from Horizon's documented notification routing + +Horizon's 12.x documentation covers built-in long-wait notifications. Do not assume the docs provide a `JobFailed` listener example in `HorizonServiceProvider`. If a user needs failed job alerts, treat that as custom queue event handling and consult the queue documentation instead of Horizon's notification-routing API. diff --git a/resources/boost/skills/configure-horizon/references/supervisors.md b/resources/boost/skills/configure-horizon/references/supervisors.md new file mode 100644 index 00000000..b71285cf --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/supervisors.md @@ -0,0 +1,27 @@ +# Supervisor & Balancing Configuration + +## Where to Find It + +Search with `search-docs` before writing any supervisor config, as option names and defaults change between Horizon versions: +- `"horizon supervisor configuration"` for the full options list +- `"horizon balancing strategies"` for auto, simple, and false modes +- `"horizon autoscaling workers"` for autoScalingStrategy details +- `"horizon environment configuration"` for the defaults and environments merge + +## What to Watch For + +### The `environments` array merges into `defaults` rather than replacing it + +The `defaults` array defines the complete base supervisor config. The `environments` array patches it per environment, overriding only the keys listed. There is no need to repeat every key in each environment block. A common pattern is to define `connection`, `queue`, `balance`, `autoScalingStrategy`, `tries`, and `timeout` in `defaults`, then override only `maxProcesses`, `balanceMaxShift`, and `balanceCooldown` in `production`. + +### Use separate named supervisors to enforce queue priority + +Horizon does not enforce queue order when using `balance: auto` on a single supervisor. The `queue` array order is ignored for load balancing. To process `notifications` before `default`, use two separately named supervisors: one for the high-priority queue with a higher `maxProcesses`, and one for the low-priority queue with a lower cap. The docs include an explicit note about this. + +### Use `balance: false` to keep a fixed number of workers on a dedicated queue + +Auto-balancing suits variable load, but if a queue should always have exactly N workers such as a video-processing queue limited to 2, set `balance: false` and `maxProcesses: 2`. Auto-balancing would scale it up during bursts, which may be undesirable. + +### Set `balanceCooldown` to prevent rapid worker scaling under bursty load + +When using `balance: auto`, the supervisor can scale up and down rapidly under bursty load. Set `balanceCooldown` to the number of seconds between scaling decisions, typically 3 to 5, to smooth this out. `balanceMaxShift` limits how many processes are added or removed per cycle. diff --git a/resources/boost/skills/configure-horizon/references/tags.md b/resources/boost/skills/configure-horizon/references/tags.md new file mode 100644 index 00000000..8234e4ad --- /dev/null +++ b/resources/boost/skills/configure-horizon/references/tags.md @@ -0,0 +1,21 @@ +# Tags & Silencing + +## Where to Find It + +Search with `search-docs`: +- `"horizon tags"` for the tagging API and auto-tagging behaviour +- `"horizon silenced jobs"` for the `silenced` and `silenced_tags` config options + +## What to Watch For + +### Eloquent model jobs are tagged automatically without any extra code + +If a job's constructor accepts Eloquent model instances, Horizon automatically tags the job with `ModelClass:id` such as `App\Models\User:42`. These tags are filterable in the dashboard without any changes to the job class. Only add a `tags()` method when custom tags beyond auto-tagging are needed. + +### `silenced` hides jobs from the dashboard completed list but does not stop them from running + +Adding a job class to the `silenced` array in `config/horizon.php` removes it from the completed jobs view. The job still runs normally. This is a dashboard noise-reduction tool, not a way to disable jobs. + +### `silenced_tags` hides all jobs carrying a matching tag from the completed list + +Any job carrying a matching tag string is hidden from the completed jobs view. This is useful for silencing a category of jobs such as all jobs tagged `notifications`, rather than silencing specific classes.