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

34

—

LowBetter than 77% of packages

Maintenance86

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 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

116d 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

[phannaly/php-datetime-khmer

The PHP library for convert datetime to Khmer

1510.3k](/packages/phannaly-php-datetime-khmer)[moosend/website-tracking

By installing the Moosend PHP Tracking library you are can track page views, product views, add to cart events and successful purchases. You can later use these details to segment your user base, run automations, check how successful your latest promo has been and how many conversions your landing page has led to.

1020.9k1](/packages/moosend-website-tracking)

PHPackages © 2026

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