PHPackages                             uginroot/async-symfony-process - 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. uginroot/async-symfony-process

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

uginroot/async-symfony-process
==============================

Execute pool symfony process

v1.0.1(5y ago)113MITPHPPHP &gt;=7.4

Since Jan 5Pushed 5y ago1 watchersCompare

[ Source](https://github.com/uginroot/async-symfony-process)[ Packagist](https://packagist.org/packages/uginroot/async-symfony-process)[ RSS](/packages/uginroot-async-symfony-process/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (2)Used By (0)

Description
===========

[](#description)

Existing libraries work with an early generated pool of processes, this is poorly suited if there are a many processes and is generally not suitable if after the execution of the process it may be necessary to execute an additional one. This library to solve this problem.

This library works on the basis of the [symfony/process](https://symfony.com/doc/current/components/process.html)

Install
=======

[](#install)

```
composer require uginroot/async-symfony-process

```

Use
===

[](#use)

Basic
-----

[](#basic)

In the simplest case, you only need to specify a function that will generate new processes. If the function returns zero instead of a process, then execution will end after all current processes have finished executing.

```
use Symfony\Component\Process\Process;
use Uginroot\AsyncSymfonyProcess\Pool;

$queue = range(1, 10);

$processFactory = static function() use (&$queue):?Process{
    if(count($queue) === 0){
        return null;
    }

    $value = array_shift($queue);
    return Process::fromShellCommandline(sprintf('echo %d', $value));
};

$pool = new Pool();
$pool->setProcessFactory($processFactory);
$pool->execute();
```

Callback
--------

[](#callback)

If you need the result of a process, then you need to set a callback function that will be called after the completion of the process.

```
use Symfony\Component\Process\Process;
use Uginroot\AsyncSymfonyProcess\Pool;
use Uginroot\AsyncSymfonyProcess\ProcessWrapper;

$queue = range(1, 10);
$results = [];

$processFactory = static function() use (&$queue):?Process{
    if(count($queue) === 0){
        return null;
    }

    $value = array_shift($queue);
    return Process::fromShellCommandline(sprintf('echo %d', $value));
};

$callback = static function(ProcessWrapper $processWrapper) use (&$results):void{
    $results[] = (int)$processWrapper->getOutput();
};

$pool = new Pool();
$pool->setProcessFactory($processFactory);
$pool->setCallback($callback);
$pool->execute();
```

Output listener
---------------

[](#output-listener)

If the process is interactive, or you need to somehow react to the errors that the process generates, then you need to set the output listener. It will receive an instance of the current process, output type (Process :: ERR or Process :: OUT) and data generated by the process.

```
use Symfony\Component\Process\InputStream;
use Symfony\Component\Process\Process;
use Uginroot\AsyncSymfonyProcess\Pool;

$queue = range(1, 10);

$processFactory = static function() use (&$queue):?Process{
    if(count($queue) === 0){
        return null;
    }

    $value = array_shift($queue);
    $process = Process::fromShellCommandline(sprintf('echo %d', $value));
    $process->setInput(new InputStream());
    return $process;
};

$outputListener = static function(Process $process, string $type, string $data):void{
    /** @var InputStream $input */
    $input = $process->getInput();
    if($type === Process::ERR){
        $input->write('exit;');
    } elseif ($type === Process::OUT){
        if($data === 'Say yes:'){
            $input->write('yes');
        }
    }
};

$pool = new Pool();
$pool->setProcessFactory($processFactory);
$pool->setOutputListener($outputListener);
$pool->execute();
```

While listener
--------------

[](#while-listener)

To perform any actions at each iteration of the process execution loop, you must set a loop listener.

```
use Symfony\Component\Process\Process;
use Uginroot\AsyncSymfonyProcess\Pool;

$queue = range(1, 10);

$processFactory = static function() use (&$queue):?Process{
    if(count($queue) === 0){
        return null;
    }

    $value = array_shift($queue);
    return Process::fromShellCommandline(sprintf('echo %d', $value));
};

$whileListener = static function():void{
    // pass
};

$pool = new Pool();
$pool->setProcessFactory($processFactory);
$pool->setWhileListener($whileListener);
$pool->execute();
```

Endless execution loop
----------------------

[](#endless-execution-loop)

In order for the process execution cycle not to stop when the process factory returns zero, it is necessary to inform this when configuring the pool. You can react and replenish the list of processes in any of the called functions, for example, in the whileListener. If you need to halt infinite execution, then you need to specify this to the pool.

```
use Symfony\Component\Process\Process;
use Uginroot\AsyncSymfonyProcess\Pool;

$queue = [];
$iteration = 0;

$processFactory = static function() use (&$queue):?Process{
    if(count($queue) === 0){
        return null;
    }

    $value = array_shift($queue);
    return Process::fromShellCommandline(sprintf('echo %d', $value));
};

$whileListener = static function() use (&$queue, &$iteration, &$pool):void{
    $iteration++;

    if($iteration === 20){
        // Will end execution after executed and
        // newly generated processes have finished
        $pool->setIsEternal(false);
    }

    if($iteration % 5 === 0){
        $queue[] = $iteration;
    }
};

$pool = new Pool();
$pool->setProcessFactory($processFactory);
$pool->setWhileListener($whileListener);
$pool->setIsEternal(true);
$pool->execute();
```

Use in class
------------

[](#use-in-class)

```
use Symfony\Component\Process\Process;
use Uginroot\AsyncSymfonyProcess\Pool;
use Uginroot\AsyncSymfonyProcess\ProcessWrapper;

class AsyncProcess
{
    private array $indexes;
    private array $results = [];

    public function __construct() {
        $this->indexes = range(1, 10);
    }

    public function processFactory():?Process
    {
        if(count($this->indexes) === 0){
            return null;
        }

        $index = array_shift($this->indexes);
        return Process::fromShellCommandline(sprintf('echo %d', $index));
    }

    public function processCallback(ProcessWrapper $processWrapper):void
    {
        $index = (int)$processWrapper->getOutput();
        $this->results[] = $index;
    }

    public function run():void
    {
        $pool = new Pool();
        $pool
            ->setProcessFactory([$this, 'processFactory'])
            ->setCallback([$this, 'processCallback'])
            ->execute()
        ;
    }
}
```

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity53

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

1951d ago

### Community

Maintainers

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

---

Top Contributors

[![uginroot](https://avatars.githubusercontent.com/u/2391460?v=4)](https://github.com/uginroot "uginroot (2 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/uginroot-async-symfony-process/health.svg)

```
[![Health](https://phpackages.com/badges/uginroot-async-symfony-process/health.svg)](https://phpackages.com/packages/uginroot-async-symfony-process)
```

###  Alternatives

[symplify/monorepo-builder

Not only Composer tools to build a Monorepo.

5205.3M82](/packages/symplify-monorepo-builder)[spatie/typescript-transformer

This is my package typescript-transformer

3706.5M16](/packages/spatie-typescript-transformer)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k17](/packages/civicrm-civicrm-core)[shivas/versioning-bundle

Symfony application versioning, simple console command to manage version (with providers e.g. git tag) of your application using Semantic Versioning 2.0.0 recommendations

1121.2M1](/packages/shivas-versioning-bundle)[eclipxe/cfdiutils

PHP Common utilities for Mexican CFDI 3.2, 3.3 &amp; 4.0

141129.9k6](/packages/eclipxe-cfdiutils)[shyim/danger-php

Port of danger to PHP

8544.9k](/packages/shyim-danger-php)

PHPackages © 2026

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