PHPackages                             mathieualbanese/horizon-longtask - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. mathieualbanese/horizon-longtask

ActiveLibrary[Queues &amp; Workers](/categories/queues)

mathieualbanese/horizon-longtask
================================

Laravel library for managing long tasks with horizon

v1.0.2(1y ago)017MITPHPPHP ^8.0

Since Feb 14Pushed 1y ago1 watchersCompare

[ Source](https://github.com/mathieualbanese/horizon-longtask)[ Packagist](https://packagist.org/packages/mathieualbanese/horizon-longtask)[ RSS](/packages/mathieualbanese-horizon-longtask/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (4)Used By (0)

Laravel Horizon Long Task
=========================

[](#laravel-horizon-long-task)

A Laravel package for managing long-running tasks with Laravel Horizon.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require mathieualbanese/horizon-longtask
```

Configuration
-------------

[](#configuration)

You can publish the config file with:

```
php artisan vendor:publish --provider="MathieuAlbanese\HorizonLongTask\Providers\HorizonLongTaskServiceProvider"
```

Usage
-----

[](#usage)

This package provides a trait `HorizonJobManagerTrait` that helps you manage long-running jobs in Laravel Horizon. Here's how to use it:

1. First, use the trait in your job class:

```
use MathieuAlbanese\HorizonLongTask\Traits\HorizonJobManagerTrait;

class YourLongRunningJob implements ShouldQueue
{
    use HorizonJobManagerTrait;

    public function handle()
    {
        // 1. set the lock key name
        $this->setLockKeyName('your-job-lock-key');

        // 2. check if the job is already running with the same key name
        if ($this->isRunning()) {
            die('JOB IS ALREADY RUNNING - killed Process');
            exit();
        }

        //3. start the job
        $this->startJob();

        try {
            // 4. Your long-running logic here
            while (true) {
                // Do some work...

                // 5. Refresh the job lock to prevent timeout
                $this->updateReservedAt();

                //OR
                if (!($this->job instanceof SyncJob))
                    $this->updateReservedAt();
                //this code block is better than the other one because it will not update the reserved_at timestamp if the job is a sync job

                // 6. Optional: Check if the job is still running
                if (!$this->isRunning()) {
                    // Job was terminated externally
                    break;
                }
            }
        } finally {
            // 7. Always end the job properly
            $this->endJob();
            $this->delete(); // Delete the job from the queue
        }
    }
}

### Key Features

- **Lock Management**: The trait provides methods to manage job locks using Redis

  - `setLockKeyName()`: Set a unique lock key for your job
  - `startJob()`: Initialize the job and set the lock
  - `refreshLock()`: Manually refresh the job lock
  - `endJob()`: Clean up the job lock
  - `isRunning()`: Check if the job is still running

- **Automatic Timeout Prevention**:
  - `updateReservedAt()`: Automatically updates the job's reserved_at timestamp to prevent timeout
  - The refresh time is calculated based on your Redis queue configuration (`queue.connections.redis.retry_after`)

### Configuration

The package uses the following configuration values from `config/horizon-longtask.php`:

```php
return [
    'enable_logging' => false,
    'redis_separator' => ':'

];
```

### Best Practices

[](#best-practices)

1. Always use a unique lock key for each job instance
2. Call `startJob()` at the beginning of your job
3. Call `updateReservedAt()` regularly in long-running loops
4. Use `isRunning()` to check if the job should continue
5. Always call `endJob()` when the job is complete (preferably in a `finally` block)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance43

Moderate activity, may be stable

Popularity6

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

452d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4071fce097a03b9cd9c6a6c072e201980ae753575c18d9843f41a9edd5122bf7?d=identicon)[mathieu.albanese](/maintainers/mathieu.albanese)

### Embed Badge

![Health badge](/badges/mathieualbanese-horizon-longtask/health.svg)

```
[![Health](https://phpackages.com/badges/mathieualbanese-horizon-longtask/health.svg)](https://phpackages.com/packages/mathieualbanese-horizon-longtask)
```

###  Alternatives

[mpbarlow/laravel-queue-debouncer

A wrapper job for debouncing other queue jobs.

63714.4k1](/packages/mpbarlow-laravel-queue-debouncer)[eyewitness/eye

Eyewitness.io client for Laravel 5 applications

116151.8k](/packages/eyewitness-eye)[convenia/pigeon

3233.0k](/packages/convenia-pigeon)[baklysystems/laravel-chat-messenger

Laravel chat package

121.8k](/packages/baklysystems-laravel-chat-messenger)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
