PHPackages                             sanmai/round-robin - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. sanmai/round-robin

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

sanmai/round-robin
==================

Minimal round-robin scheduler for PHP Fibers

0.1(3mo ago)00[2 PRs](https://github.com/sanmai/round-robin/pulls)Apache-2.0PHPPHP &gt;=8.2CI passing

Since Jan 19Pushed 1mo agoCompare

[ Source](https://github.com/sanmai/round-robin)[ Packagist](https://packagist.org/packages/sanmai/round-robin)[ GitHub Sponsors](https://github.com/sanmai)[ RSS](/packages/sanmai-round-robin/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (11)Versions (5)Used By (0)

sanmai/round-robin
==================

[](#sanmairound-robin)

A minimal, dependency-free round-robin scheduler for PHP Fibers.

A thin layer for cooperative multitasking:

- no event loop
- no promises
- no futures
- no async/await syntax
- no I/O magic

You write synchronous-looking code, insert `Fiber::suspend()` where it makes sense, and the scheduler resumes fibers in round-robin order.

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

[](#installation)

```
composer require sanmai/round-robin
```

Design goals
------------

[](#design-goals)

- **Explicit control flow** - fibers yield only where you say so
- **Deterministic scheduling** - simple round-robin, no heuristics
- **Shared memory model** - no message passing abstraction
- **Zero dependencies**
- **Tiny surface area** - easy to read, audit, and modify

Non-goals:

- Non-blocking I/O
- Parallelism
- Promises / futures
- Structured concurrency
- Cancellation graphs

If you need those, use [Amp](https://amphp.org/) or [Revolt](https://revolt.run/) instead.

Quality assurance
-----------------

[](#quality-assurance)

This library maintains 100% code coverage and 100% mutation score with [Infection](https://infection.github.io/). Tests cover every line and every mutation.

Basic usage
-----------

[](#basic-usage)

### Creating a scheduler

[](#creating-a-scheduler)

```
use RoundRobin\Scheduler;

$scheduler = new Scheduler();
```

### Adding fibers

[](#adding-fibers)

```
$scheduler->add(new Fiber(function (): void {
    echo "task A: step 1\n";
    Fiber::suspend();
    echo "task A: step 2\n";
}));

$scheduler->add(new Fiber(function (): void {
    echo "task B: step 1\n";
    Fiber::suspend();
    echo "task B: step 2\n";
}));
```

### Running

[](#running)

```
$scheduler->run();
```

Output:

```
task A: step 1
task B: step 1
task A: step 2
task B: step 2

```

Passing data between fibers
---------------------------

[](#passing-data-between-fibers)

Fibers share memory. Use ordinary PHP data structures.

```
$queue = new SplQueue();
$done  = false;

$producer = new Fiber(function () use ($queue, &$done): void {
    foreach ([1, 2, 3] as $value) {
        $queue->enqueue($value);
        Fiber::suspend();
    }
    $done = true;
});

$consumer = new Fiber(function () use ($queue, &$done): void {
    while (!$done || !$queue->isEmpty()) {
        if ($queue->isEmpty()) {
            Fiber::suspend();
            continue;
        }

        echo "got {$queue->dequeue()}\n";
        Fiber::suspend();
    }
});

$scheduler->add($producer);
$scheduler->add($consumer);
$scheduler->run();
```

API
---

[](#api)

### `RoundRobin\Scheduler`

[](#roundrobinscheduler)

#### `add(Fiber $fiber): void`

[](#addfiber-fiber-void)

Adds a fiber to the scheduler.

- Fibers may be added before or after `run()`
- A fiber is scheduled until it terminates

#### `run(): void`

[](#run-void)

Runs all scheduled fibers until all of them terminate.

Behavior:

- starts fibers that have not yet started
- resumes suspended fibers
- skips terminated fibers
- stops when no runnable fibers remain

#### `tick(): bool`

[](#tick-bool)

Runs a single round of scheduling.

Returns:

- `true` if at least one fiber was executed
- `false` if all fibers are terminated

Useful for embedding the scheduler into an existing loop.

How scheduling works
--------------------

[](#how-scheduling-works)

- Only **one fiber runs at a time**
- Fibers must call `Fiber::suspend()` to yield
- The scheduler resumes fibers in FIFO order
- There is **no preemption**
- Blocking I/O blocks the entire process

This is cooperative multitasking by design.

About I/O
---------

[](#about-io)

This library does **not** make I/O non-blocking.

If a fiber performs blocking I/O:

- the entire PHP process blocks
- no other fiber runs

If you need:

- non-blocking file or socket I/O
- readiness notifications
- timers

Use an event loop (e.g. Revolt) or integrate `stream_select()` yourself.

When to use this
----------------

[](#when-to-use-this)

Use this when you need:

- incremental Fiber adoption
- structured long-running logic
- explicit yield points
- deterministic execution
- no framework lock-in

Skip if you need:

- async/await semantics
- transparent non-blocking I/O
- parallelism
- cancellation propagation

License
-------

[](#license)

Apache-2.0

###  Health Score

36

—

LowBetter than 81% of packages

Maintenance93

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

110d ago

### Community

Maintainers

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

---

Top Contributors

[![sanmai](https://avatars.githubusercontent.com/u/139488?v=4)](https://github.com/sanmai "sanmai (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/sanmai-round-robin/health.svg)

```
[![Health](https://phpackages.com/badges/sanmai-round-robin/health.svg)](https://phpackages.com/packages/sanmai-round-robin)
```

###  Alternatives

[alexandresalome/assetic-extra-bundle

Extra feature for Assetic (asset directory)

1811.4k](/packages/alexandresalome-assetic-extra-bundle)

PHPackages © 2026

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