An async process dispatcher for Amp.

Overview

process

Code Coverage Release License

This package provides an asynchronous process dispatcher that works on all major platforms (including Windows).

As Windows pipes are file handles and do not allow non-blocking access, this package makes use of a process wrapper, that provides access to these pipes via sockets. On Unix-like systems it uses the standard pipes, as these can be accessed without blocking there. Concurrency is managed by the Amp event loop.

Installation

This package can be installed as a Composer dependency.

composer require amphp/process

Requirements

  • PHP 7.0+

Versioning

amphp/process follows the semver semantic versioning specification like all other amphp packages.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

License

The MIT License (MIT). Please see LICENSE for more information.

Comments
  • Moderate to high concurrency load causes

    Moderate to high concurrency load causes "Failed to launch process" errors on Windows

    Using Artax (composer require amphp/artax) and running the following code on Windows:

            Loop::run(function () {
                foreach (range(1, 1000) as $id) {
                    $this->client->request('http://example.com')->onResolve(function ($error, $response) {
                        if ($error) {
                            echo "$error\n";
    
                            return;
                        }
                    });
                }
            });
    

    Generates the following error:

    Amp\Process\ProcessException: Process did not connect to server before timeout elapsed in vendor\amphp\process\lib\Internal\Windows\SocketConnector.php:344

    The key is to have a high concurrency limit (i.e. 1000 in this case). Lower limits can trigger trigger it, too, but they need to be at least in the region of ~500 on my Windows 7 system.

    The error is strange because only a couple of seconds are passing, at most, before the errors start streaming in. The same code works (can successfully download a response) with lower concurrency limits (e.g. around 200 or so).


    Edit: After further testing, I can trigger this with a limit as low as 50. It seems to depend on how long the destination server takes to respond. Loading larger pages is more likely to cause it to fail. Again, only a second or so of real user time is passing but even trying to load 50 heavy URLs at once will cause it to fail the majority of the time and there seems to be no way to override the timeout.

    bug windows 
    opened by Bilge 13
  • 'Could not start process' (0)

    'Could not start process' (0)

    my process I try to start, errors while starting up.

    I get errors like

    Uncaught exception: 'Amp\Process\ProcessException' with message 'Could not start process' (0)
    > in /cluster/www/www/www/rocket/vendor/amphp/process/lib/Internal/Posix/Runner.php:88
    Stack trace:
    #0 /cluster/www/www/www/rocket/vendor/amphp/process/lib/Process.php(96): Amp\Process\Internal\Posix\Runner->start('{ ('/usr/bin/ph...', '', Array, Array)
    #1 /cluster/www/www/www/rocket/vendor/amphp/parallel/lib/Context/Process.php(166): Amp\Process\Process->start()
    #2 /cluster/www/www/www/rocket/vendor/amphp/parallel/lib/Worker/AbstractWorker.php(59): Amp\Parallel\Context\Process->start()
    #3 /cluster/www/www/www/rocket/vendor/amphp/parallel/lib/Worker/DefaultPool.php(137): Amp\Parallel\Worker\AbstractWorker->enqueue(Object(BlockingTask))
    #4 /cluster/www/www/www/rocket/helpers/ImageHelper.php(73): Amp\Parallel\Worker\DefaultPool->enqueue(Object(BlockingTask))
    #5 [internal function]: {closure}('a', NULL)
    #6 /cluster/www/www/www/rocket/vendor/amphp/amp/lib/Coroutine.php(39): Generator->current()
    #7 /cluster/www/www/www/rocket/vendor/amphp/amp/lib/Loop/Driver.php(119): Amp\Coroutine->__construct(Object(Generator))
    #8 /cluster/www/www/www/rocket/vendor/amphp/amp/lib/Loop/Driver.php(70): Amp\Loop\Driver->tick()
    #9 /cluster/www/www/www/rocket/vendor/amphp/amp/lib/Loop.php(76): Amp\Loop\Driver->run()
    #10 /cluster/www/www/www/rocket/helpers/ImageHelper.php(80): Amp\Loop::run(Object(Closure))
    

    I guess the problem itself is, that proc_open is on the disable_functions list and therefore php does not allow to start the process.

    my calling code looks like

    function resize_image($filename, $destinations = null, $allowEnlarge = false)
    {
        $result = true;
    
        Amp\Loop::run(function () use ($filename, $destinations, $allowEnlarge, &$result) {
            $pool = new DefaultPool();
    
            $promises = array();
            foreach($destinations as $name => $params) {
                $promises[] = $pool->enqueue(new BlockingTask('resize_image_process', $filename, array($name => $params), $allowEnlarge));
            }
    
            foreach($promises as $promise) {
                $result = $result && yield $promise;
            }
            $result = $result && yield $pool->shutdown();
        });
    
        return $result;
    }
    

    while I am using classes from the examples from the parallel component https://github.com/amphp/parallel/tree/master/examples

    help wanted error messages 
    opened by staabm 7
  • Changed Windows socket timeout from 1s -> 30s

    Changed Windows socket timeout from 1s -> 30s

    One second is an insanely short timeout for a socket to respond. Many web services delivering heavy web applications easily trip this timeout during normal use. See #21.

    opened by Bilge 7
  • Amphp gets stuck in and infinite loop doing nothing if firewall delays  port access

    Amphp gets stuck in and infinite loop doing nothing if firewall delays port access

    @kelunik told me to open a ticket here.

    Please open an issue at https://github.com/amphp/parallel for the infinite loop and https://github.com/amphp/process for the ports if you want.

    its quite a while but as the problem with box was easy solvable by using the --no-parallel option i simply forgot until i hit the problem again with fink.

    i am not sure where to write which info, it feels i would post the same text in parallel and process as i haven't used amphp directly but only tools which use it, i don't know the internals.

    if i run fink it simply gets stuck forever on a windows system with a firewall.

    php fink.phar https://getcomposer.org
    

    console

    if my firewall is in learning mode, it ask me to allow ampXXXX.tmp a local connection.

    firewall-dialog

    after allowing it, the connection monitor show the following:

    connections

    this 3 php and amp processes stay there forever in an infinite loop and are doing nothing (no more as the initial 22 bytes are sent or received).

    if i run the firewall in allow all mode (which sadly makes no sense at all), it works without a problem.

    so it looks like amphp has a problem if the port is not instantly accessible but delayed by a firewall learning mode dialog. as the amp process names are randomly generated it is not possible to precreate the firewall rules. having some kind of check if ports can be accessed and if not some kind of fallback could be a solution. a slow synchronous processing is still faster as a infinite do nothing processing :) edit: non-dynamic ports can also help (only in combination with non random process names)

    opened by c33s 6
  • process immediate exit after sigterm

    process immediate exit after sigterm

    Some example code to reproduce

    test.php

    <?php
    require __DIR__.'/vendor/autoload.php';
    
    $onInterrupt = \Amp\Loop::onSignal(SIGINT, function ($reference){
    	echo "sigterm\n";
    	//\Amp\Loop::cancel($reference);
    });
    \Amp\Loop::run(function() use($onInterrupt ){
    	$process = new \Amp\Process\Process("php test-process.php");
    	$pid = yield $process->start();
    	\Amp\ByteStream\pipe($process->getStdout(), \Amp\ByteStream\getStdout());
    	\Amp\ByteStream\pipe($process->getStderr(), \Amp\ByteStream\getStderr());
    	$code = yield $process->join();
    	echo $code;
    	if(file_exists("/proc/{$pid}")) {
    		echo "Process still running\n";
    	}
    	yield new \Amp\Delayed(10000);
    	\Amp\Loop::cancel($onInterrupt);
    });
    

    test-process.php

    <?php
    require __DIR__.'/vendor/autoload.php';
    
    //pcntl_async_signals(true);
    \Amp\Loop::onSignal(SIGINT, function (){
    	echo "sigterm from parent\n";
    });
    echo "Start\n";
    \Amp\Loop::repeat(100, function(){
    	echo "test\n";
    	sleep(1);
    });
    \Amp\Loop::run();
    echo "exit\n";
    

    Steps to reproduce

    1. I start script test.php. Example output was:
    Start
    test
    test
    test
    

    Process list:

    26434 pts/7    S+     0:00 php ./test.php
    26435 pts/7    S+     0:00 sh -c { (php test-process.php) <&3 3<&- 3>/dev/null & } 3<&0;pid=$!; echo $pid >&3; wait $pid; RC=$?; echo $RC >&3; exit $RC
    26436 pts/7    S+     0:00 php test-process.php
    
    1. I send sigint(ctrl+c) to script. Output was:
    ^C0Process still running
    sigterm from parent
    test
    sigterm
    

    Processs list:

    27301 pts/7    S+     0:00 php ./test.php
    27303 pts/7    S+     0:00 php test-process.php
    
    1. I wait for script to finish. Output was:
    test
    test
    test
    test
    test
    test
    test
    test
    test
    test
    

    Actual behavior

    As you can see when sigint received php closed process wrapper (sh -c) and send sigint to test-process.php. amp/Process wait for process wrapper to finish but doesn't wait for test-process.php. But pipes will continue to work after that. The child process only killed after main process exit.

    Expected behavior

    Process::join only resolves when test-process.php finished/halted/cancelled.

    bug 
    opened by Ekstazi 6
  • Recycle process

    Recycle process

    Starting and stopping processes is a very time consuming thing.

    Would it be possible to leave a process open after the command finished and let it run another command? Or maybe some kind of process pooling to reduce start/stop overhead?

    Not sure its possible at all...

    question 
    opened by staabm 6
  • Killing detached process

    Killing detached process

    Actually killing a process which is detached does not work

    $process = new \Amp\Process\Process("setsid sleep 100");
    $process->start();
    
    $pid = yield $process->getPid();
    
    $process->kill();
    

    Then doing a ps aufx|grep sleep show the process still running, it is possible to kill him since we have the correct id and we can use then posix_kill, but should we do that (it introduce maybe a new extension dependency)

    feature request 
    opened by joelwurtz 6
  • Added some test coverage and fixed the structure

    Added some test coverage and fixed the structure

    • New getCommand(), status() and refactored pid() function.
    • Added test for kill(), exec(), pid() and status() functions against UvReactor, LibeventReactor and NativeReactor.
    • Added php-cs-fixed and phpunit/phpunit to dev-dependencies and added .php_cs file based on the others projects.
    • Changed the structure of the repository according to amphp/amp
    opened by skedone 6
  • php8 on windows with error

    php8 on windows with error

    D:\sites\git\epmms2-award>vendor\bin\grumphp.bat run GrumPHP is sniffing your code! Running tasks with priority 0! ==============================

    Running task 1/5: phpcs... Running task 2/5: phpcsfixer... Running task 3/5: shell... ✘ Running task 4/5: composer... Running task 5/5: yamllint... ✔ Aborted ... ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▄▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌ ▄███▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌ █▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌ ▐█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌ ▀█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌ ▀▀▓▓▓▓▓▓▓▓▓▓▓▓█▀▀▀▀▀▀▀▀▀▀▀▀▀▀████████████▄ ▄███████ ██████████ ███████▀ ▀▀▀▀▀▄ ▄▀▀▀▀▀ █████ ▀ ▐████ ▐██ ▐██ ████▌ ████▌ ███ ▌██▌ ▄▄ ▄▄ ▐███ ███ ▄▄▄▄▄▄▄▄▄▄▄▄ ▐███ ██▄ ▐███████████████████████████ █▀███████████▀ ▀▀███████████ ██████████▄███████▄███████████ ▐█████████████████████████████ █████████████████████████████ ██ █████████████████████▐██▀ ▀ ▐███████████████████▌ ▐▀ ████▀████████▀▐███ ▀█▌ ▐█████ ██▌ ██▀ ▐▀

       ██████████████████████████████████
       █░░░░░░▀█▀░░░░░░▀█░░░░░░▀█▀░░░░░▀█
       █░░▐█▌░░█░░░██░░░█░░██░░░█░░░██░░█
       █░░▐█▌░░█░░░██░░░█░░██░░░█░░░██░░█
       █░░▐█▌░░█░░░██░░░█░░░░░░▄█░░▄▄▄▄▄█
       █░░▐█▌░░█░░░██░░░█░░░░████░░░░░░░█
       █░░░█░░░█▄░░░░░░▄█░░░░████▄░░░░░▄█
       ██████████████████████████████████
    

    shell

    The executable for "sh" could not be found. To skip commit checks, add -n or --no-verify flag to commit command PHP Fatal error: Uncaught TypeError: fclose(): supplied resource is not a valid stream resource in D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php:221 Stack trace: #0 D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php(221): fclose(Resource id #530) amphp/amp#1 D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php(201): Amp\Process\Internal\Windows\Runner->free(Object(Amp\Process\Internal\Windows\Handle)) amphp/amp#2 D:\sites\git\epmms2-award\vendor\amphp\process\lib\Process.php(85): Amp\Process\Internal\Windows\Runner->destroy(Object(Amp\Process\Internal\Windows\Handle)) amphp/amp#3 [internal function]: Amp\Process\Process->__destruct() amphp/amp#4 {main} thrown in D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php on line 221

    Fatal error: Uncaught TypeError: fclose(): supplied resource is not a valid stream resource in D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php:221 Stack trace: #0 D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php(221): fclose(Resource id #530) amphp/amp#1 D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php(201): Amp\Process\Internal\Windows\Runner->free(Object(Amp\Process\Internal\Windows\Handle)) amphp/amp#2 D:\sites\git\epmms2-award\vendor\amphp\process\lib\Process.php(85): Amp\Process\Internal\Windows\Runner->destroy(Object(Amp\Process\Internal\Windows\Handle)) amphp/amp#3 [internal function]: Amp\Process\Process->__destruct() amphp/amp#4 {main} thrown in D:\sites\git\epmms2-award\vendor\amphp\process\lib\Internal\Windows\Runner.php on line 221

    opened by haohetao 5
  • RFC Check for constant existence before declaring

    RFC Check for constant existence before declaring

    I use an tool which requires the composer autoloader.php in order to use the class map.

    When this tool is used with the library it issues a warning as these constants are then redefined.

    This PR checks for the existence of the constants before defining them.

    opened by dantleech 5
  • Close all FDs in spawned process, because PHP leaks them

    Close all FDs in spawned process, because PHP leaks them

    This might fix https://github.com/amphp/aerys/issues/192, @brstgt please test it.

    @bwoebi Please test whether that works on macOS.

    This should have a test, but I've not been able to write one yet.

    It works locally, but apparently doesn't work on Travis, needs further investigation.

    opened by kelunik 5
  • v2 not working on FPM while v1 does

    v2 not working on FPM while v1 does

    Hi, testing Parallel v2 with fibers on php 8.1 FPM with a simple task service, but it cannot work anymore because the underlaying Process requires pcntl which is not available on FPM. The same code with Promises works on Parallel/Process v1

    opened by Dando-Real-ITA 8
  • Application stucks when launch application that requires elevated privileges on Windows

    Application stucks when launch application that requires elevated privileges on Windows

    The following code:

    Loop::run(static function () {
    
        $process = new Process("diskpart");
        yield $process->start();
    
    });
    

    Problem: app just stucks and does not stdout anything, using a timeout completely breaks the script execution:

    Loop::run(static function () {
    
        $process = new Process("diskpart");
    
        yield timeout($process->start(), 5000);
    
    });
    

    Here an exception:

    PHP Fatal error:  Uncaught Exception: stream_select(): supplied resource is not a valid stream resource in C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\NativeDriver.php:79
    Stack trace:
    #0 [internal function]: Amp\Loop\NativeDriver->Amp\Loop\{closure}(2, 'stream_select()...', 'C:\\Users\\Admin\\...', 294, Array)
    #1 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\NativeDriver.php(294): stream_select(Array, Array, NULL, 4, 0)
    #2 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\NativeDriver.php(127): Amp\Loop\NativeDriver->selectStreams(Array, Array, 4)
    #3 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\Driver.php(138): Amp\Loop\NativeDriver->dispatch(true)
    #4 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\Driver.php(72): Amp\Loop\Driver->tick()
    #5 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amp in C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\NativeDriver.php on line 79
    
    Process finished with exit code 255
    
    

    I found a possible solution to solve this problem, but I'm not good at creating PR.

    By adding the following code to "lib/Internal/Windows/SocketConnector.php" at the end of the function "onProcessConnectTimeout" (I added after the line 367)

    if ($handle->status === ProcessStatus::STARTING) {
        Loop::cancel($handle->childPidWatcher);
        $handle->pidDeferred->fail($error);
    }
    

    The problem is solved completely and now the output when running the first script:

    PHP Fatal error:  Uncaught Amp\Process\ProcessException: Failed to create child process: 740: Запрошенная операция требует повышения. in C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\process\lib\Internal\Windows\SocketConnector.php:359
    Stack trace:
    #0 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\NativeDriver.php(142): Amp\Process\Internal\Windows\SocketConnector->onProcessConnectTimeout('e', Object(Amp\Process\Internal\Windows\Handle))
    #1 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\Driver.php(138): Amp\Loop\NativeDriver->dispatch(true)
    #2 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop\Driver.php(72): Amp\Loop\Driver->tick()
    #3 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\amp\lib\Loop.php(95): Amp\Loop\Driver->run()
    #4 C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\test.php(17): Amp\ in C:\Users\Admin\Documents\win_install_stuff\windows_installer_v0\vendor\amphp\process\lib\Internal\Windows\SocketConnector.php on line 359
    
    Process finished with exit code 255
    
    

    PS. Sorry for a little machine translation, English is not my first language

    opened by Nicodinus 1
  • amphp/process kills sub process on exit

    amphp/process kills sub process on exit

    wrapper.php

    <?php
    echo 'foo';
    sleep(1);
    touch('a');
    

    Following works as expected, outputs foo, exits immediately and after 1 second creates file 'a'.

    <?php
    
    $fd = [
        ["pipe", "r"], // stdin
        ["pipe", "w"], // stdout
    ];
    $handle = @\proc_open('php wrapper.php', $fd, $pipes);
    
    echo fread($pipes[1], 100);
    

    Following does not work as expected. Outputs foo, exits immediately but file is not created.

    <?php
    require_once "vendor/autoload.php";
    \Amp\Loop::run(function () {
        $process = new \Amp\Process\Process("php wrapper.php");
        yield $process->start();
        echo yield $process->getStdout()->read();
    });
    
    discussion 
    opened by ostrolucky 6
Releases(v2.0.0-beta.7)
  • v2.0.0-beta.7(Nov 7, 2022)

  • v2.0.0-beta.6(Oct 28, 2022)

  • v2.0.0-beta.5(Jul 18, 2022)

  • v2.0.0-beta.4(Jul 7, 2022)

    • Removed check for ext-pcntl, which is not strictly required for this library.
    • Fixed ended processes sometimes leaving zombie processes on *nix systems (requires ext-pcntl)
    Source code(tar.gz)
    Source code(zip)
  • v1.1.4(Jul 7, 2022)

  • v2.0.0-beta.3(Feb 3, 2022)

    What's Changed

    • Drop dependency on amphp/sync
    • Add compatibility with revolt/event-loop 0.2.x

    Full Changelog: https://github.com/amphp/process/compare/v2.0.0-beta.2...v2.0.0-beta.3

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.2(Dec 17, 2021)

    • Fixed and improved wrapper copy if running inside of PHARs on Windows
    • Removed nullability of Process::getWorkingDirectory()
    • Fixed compatibility with amphp/byte-stream v2.0.0-beta.2
    • Avoid calling join() inside kill() to avoid suspensions in destructors
    Source code(tar.gz)
    Source code(zip)
  • v1.1.3(Dec 17, 2021)

    • Fixed wrapper path if running inside PHARs on Windows
    • Improved wrapper copy behavior if running inside PHARs on Windows
    • Removed ProcessException being thrown if process killing fails on Windows, which has been subject to race conditions
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta.1(Dec 14, 2021)

    • Process::__construct() is now private in favor of Process::start()
    • Process::start() is now static instead of an instance method
    • Process::start() does no longer return the PID, use Process::getPid()
    • Process::kill() does no longer result in an exception of Process::join()
    • Process::getEnv() has been renamed to Process::getEnvironment()
    • Improved handling if process is destructed, but streams are still used
    • Renamed escapeArguments to escapeArgument
    • Removed custom stream implementations
    • Removed StatusError
    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Oct 8, 2021)

  • v1.1.1(Mar 30, 2021)

  • v1.1.0(Mar 4, 2019)

    • Added escapeArguments() function that escapes process arguments for each platform (i.e., Windows vs. Linux/Unix) (#35)
    • File descriptors inherited from the parent process are now closed automatically in the child process on Posix systems.
    • Updated bundled Windows process wrapper executable to v1.2 (#34)
    • Fixed Process::signal() sending signals to the wrapper child process instead of the intended child (#36)
    • Fixed Process::join() resolving before the child process exits due to termination signals being sent and handled or ignored by the child process (#36)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(Jan 15, 2019)

  • v1.0.2(Nov 9, 2018)

  • v1.0.1(Nov 8, 2018)

    • Fixed issue on Windows when calling Process::getStdin(), Process::getStdout(), or Process::getStderr() immediately after the process has started.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Oct 21, 2018)

    This release introduces a couple of backwards-compatibility breaks that will require some small adjustments to code using this library.

    • Process::start() now returns a promise. This promise must resolve before calling Process::getPid(), Process::getStdin(), Process::getStdout(), and Process::getStderr() otherwise an exception is thrown from these methods.
    • Process::getPid() now returns an integer.
    • Process, ProcessInputStream, and ProcessOutputStream are now final.
    Source code(tar.gz)
    Source code(zip)
  • v0.3.3(Apr 9, 2018)

  • v0.3.2(Mar 8, 2018)

  • v0.3.1(Dec 5, 2017)

  • v0.3.0(Nov 25, 2017)

    Windows support added!

    Only some minor API breaks were necessary:

    • Process::getPid() now returns a promise for the PID.
    • Process::getStdIn() returns an instance of ProcessInputStream instead of ResourceInputStream, however the same API is shared by both classes.
    • Process::getStdOut() and Process::getStdErr() both return an instance of ProcessOutputStream instead of ResourceOutputStream, however the same API is shared by both classes.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Jul 18, 2017)

    • Changed return types of Process::getStd*() functions to be more specific. By specifying ResourceInputStream and ResourceOutputStream, methods such as close() or unreference() can reliably be used.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jun 16, 2017)

  • v0.1.3(Sep 24, 2016)

  • v0.1.0(Sep 10, 2015)

Owner
AMPHP
AMPHP is a collection of high-quality, event-driven libraries for PHP designed with fibers and concurrency in mind.
AMPHP
AMP Optimizer PHP library

AMP Toolbox for PHP A collection of AMP tools making it easier to publish and host AMP pages with PHP. The following tools are part of this library: A

AMP 71 Dec 28, 2022
Dispatcher is a Laravel artisan command scheduling tool used to schedule artisan commands within your project so you don't need to touch your crontab when deploying.

Dispatcher Dispatcher allows you to schedule your artisan commands within your Laravel project, eliminating the need to touch the crontab when deployi

Indatus 1.1k Dec 21, 2022
Artax is an asynchronous HTTP client for PHP based on Amp

Artax is an asynchronous HTTP client for PHP based on Amp. Its API simplifies standards-compliant HTTP resource traversal and RESTful web service consumption without obscuring the underlying protocol. The library manually implements HTTP over TCP sockets; as such it has no dependency on ext/curl.

AMPHP 21 Dec 14, 2022
Venture allows you to create and manage complex, async workflows in your Laravel apps.

Venture is a package to help you build and manage complex workflows of interdependent jobs using Laravel's queueing system. Installation Note: Venture

Kai Sassnowski 680 Dec 14, 2022
Use php-fpm as a simple built-in async queue

PHP-FPM Async Queue Use php-fpm as a simple built-in async queue. Based on interoperable queue interfaces Queue Interop. Usage composer makasim/php-fp

Max Kotliar 111 Nov 19, 2022
This component, based on the Symfony serializer and async-aws, is a human-readable and quick abstraction to easily store serialized objects in DynamoDB 🚀.

DynamoDB Storable This component, based on the Symfony serializer and async-aws, is a human-readable and quick abstraction to easily store serialized

Matthieu W. 2 Jun 19, 2022
Simple async lowlevel ICMP (ping) messaging library built on top of React PHP

clue/icmp-react Simple async lowlevel ICMP (ping) messaging library built on top of react Usage Once clue/icmp-react is installed, you can run any of

Christian Lück 13 Jun 10, 2022
Stupid async implementation using await-generator

libAsync Stupid async implementation using await-generator Usage libAsync::doAsync(Closure $executor); // <-- Returns a promise Example Fetch data fro

null 5 Jan 2, 2023
Integrate reCAPTCHA using async HTTP/2, making your app fast with a few lines.

ReCaptcha Integrate reCAPTCHA using async HTTP/2, making your app fast with a few lines. use Illuminate\Support\Facades\Route; Route::post('login', f

Laragear 14 Dec 6, 2022
PPM is a process manager, supercharger and load balancer for modern PHP applications.

PPM - PHP Process Manager PHP-PM is a process manager, supercharger and load balancer for PHP applications. It's based on ReactPHP and works best with

PPM - PHP Process Manager 6.5k Jan 3, 2023
A visual process builder

DataStory ⚡ visual programming DataStory provides a workbench for designing data flow diagrams. ⚠️ We have moved to an organisation ?? Live Demo data-

Anders Jürisoo 120 Dec 12, 2022
This extension facilitates the cms editing process in your store.

Magenerds_PageDesigner This extension facilitates the cms editing process in your store. Instead of just a wysiwyg editor you now have a drag and drop

Magenerds 92 Nov 23, 2022
This composer plugin is a temporary implementation of using symbolic links to local packages as dependencies to allow a parallel work process

Composer symlinker A Composer plugin to install packages as local symbolic links. This plugin is a temporary implementation of using symbolic links to

Pierre Cassat 18 Nov 9, 2021
A library for simplifying the PHAR build process.

Box is a library built on the Phar class. It is designed to make it easier to create new phars and modifying existing ones. Features include compacting source files, better custom stub generation, and better OpenSSL signing handling.

Box Project 193 May 16, 2022
A sampling profiler for PHP written in PHP, which reads information about running PHP VM from outside of the process.

Reli Reli is a sampling profiler (or a VM state inspector) written in PHP. It can read information about running PHP script from outside of the proces

null 272 Dec 22, 2022
A lightweight mulit-process helper base on PHP.

workbunny/process ?? A lightweight multi-process helper base on PHP. ?? 简介 这是一个基于ext-pcntl和ext-posix拓展的PHP多进程助手,用于更方便的调用使用。 快速开始 composer require work

workbunny 10 Dec 14, 2022
A sampling profiler for PHP written in PHP, which reads information about running PHP VM from outside of the process.

Reli Reli is a sampling profiler (or a VM state inspector) written in PHP. It can read information about running PHP script from outside of the proces

null 258 Sep 15, 2022
Pat if amp - ⚡ A Textpattern Conditional Plugin for Google's Accelerated Mobile Pages Project (AMP)

pat_if_amp Download | Packagist AMP pages for Textpattern CMS. This conditional tag examines the URL of the current page and determines if the URL end

Patrick LEFEVRE 4 Dec 15, 2019
Async HTTP/1.1+2 client for PHP based on Amp.

This package provides an asynchronous HTTP client for PHP based on Amp. Its API simplifies standards-compliant HTTP resource traversal and RESTful web

AMPHP 641 Dec 19, 2022