PHPackages                             duyler/parallel - 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. duyler/parallel

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

duyler/parallel
===============

Parallel extension wrapper

01PHPCI passing

Since Nov 25Pushed 7mo agoCompare

[ Source](https://github.com/duyler/parallel)[ Packagist](https://packagist.org/packages/duyler/parallel)[ RSS](/packages/duyler-parallel/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

Parallel Extension Wrapper
==========================

[](#parallel-extension-wrapper)

A modern, type-safe wrapper for PHP's parallel extension providing a clean object-oriented API for parallel programming.

Requirements
------------

[](#requirements)

- PHP 8.4 or higher with ZTS (Zend Thread Safety) enabled
- ext-parallel installed and enabled

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

[](#installation)

```
composer require duyler/parallel
```

Features
--------

[](#features)

- Type-safe interfaces for all components
- Exception handling with custom exception hierarchy
- Clean OOP API following SOLID principles
- Full support for Runtime, Future, Channel, and Events
- Comprehensive test coverage

Quick Start
-----------

[](#quick-start)

### Basic Runtime Usage

[](#basic-runtime-usage)

```
use Duyler\Parallel\Runtime;

$runtime = new Runtime();

$future = $runtime->run(function () {
    return 42;
});

$result = $future->value();
echo $result; // 42

$runtime->close();
```

### Using the Facade

[](#using-the-facade)

```
use Duyler\Parallel\Parallel;

$future = Parallel::run(function ($x, $y) {
    return $x + $y;
}, [10, 20]);

echo $future->value(); // 30
```

### Using Runtime Pool

[](#using-runtime-pool)

```
use Duyler\Parallel\RuntimePool;

$pool = new RuntimePool(maxRuntimes: 4);

$futures = [];
for ($i = 0; $i < 10; $i++) {
    $futures[] = $pool->run(fn($n) => $n * $n, [$i]);
}

foreach ($futures as $future) {
    echo $future->value() . PHP_EOL;
}

$pool->closeAll();
```

### Using Workflow Builder

[](#using-workflow-builder)

```
use Duyler\Parallel\WorkflowBuilder;

$result = (new WorkflowBuilder())
    ->addChannel('input', 10)
    ->addTask('task1', fn($ch) => processTask1($ch), [$inputChannel])
    ->addTask('task2', fn($ch) => processTask2($ch), [$inputChannel])
    ->execute();

$results = $result->waitAll();
$result->closeAll();
```

### Working with Channels

[](#working-with-channels)

```
use Duyler\Parallel\Channel;
use Duyler\Parallel\Runtime;

$channel = Channel::createBuffered(10);

$runtime = new Runtime();
$future = $runtime->run(function ($ch) {
    for ($i = 0; $i < 5; $i++) {
        $ch->send($i * $i);
    }
}, [$channel]);

for ($i = 0; $i < 5; $i++) {
    echo $channel->recv() . PHP_EOL;
}

$runtime->close();
```

### Event Loop

[](#event-loop)

```
use Duyler\Parallel\Events;
use Duyler\Parallel\Runtime;

$runtime1 = new Runtime();
$runtime2 = new Runtime();

$future1 = $runtime1->run(function () {
    return 'task1';
});

$future2 = $runtime2->run(function () {
    return 'task2';
});

$events = new Events();
$events->addFuture('f1', $future1);
$events->addFuture('f2', $future2);

while ($event = $events->poll()) {
    echo "Task {$event->source} completed with: {$event->value}" . PHP_EOL;
}
```

### Named Channels

[](#named-channels)

```
use Duyler\Parallel\Channel;

$channel1 = Channel::make('my-channel', 10);
$channel2 = Channel::open('my-channel');

$channel1->send('Hello from channel 1');
echo $channel2->recv(); // Hello from channel 1
```

API Documentation
-----------------

[](#api-documentation)

### Runtime

[](#runtime)

Creates and manages a parallel execution context.

```
$runtime = new Runtime(?string $bootstrap = null);
$future = $runtime->run(Closure $task, array $argv = []): FutureInterface;
$runtime->close(): void;
$runtime->kill(): void;
```

### RuntimePool

[](#runtimepool)

Manages a pool of Runtime instances for better performance.

```
$pool = new RuntimePool(int $maxRuntimes = 4, ?string $bootstrap = null);
$future = $pool->run(Closure $task, array $argv = []): FutureInterface;
$pool->closeAll(): void;
$pool->killAll(): void;
$pool->getSize(): int;
$pool->getMaxSize(): int;
```

### WorkflowBuilder

[](#workflowbuilder)

Builds complex workflows with multiple tasks and channels.

```
$builder = new WorkflowBuilder();
$builder->withBootstrap(string $bootstrap): WorkflowBuilder;
$builder->withRuntime(RuntimeInterface $runtime): WorkflowBuilder;
$builder->addTask(string $name, Closure $task, array $argv = []): WorkflowBuilder;
$builder->addChannel(string $name, int $capacity = 0): WorkflowBuilder;
$result = $builder->execute(): WorkflowResult;

// WorkflowResult methods
$result->getFuture(string $name): ?FutureInterface;
$result->getChannel(string $name): ?ChannelInterface;
$result->getFutures(): array;
$result->getChannels(): array;
$result->waitAll(): array;
$result->closeAll(): void;
```

### Future

[](#future)

Represents the result of a parallel task.

```
$value = $future->value(): mixed;
$isDone = $future->done(): bool;
$isCancelled = $future->cancelled(): bool;
$cancelled = $future->cancel(): bool;
```

### Channel

[](#channel)

Bidirectional communication channel between tasks.

```
$channel = Channel::create(): ChannelInterface;
$channel = Channel::createBuffered(int $capacity): ChannelInterface;
$channel = Channel::make(string $name, int $capacity = 0): ChannelInterface;
$channel = Channel::open(string $name): ChannelInterface;

$channel->send(mixed $value): void;
$value = $channel->recv(): mixed;
$channel->close(): void;
```

### Events

[](#events)

Event loop for monitoring multiple Futures and Channels.

```
$events = new Events();
$events->addFuture(string $name, FutureInterface $future): void;
$events->addChannel(ChannelInterface $channel): void;
$events->remove(string $name): void;
$events->setBlocking(bool $blocking): void;
$events->setTimeout(int $timeout): void;
$event = $events->poll(): ?Event;
```

### Event

[](#event)

Result from Events::poll().

```
$event->type: Type; // Read, Write, Close, Cancel, Kill, Error
$event->source: string;
$event->object: object; // Future or Channel
$event->value: mixed;
```

Exception Handling
------------------

[](#exception-handling)

All exceptions from ext-parallel are wrapped in custom exception classes:

- `ParallelException` - Base exception class
- `CancellationException` - Task was cancelled
- `ClosedException` - Runtime or Channel was closed
- `ForeignException` - Exception thrown in parallel task
- `IllegalValueException` - Invalid or non-serializable value
- `TimeoutException` - Operation timed out
- `BootstrapException` - Bootstrap file error

```
use Duyler\Parallel\Exception\ForeignException;
use Duyler\Parallel\Runtime;

try {
    $runtime = new Runtime();
    $future = $runtime->run(function () {
        throw new \Exception('Error in task');
    });
    $future->value();
} catch (ForeignException $e) {
    echo "Task failed: " . $e->getMessage();
}
```

Type Safety
-----------

[](#type-safety)

All components implement interfaces for better type safety and testability:

- `RuntimeInterface`
- `FutureInterface`
- `ChannelInterface`
- `EventsInterface`
- `WrapperInterface`

```
use Duyler\Parallel\Contract\RuntimeInterface;

function processTask(RuntimeInterface $runtime): void {
    $future = $runtime->run(function () {
        return 'result';
    });
    echo $future->value();
}
```

Testing
-------

[](#testing)

Run tests using PHPUnit:

```
vendor/bin/phpunit
```

Run static analysis:

```
vendor/bin/psalm
```

Run code style fixer:

```
vendor/bin/php-cs-fixer fix
```

Important Notes
---------------

[](#important-notes)

1. PHP must be compiled with ZTS (Zend Thread Safety) support
2. ext-parallel must be installed and enabled
3. Closures passed to parallel tasks cannot use yield, declare classes, or declare named functions
4. Values passed between tasks must be serializable
5. Always close Runtime instances when done to free resources

Checking ZTS Support
--------------------

[](#checking-zts-support)

```
php -v | grep ZTS
```

If ZTS is not shown, you need to recompile PHP with the `--enable-zts` flag.

License
-------

[](#license)

MIT License. See LICENSE file for details.

Links
-----

[](#links)

- Documentation:
- ext-parallel on PECL:
- ext-parallel on GitHub:

###  Health Score

16

—

LowBetter than 4% of packages

Maintenance45

Moderate activity, may be stable

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity13

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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/69f18edde71f0f80540eda4e097854eddf8eb3390f38ff2ad241b9daaf622281?d=identicon)[milinsky](/maintainers/milinsky)

---

Top Contributors

[![milinsky](https://avatars.githubusercontent.com/u/17288321?v=4)](https://github.com/milinsky "milinsky (9 commits)")

### Embed Badge

![Health badge](/badges/duyler-parallel/health.svg)

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

###  Alternatives

[64robots/nova-fields

A Laravel Nova field.

2831.1M4](/packages/64robots-nova-fields)[romanzipp/dto

A strongly typed Data Transfer Object without magic for PHP 7.4+

1216.5k1](/packages/romanzipp-dto)

PHPackages © 2026

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