PHPackages                             danog/loop - 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. danog/loop

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

danog/loop
==========

Loop abstraction for AMPHP.

1.1.1(2y ago)9348.4k—1.6%10[1 issues](https://github.com/danog/loop/issues)4MITPHPPHP &gt;=8.1CI failing

Since Jul 24Pushed 1y agoCompare

[ Source](https://github.com/danog/loop)[ Packagist](https://packagist.org/packages/danog/loop)[ Docs](https://github.com/danog/loop)[ GitHub Sponsors](https://github.com/danog)[ RSS](/packages/danog-loop/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (6)Dependencies (5)Versions (10)Used By (4)

Loop
====

[](#loop)

[![codecov](https://camo.githubusercontent.com/d9b8831c134d368728fef1c96c04b8885c601d1a22be8b0aeea5f56a63d65da7/68747470733a2f2f636f6465636f762e696f2f67682f64616e6f672f6c6f6f702f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/danog/loop)[![Mutation testing badge](https://camo.githubusercontent.com/beb7c21329c9dbbc2b3d665f69d5729b026084f22868492cda86deab9f268c37/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f7374796c653d666c61742675726c3d687474707325334125324625324662616467652d6170692e737472796b65722d6d757461746f722e696f2532466769746875622e636f6d25324664616e6f672532466c6f6f702532466d6173746572)](https://dashboard.stryker-mutator.io/reports/github.com/danog/loop/master)[![Psalm coverage](https://camo.githubusercontent.com/85e4540dddb1845ba3d899e2f94d707049a450777b1c4f91856c444d92844707/68747470733a2f2f73686570686572642e6465762f6769746875622f64616e6f672f6c6f6f702f636f7665726167652e737667)](https://shepherd.dev/github/danog/loop)[![Psalm level 1](https://camo.githubusercontent.com/a0bbee577c4d039a28dd4a607a7ba786ef8ebad307b2c8726ec1c0fa92a1f992/68747470733a2f2f73686570686572642e6465762f6769746875622f64616e6f672f6c6f6f702f6c6576656c2e737667)](https://shepherd.dev/github/danog/loop)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)

`danog/loop` provides a set of powerful async loop APIs based on [amphp](https://amphp.org) for executing operations periodically or on demand, in background loops a-la threads.

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

[](#installation)

```
composer require danog/loop
```

API
---

[](#api)

- Basic
    - [GenericLoop](#genericloop)
    - [PeriodicLoop](#periodicloop)
- Advanced
    - [Loop](#loop)

### Loop

[](#loop-1)

[Class](https://github.com/danog/loop/blob/master/lib/Loop.php) - [Example](https://github.com/danog/loop/blob/master/examples/Loop.php)

A loop capable of running in background (asynchronously) the code contained in the `loop` function.
Implements pause and resume functionality, and can be stopped from the outside or from the inside.

API:

```
namespace danog\Loop;

abstract class Loop
{
    /**
     * Stop the loop.
     */
    public const STOP;
    /**
     * Pause the loop.
     */
    public const PAUSE;
    /**
     * Rerun the loop.
     */
    public const CONTINUE;

    /**
     * Loop body.
     *
     * The return value can be:
     * A number - the loop will be paused for the specified number of seconds
     * Loop::STOP - The loop will stop
     * Loop::PAUSE - The loop will pause forever (or until loop is `resume()`'d
     *                        from outside the loop)
     * Loop::CONTINUE - Return this if you want to rerun the loop immediately
     *
     * The loop can be stopped from the outside by using stop().
     * @return float|Loop::STOP|Loop::PAUSE|Loop::CONTINUE
     */
    abstract protected function loop(): ?float;

    /**
     * Loop name, useful for logging.
     */
    abstract public function __toString(): string;

    /**
     * Start the loop.
     *
     * Returns false if the loop is already running.
     */
    public function start(): bool;
    /**
     * Resume the loop.
     *
     * If resume is called multiple times, and the event loop hasn't resumed the loop yet,
     * the loop will be resumed only once, not N times for every call.
     *
     * @param bool $postpone If true, multiple resumes will postpone the resuming to the end of the callback queue instead of leaving its position unchanged.
     *
     * @return bool Returns false if the loop is not paused.
     */
    public function resume(bool $postpone = false): bool;
    /**
     * Stops loop.
     *
     * Returns false if the loop is not running.
     */
    public function stop(): bool;

    /**
     * Check whether loop is running.
     */
    public function isRunning(): bool;
    /**
     * Check whether loop is paused.
     */
    public function isPaused(): bool;

    /**
     * Report pause, can be overriden for logging.
     *
     * @param float $timeout Pause duration, 0 = forever
     */
    protected function reportPause(float $timeout): void;

    /**
     * Signal that loop was started.
     */
    protected function startedLoop(): void;
    /**
     * Signal that loop has exited.
     */
    protected function exitedLoop(): void;
}
```

### GenericLoop

[](#genericloop)

[Class](https://github.com/danog/loop/blob/master/lib/GenericLoop.php) - [Example](https://github.com/danog/loop/blob/master/examples/GenericLoop.php)

If you want a simpler way to use the `Loop`, you can use the GenericLoop.

```
namespace danog\Loop;

class GenericLoop extends Loop
{
    /**
     * Constructor.
     *
     * The return value of the callable can be:
     * * A number - the loop will be paused for the specified number of seconds
     * * GenericLoop::STOP - The loop will stop
     * * GenericLoop::PAUSE - The loop will pause forever (or until loop is `resume()`'d
     *                        from outside the loop)
     * * GenericLoop::CONTINUE - Return this if you want to rerun the loop immediately
     *
     * If the callable does not return anything,
     * the loop will behave is if GenericLoop::PAUSE was returned.
     *
     * The loop can be stopped from the outside by using stop().
     *
     * @param callable(static):?float $callable Callable to run
     * @param string   $name     Loop name
     */
    public function __construct(callable $callable, private string $name);
    /**
     * Get loop name, provided to constructor.
     */
    public function __toString(): string;
}
```

### PeriodicLoop

[](#periodicloop)

[Class](https://github.com/danog/loop/blob/master/lib/PeriodicLoop.php) - [Example](https://github.com/danog/loop/blob/master/examples/PeriodicLoop.php)

If you simply want to execute an action every N seconds, [PeriodicLoop](https://github.com/danog/MadelineProto/blob/master/src/danog/MadelineProto/Loop/Generic/PeriodicLoop.php) is the way to go.

```
namespace danog\Loop;

class PeriodicLoop extends GenericLoop
{
    /**
     * Constructor.
     *
     * Runs a callback at a periodic interval.
     *
     * The loop can be stopped from the outside by calling stop()
     * and from the inside by returning `true`.
     *
     * @param callable(static):bool $callback Callable to run
     * @param string   $name     Loop name
     * @param ?float   $interval Loop interval; if null, pauses indefinitely or until `resume()` is called.
     */
    public function __construct(callable $callback, string $name, ?float $interval)
    /**
     * Get name of the loop, passed to the constructor.
     *
     * @return string
     */
    public function __toString(): string;
}
```

###  Health Score

45

—

FairBetter than 93% of packages

Maintenance31

Infrequent updates — may be unmaintained

Popularity45

Moderate usage in the ecosystem

Community17

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 98% of commits — single point of failure

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 ~145 days

Recently: every ~62 days

Total

9

Last Release

961d ago

Major Versions

0.1.1 → 1.0.02023-01-24

PHP version history (2 changes)0.1.0PHP &gt;=7.1

1.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/e1586cd637028e4f8da85f2252b8f4b81e05f6b17a93f92c34ff064dd838e6bb?d=identicon)[danog](/maintainers/danog)

---

Top Contributors

[![danog](https://avatars.githubusercontent.com/u/7339644?v=4)](https://github.com/danog "danog (100 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (2 commits)")

---

Tags

asyncasynchronousconcurrentmulti-threadingmulti-processing

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/danog-loop/health.svg)

```
[![Health](https://phpackages.com/badges/danog-loop/health.svg)](https://phpackages.com/packages/danog-loop)
```

###  Alternatives

[amphp/parallel

Parallel processing component for Amp.

84746.2M74](/packages/amphp-parallel)[amphp/amp

A non-blocking concurrency framework for PHP applications.

4.4k123.4M323](/packages/amphp-amp)[revolt/event-loop

Rock-solid event loop for concurrent PHP applications.

91943.6M138](/packages/revolt-event-loop)[danog/ipc

IPC component for Amp.

11680.1k6](/packages/danog-ipc)[amphp/sync

Non-blocking synchronization primitives for PHP based on Amp and Revolt.

18852.8M39](/packages/amphp-sync)[amphp/serialization

Serialization tools for IPC and data storage in PHP.

13451.1M18](/packages/amphp-serialization)

PHPackages © 2026

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