Code Monkey home page Code Monkey logo

async's Introduction

Asynchronous and parallel PHP

Latest Version on Packagist Tests Status Quality Score Total Downloads

This library provides a small and easy wrapper around PHP's PCNTL extension. It allows running of different processes in parallel, with an easy-to-use API.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/async

Usage

use Spatie\Async\Pool;

$pool = Pool::create();

foreach ($things as $thing) {
    $pool->add(function () use ($thing) {
        // Do a thing
    })->then(function ($output) {
        // Handle success
    })->catch(function (Throwable $exception) {
        // Handle exception
    });
}

$pool->wait();

Event listeners

When creating asynchronous processes, you'll get an instance of ParallelProcess returned. You can add the following event hooks on a process.

$pool
    ->add(function () {
        // ...
    })
    ->then(function ($output) {
        // On success, `$output` is returned by the process or callable you passed to the queue.
    })
    ->catch(function ($exception) {
        // When an exception is thrown from within a process, it's caught and passed here.
    })
    ->timeout(function () {
        // A process took too long to finish.
    })
;

Functional API

Instead of using methods on the $pool object, you may also use the async and await helper functions.

use Spatie\Async\Pool;

$pool = Pool::create();

foreach (range(1, 5) as $i) {
    $pool[] = async(function () {
        usleep(random_int(10, 1000));

        return 2;
    })->then(function (int $output) {
        $this->counter += $output;
    });
}

await($pool);

Error handling

If an Exception or Error is thrown from within a child process, it can be caught per process by specifying a callback in the ->catch() method.

$pool
    ->add(function () {
        // ...
    })
    ->catch(function ($exception) {
        // Handle the thrown exception for this child process.
    })
;

If there's no error handler added, the error will be thrown in the parent process when calling await() or $pool->wait().

If the child process would unexpectedly stop without throwing an Throwable, the output written to stderr will be wrapped and thrown as Spatie\Async\ParallelError in the parent process.

Catching exceptions by type

By type hinting the catch functions, you can provide multiple error handlers, each for individual types of errors.

$pool
    ->add(function () {
        throw new MyException('test');
    })
    ->catch(function (MyException $e) {
        // Handle `MyException`
    })
    ->catch(function (OtherException $e) {
        // Handle `OtherException`
    });

Note that as soon as an exception is handled, it won't trigger any other handlers

$pool
    ->add(function () {
        throw new MyException('test');
    })
    ->catch(function (MyException $e) {
        // This one is triggerd when `MyException` is thrown
    })
    ->catch(function (Exception $e) {
        // This one is not triggerd, even though `MyException` extends `Exception`
    });

Stopping a pool

If you need to stop a pool early, because the task it was performing has been completed by one of the child processes, you can use the $pool->stop() method. This will prevent the pool from starting any additional processes.

use Spatie\Async\Pool;

$pool = Pool::create();

// Generate 10k processes generating random numbers
for($i = 0; $i < 10000; $i++) {
    $pool->add(function() use ($i) {
        return rand(0, 100);
    })->then(function($output) use ($pool) {
        // If one of them randomly picks 100, end the pool early.
        if ($output === 100) {
            $pool->stop();
        }
    });
}

$pool->wait();

Note that a pool will be rendered useless after being stopped, and a new pool should be created if needed.

Using another PHP binary

By default the pool will use php to execute its child processes. You can configure another binary like so:

Pool::create()
    ->withBinary('/path/to/php');

Working with tasks

Besides using closures, you can also work with a Task. A Task is useful in situations where you need more setup work in the child process. Because a child process is always bootstrapped from nothing, chances are you'll want to initialise eg. the dependency container before executing the task. The Task class makes this easier to do.

use Spatie\Async\Task;

class MyTask extends Task
{
    public function configure()
    {
        // Setup eg. dependency container, load config,...
    }

    public function run()
    {
        // Do the real work here.
    }
}

// Add the task to the pool
$pool->add(new MyTask());

Simple tasks

If you want to encapsulate the logic of your task, but don't want to create a full blown Task object, you may also pass an invokable object to the Pool.

class InvokableClass
{
    // ...

    public function __invoke()
    {
        // ...
    }
}

$pool->add(new InvokableClass(/* ... */));

Pool configuration

You're free to create as many pools as you want, each pool has its own queue of processes it will handle.

A pool is configurable by the developer:

use Spatie\Async\Pool;

$pool = Pool::create()

// The maximum amount of processes which can run simultaneously.
    ->concurrency(20)

// The maximum amount of time a process may take to finish in seconds
// (decimal places are supported for more granular timeouts).
    ->timeout(15)

// Configure which autoloader sub processes should use.
    ->autoload(__DIR__ . '/../../vendor/autoload.php')
    
// Configure how long the loop should sleep before re-checking the process statuses in microseconds.
    ->sleepTime(50000)
;

Synchronous fallback

If the required extensions (pcntl and posix) are not installed in your current PHP runtime, the Pool will automatically fallback to synchronous execution of tasks.

The Pool class has a static method isSupported you can call to check whether your platform is able to run asynchronous processes.

If you're using a Task to run processes, only the run method of those tasks will be called when running in synchronous mode.

Behind the curtains

When using this package, you're probably wondering what's happening underneath the surface.

We're using the symfony/process component to create and manage child processes in PHP. By creating child processes on the fly, we're able to execute PHP scripts in parallel. This parallelism can improve performance significantly when dealing with multiple synchronous tasks, which don't really need to wait for each other. By giving these tasks a separate process to run on, the underlying operating system can take care of running them in parallel.

There's a caveat when dynamically spawning processes: you need to make sure that there won't be too many processes at once, or the application might crash. The Pool class provided by this package takes care of handling as many processes as you want by scheduling and running them when it's possible.

That's the part that async() or $pool->add() does. Now let's look at what await() or $pool->wait() does.

When multiple processes are spawned, each can have a separate time to completion. One process might eg. have to wait for a HTTP call, while the other has to process large amounts of data. Sometimes you also have points in your code which have to wait until the result of a process is returned.

This is why we have to wait at a certain point in time: for all processes on a pool to finish, so we can be sure it's safe to continue without accidentally killing the child processes which aren't done yet.

Waiting for all processes is done by using a while loop, which will wait until all processes are finished. Determining when a process is finished is done by using a listener on the SIGCHLD signal. This signal is emitted when a child process is finished by the OS kernel. As of PHP 7.1, there's much better support for listening and handling signals, making this approach more performant than eg. using process forks or sockets for communication. You can read more about it here.

When a process is finished, its success event is triggered, which you can hook into with the ->then() function. Likewise, when a process fails or times out, the loop will update that process' status and move on. When all processes are finished, the while loop will see that there's nothing more to wait for, and stop. This is the moment your parent process can continue to execute.

Comparison to other libraries

We've written a blog post containing more information about use cases for this package, as well as making comparisons to other asynchronous PHP libraries like ReactPHP and Amp: http://stitcher.io/blog/asynchronous-php.

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

License

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

async's People

Contributors

adrianmrn avatar alexvanderbist avatar assertchris avatar barchard avatar brendt avatar carusogabriel avatar chinthakagodawita avatar divineomega avatar exussum12 avatar freekmurze avatar gazugafan avatar githubhubus avatar grahamcampbell avatar gummibeer avatar howardtomlinson avatar jeromegamez avatar joaorobertopb avatar jonasraoni avatar kanti avatar matthi4s avatar michielkempen avatar mintunitish avatar nielsvanpach avatar oniice avatar patinthehat avatar stevemoretz avatar svenluijten avatar thecaliskan avatar vdbelt avatar vuongxuongminh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

async's Issues

Simple example not working

[2018-11-30 16:47:58] local.DEBUG: The serialized closure is signed. Make sure you use a security provider for both serialization and unserialization.

#0 [internal function]: Opis\Closure\SerializableClosure->unserialize('@{"closure":"a:...')
#1 /home/vagrant/code/vendor/opis/closure/functions.php(34): unserialize('C:32:"Opis\Clos...')
#2 /home/vagrant/code/vendor/spatie/async/src/Runtime/ParentRuntime.php(92): Opis\Closure\unserialize('C:32:"Opis\Clos...')
#3 /home/vagrant/code/vendor/spatie/async/src/Runtime/ChildRuntime.php(23): Spatie\Async\Runtime\ParentRuntime::decodeTask('QzozMjoiT3Bpc1x...')
#4 {main}

    $pool = \Spatie\Async\Pool::create();

    $json = '';



    $pool->add(function() {

        logger('rates test 1');

        return '{"id":"1","label":"test 1","cost":100}';

    })->then(function($out) use(&$json) {

        logger('rates test 2');

        if( $json ) $json .= ',';

        $json .= $out;

    })->catch(function(Throwable $e) {

        logger($e->getMessage());

    });


    $pool->add(function() {

        return '{"id":"2","label":"test 2","cost":200}';

    })->then(function($out) use(&$json) {

        if( $json ) $json .= ',';

        $json .= $out;

    })->catch(function(Throwable $e) {

        //

    });


    $pool->add(function() {

        return '{"id":"3","label":"test 3","cost":300}';

    })->then(function($out) use(&$json) {

        if( $json ) $json .= ',';

        $json .= $out;

    })->catch(function(Throwable $e) {

        //

    });


    $pool->wait();

    logger('rates test 3');

    echo '{"rates":[' . $json . ']}';

The $json variable is blank

PHP Startup: Unable to load dynamic library

Hello. I need help here.

  • PHP 7.3.2

My code:
`
dump('supported: ' . Pool::isSupported());

    dump('posix: ' . extension_loaded('posix'));
    dump('pcntl: ' . extension_loaded('pcntl'));

    dump('Start pool: ' . Carbon::now()->format('Y-m-d H:i:s'));
    $pool = Pool::create();
    dump($pool);

    for ($i = 0; $i <= 5; $i++) {

        dump('Task '.$i.': ' . Carbon::now()->format('Y-m-d H:i:s'));
        $pool->add(function () use ($i) {
            sleep($i);
            return $i;
        })->then(function ($output) {
            $this->results[] = $output;
        })->catch(function (\Throwable $exception) {
            ApmReportExceptionService::report($exception);
        });

    }

    dump('Wait: ' . Carbon::now()->format('Y-m-d H:i:s'));
    $pool->wait();
    dump('End: ' . Carbon::now()->format('Y-m-d H:i:s'));

`

My output:
image
image

My exception message:
PHP Warning: PHP Startup: Unable to load dynamic library 'mysqlnd.so' (tried: /usr/lib/php7/modules/mysqlnd.so (Error relocating /usr/lib/php7/modules/mysqlnd.so: _zend_hash_str_update: symbol not found), /usr/lib/php7/modules/mysqlnd.so.so (Error loading shared library /usr/lib/php7/modules/mysqlnd.so.so: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'mysqli.so' (tried: /usr/lib/php7/modules/mysqli.so (Error relocating /usr/lib/php7/modules/mysqli.so: _zend_hash_str_update: symbol not found), /usr/lib/php7/modules/mysqli.so.so (Error loading shared library /usr/lib/php7/modules/mysqli.so.so: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'pdo_mysql.so' (tried: /usr/lib/php7/modules/pdo_mysql.so (Error relocating /usr/lib/php7/modules/pdo_mysql.so: _zval_ptr_dtor: symbol not found), /usr/lib/php7/modules/pdo_mysql.so.so (Error loading shared library /usr/lib/php7/modules/pdo_mysql.so.so: No such file or directory)) in Unknown on line 0

Tks!

vendor/spatie/async/src/Runtime/ChildRuntime.php(25): Opis\Closure\SerializableClosure->{closure}()

In my save function, I use the pool to operate faster, but it doesn't seem to work and logs like above!
Here is my function:
public static function create(array $products, string $orderId, string $orderTotal)
{
$unit = null;
$response =[];
$pool = Pool::create();
foreach ($products as $product) {
$amount = $product['price'] * $product['quantity'];
$orderTotal += $amount;
$pool[] = async(function () use ($product, $orderId,$amount) {
$image = null;
$unit = $product['unit'] ?? $product['unit_name'];
$image = $product['product']['thumbnail'] ?? $product['thumbnail'];
$data = new OrderProduct();
$data->product_id = $product['pid'];
$data->name = $product['name'];
$data->thumbnail = $image;
$data->order_id = $orderId;
$data->quantity = $product['quantity'];
$data->price = $product['price'];
$data->unit = $unit;
$data->total_price = $amount;
$data->save();
Product::remainingProduct($product['pid'], $product['quantity']);
$output[] = $data;
return $output;
})->then(function (array $output) {
return $output;
})->catch(function (\Throwable $exception) {
Log::error($exception->getMessage());
});
}
await($pool);
$orders = $pool->getFinished();
foreach ($orders as $order => $value)
{
$response[] = $value->getOutput()[0];
}
$response['order_total'] = $orderTotal;
return $response;
}

[Symfony\Component\Debug\Exception\ContextErrorException] Warning: Cannot bind closure to scope of internal class ReflectionProperty

Hi! There is a problem on

Symfony 3.4.29 (kernel: app, env: dev, debug: true)
PHP 7.1.19 (cli) (built: Jun 25 2018 10:42:21) ( NTS )

protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->logger = new \Symfony\Component\Console\Logger\ConsoleLogger($output);

        $pool = Pool::create();
            //->autoload(__DIR__ . '/../../../app/autoload.php')
            //->concurrency(5)
            //->timeout(120);

        foreach (array_range(1, 10) as $i) {
            $pool[] = async(function () {
                usleep(random_int(100000, 1000000));

                $this->logger->info('Test');

                return 2;
            })->then(function (int $output) {
                //
            });
        }

        await($pool);

        return 0;
    }
In EntityManager_9a5be93.php line 500:

  [Symfony\Component\Debug\Exception\ContextErrorException]
  Warning: Cannot bind closure to scope of internal class ReflectionProperty


Exception trace:
 () at /Users/user/dev/project/var/cache/dev/ContainerJknfemg/EntityManager_9a5be93.php:500
 EntityManager_9a5be93->__get() at n/a:n/a
 ReflectionProperty->getValue() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:426
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:390
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:428
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:428
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:428
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:390
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:428
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:428
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:428
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:428
 Opis\Closure\SerializableClosure::wrapClosures() at /Users/user/dev/project/vendor/opis/closure/src/SerializableClosure.php:131
 Opis\Closure\SerializableClosure->serialize() at n/a:n/a
 serialize() at /Users/user/dev/project/vendor/opis/closure/functions.php:20
 Opis\Closure\serialize() at /Users/user/dev/project/vendor/spatie/async/src/Runtime/ParentRuntime.php:89
 Spatie\Async\Runtime\ParentRuntime::encodeTask() at /Users/user/dev/project/vendor/spatie/async/src/Runtime/ParentRuntime.php:71
 Spatie\Async\Runtime\ParentRuntime::createProcess() at /Users/user/dev/project/vendor/spatie/async/src/helpers.php:15
 async() at /Users/user/dev/project/src/AppBundle/Command/GatherUsersBalancesCommand.php:112
 AppBundle\Command\GatherUsersBalancesCommand->execute() at /Users/user/dev/project/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at /Users/user/dev/project/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:987
 Symfony\Component\Console\Application->doRunCommand() at /Users/user/dev/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:86
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /Users/user/dev/project/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:255
 Symfony\Component\Console\Application->doRun() at /Users/user/dev/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:74
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /Users/user/dev/project/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:148
 Symfony\Component\Console\Application->run() at /Users/user/dev/project/bin/console:33

tell me if you know how to solve this please?

How to requeue a task?

I am learning how to use async and I have a question for the best way to handle an exception in a task if you want to retry it.

Basically I want to do something like this:

$pool = Pool::create();

foreach ($tasks as $task) {
   $pool->add(new SomeTaskThatFails($task))
   ->catch(function (Throwable $exception) {
      // deal with a problem
      // retry for success
   });
}

$pool->wait();

Is something like this possible? I have tried a few things but I mostly end up in an infinite loop.

Synchronous fallback confuse

In document i found:

If the required extensions (pcntl and posix) are not installed in your current PHP runtime, the Pool will automatically fallback to synchronous execution of tasks.

But currently when not have required extensions an error will be throw because a Pool call registerListener in the constructor should we check isSupported before call it? If not, why we not add it to require section in composer.json?

Error in laravel 5.8 installation

i just installed this package in larave 5.8 and i get the following error

PHP Deprecated: Passing a command as string when creating a "Symfony/Component/Process/Process" instance is deprecated since Symfony 4.2, pass it as an array of its arguments instead, or use the "Process::fromShellCommandline()" constructor if you need features provided by the shell. in /home/benjamingakami/jobs/syntax/dropexpress/vendor/symfony/process/Process.php on line 147

Future plans for this package

Hey,

what are the future plans for this package, given you have integrated amphp/parallel-functions into https://github.com/spatie/laravel-collection-macros instead of using this package?

Generally I'd recommend against using forks, because each forks retains the previous state, e.g. open files etc. While that's currently also true for all child processes opened by PHP, that might change in the future, and they're already better for most uses generic use cases right now, because they don't retain the memory allocated by the currently running process.

Not working out of the box

Laravel 5.7
PHP 7.1.25
spatie/async 1.0.0

Opis\Closure\SecurityException: The serialized closure is signed. Make sure you use a security provider for both serialization and unserialization.

$pool = new Pool();
$i = 5;
while ($i) {
     $pool->add(function () use ($i) {
          echo $i;
          sleep(10);
     });
     $i--;
}

$pool->wait();

Using it for HIPAA compliant audit logs

Your packages seems to be promising and seems to be solving the problem statement we have. Just wanted to be sure before I try that out. So wanted to confirm from the team if its good fit for our use case.

We are building a healthcare EHR solution. In healthcare projects there is a must requirement to audit log everything (specially data related to Patient protected health information). So right now with each request we serialize data and put it into audit log (it involves some more processing along with it as well). Requests to our system includes mainly bulk queries so we have to log each one. Doing so increases the overall response time of the request. What we want to do is to run the main code as it is and send the response to the end user and put the audit log code in async mode so it can be completed afterwards also. But if anything fails while executing audit log code we need to capture that because at no cost we can miss an audit log. And should be able to re-run the same

Please advise if above use case is possible using this library. We have never done any async programming in PHP but have experience of the same in Node JS.

Thanks in advance.

InvalidArgumentException : Unknown setter 'date'

Same here:

 InvalidArgumentException : Unknown setter 'date'
 at /Users/{PH}/Sites/{PH}/{PH}/vendor/nesbot/carbon/src/Carbon/Carbon.php:1202
 1198| $this->setTimezone($value);
 1199| break;
 1200|
 1201| default:
 1202| throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
 1203| }
 1204| }
 1205|
 1206| /**

Exception trace:

1 Carbon\Carbon::__set("date", "2018-10-09 13:30:51.266615")
[internal]:0

2 ReflectionProperty::setValue(Object(Illuminate\Support\Carbon), "2018-10-09 13:30:51.266615")
/Users/{PH}/Sites/{PH}/{PH}/vendor/opis/closure/src/SerializableClosure.php:397

code:

    $sPool = SPool::create()->concurrency(20);
    $sPool[] = async(function () use ($msg){
                             // Some process here
                       })->then(function ($output) {
                            // Handle success
                            \Log::info("OUT: " . $output);
                      })->catch(function (\Exception $exception) {
                         // Handle exception
                        \Log::info($exception->getMessage());
                    });
    await($sPool);

AND WHILE I used try catch for the SerializableClosure.php:397 I Got this:

[2018-10-09 13:18:29] local.INFO: Unknown setter 'date'
[2018-10-09 13:18:29] local.INFO: Unknown setter 'timezone_type'
[2018-10-09 13:18:29] local.INFO: DateTime::setTimezone(): The DateTime object has not been correctly initialized by its constructor

local.ERROR: Target [Illuminate\Contracts\Config\Repository] is not instantiable while building [Hyn\Tenancy\Database\Connection].

#0 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(794): Illuminate\Container\Container->notInstantiable('Illuminate\Cont...')
#1 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(667): Illuminate\Container\Container->build('Illuminate\Cont...')
#2 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(615): Illuminate\Container\Container->resolve('Illuminate\Cont...', Array)
#3 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(927): Illuminate\Container\Container->make('Illuminate\Cont...')
#4 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(855): Illuminate\Container\Container->resolveClass(Object(ReflectionParameter))
#5 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(816): Illuminate\Container\Container->resolveDependencies(Array)
#6 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(667): Illuminate\Container\Container->build('Hyn\Tenancy\Dat...')
#7 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Container/Container.php(615): Illuminate\Container\Container->resolve('Hyn\Tenancy\Dat...', Array)
#8 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(121): Illuminate\Container\Container->make('Hyn\Tenancy\Dat...', Array)
#9 /home/shoply/public_html/api-shoply/vendor/hyn/multi-tenant/src/Traits/UsesTenantConnection.php(23): app('Hyn\Tenancy\Dat...')
#10 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1219): SHL\Product\Entities\Product->getConnectionName()
#11 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1051): Illuminate\Database\Eloquent\Model->getConnection()
#12 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(968): Illuminate\Database\Eloquent\Model->newBaseQueryBuilder()
#13 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1004): Illuminate\Database\Eloquent\Model->newModelQuery()
#14 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(957): Illuminate\Database\Eloquent\Model->newQueryWithoutScopes()
#15 /home/shoply/public_html/api-shoply/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(947): Illuminate\Database\Eloquent\Model->newQuery()
#16 closure://function () use ($product,$outOfStock) {
$product = \SHL\Product\Entities\Product::query()->select('id','quantity')->where([
['id',$product['pid']],
['quantity','<',$product['quantity']]
])->first();
if($product != null){
$outOfStock[]=$product->original;
}
return $outOfStock;
}(3): Illuminate\Database\Eloquent\Model::query()
#17 /home/shoply/public_html/api-shoply/vendor/spatie/async/src/Runtime/ChildRuntime.php(25): Opis\Closure\SerializableClosure->{closure}()
#18 {main}

Pool hangs on large output

I'm not sure what the exact cut-off is, though at least on outputs of several megabytes (now possible thanks to the changes in 1.1.0) on RHEL 7, the Pool seems to enter a hang state -- I don't understand the exact mechanism, but I'm guessing the output pipe is filling its buffer and then blocking for the parent process to read it, which isn't happening. Subsequently, the child process never exits, never fires SIGCHILD, and thus the Pool never completes, entering an infinite wait.

One simple solution, which may not be the best, is here: FreezeWarp@deab44e

I'm happy to open a pull request if this seems like a satisfactory solution.

Regards,
JTP

Database connection can not be resolved

I'm testing your package to see if it makes sense for us to use async DB inserts in order to improve performance and I'm running into the following problem when calling $dbModelObject->save() (I should mention that we're using Eloquent and specifically the mongodb extension for it (jenssegers/mongodb) but I'm suspecting that this is generic issue):

PHP Fatal error:  Uncaught Error: Call to a member function connection() on null
#0 /var/www/html/BoostFixes/vendor/illuminate/database/Eloquent/Model.php(1205): Illuminate\Database\Eloquent\Model::resolveConnection(NULL)
#1 /var/www/html/BoostFixes/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Eloquent/Model.php(412): Illuminate\Database\Eloquent\Model->getConnection()
#2 /var/www/html/BoostFixes/vendor/illuminate/database/Eloquent/Model.php(950): Jenssegers\Mongodb\Eloquent\Model->newBaseQueryBuilder()
#3 /var/www/html/BoostFixes/vendor/illuminate/database/Eloquent/Model.php(628): Illuminate\Database\Eloquent\Model->newModelQuery()
#4 /var/www/html/BoostFixes/src/Model/BaseModel.php(395): Illuminate\Database\Eloquent\Model->save()
#5 closure://function() use ($bet) { $bet->save (); }(2): Boost\Model\BaseModel->save()
#6 /var/www/html/BoostFixes/vendor/spatie/async/src/Runtime/ChildRuntime.php(25): Opis\Closure\SerializableClosure->{closure}()
#7 {main} in /var/www/html/BoostFixes/vendor/spatie/async/src/Output/Serializab in /var/www/html/BoostFixes/vendor/spatie/async/src/Output/SerializableException.php on line 28

Just to be clear, the code works fine without using your package; it seems to be that somehow the DB context is not available in the child/async process. Could you please advise how/if it is possible to get this to work?

InvalidArgumentException : Unknown setter 'date'

When I add a pool, a error is throwed:

   InvalidArgumentException  : Unknown setter 'date'

  at vendor/nesbot/carbon/src/Carbon/Carbon.php:1011
    1007|                 $this->setTimezone($value);
    1008|                 break;
    1009|
    1010|             default:
  > 1011|                 throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
    1012|         }
    1013|     }
    1014|
    1015|     /**

  Exception trace:

  1   Carbon\Carbon::__set("date", "2018-05-14 09:42:26.369021")
      [internal]:0

  2   ReflectionProperty::setValue(Object(Illuminate\Support\Carbon), "2018-05-14 09:42:26.369021")
      vendor/opis/closure/src/SerializableClosure.php:359

Concurrency

Is there a limit on concurrency? I can't seem to make this library create more 20 concurrent processes. I checked the getter/setter and code seems correct. I tried many combinations of concurrency and sleepTime but still no change.

Also, what are the future plans on allowing many tasks per process? I saw an old issue and there's still a variable for that on the Pool class.

PDO instance?

if my function has a MySQL PDO I get failed to serialize PDO instance

Fatal error: Uncaught Spatie\Async\Output\ParallelError

Hello. I'm trying to run my code asynchronously, but I'm recieving an unknown error. Could you please take a look into it?

My environment: ubuntu 16.04, PHP 7.2.7 with PHP-FPM.

My code:

$pool = Pool::create();

$pool->add(function() {
    error_log('Async snapshot called');
    $html = getSnapshotHTML($full_uri);
    $source_code = pg_escape_string($html['source_code']);
    $url_path = parse_url($full_uri, PHP_URL_PATH);

    if($html['status_code'] == 200) {
        $query = "UPDATE snapshots SET (html, inserted) = ('$source_code', '$now') WHERE pathname = '{$url_path}'";
        $result = pg_query($query) or die('Query failed: ' . pg_last_error());   
    }
});

Stack trace:

2018/07/03 21:53:07 [error] 22566#22566: *2 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Spatie\Async\Output\ParallelError in /var/www/production/engine/vendor/spatie/async/src/Output/ParallelError.php:11
Stack trace:
#0 /var/www/production/engine/vendor/spatie/async/src/Process/ParallelProcess.php(126): Spatie\Async\Output\ParallelError::fromException('')
#1 /var/www/production/engine/vendor/spatie/async/src/Process/ProcessCallbacks.php(51): Spatie\Async\Process\ParallelProcess->resolveErrorOutput()
#2 /var/www/production/engine/vendor/spatie/async/src/Pool.php(197): Spatie\Async\Process\ParallelProcess->triggerError()
#3 /var/www/production/engine/vendor/spatie/async/src/Pool.php(285): Spatie\Async\Pool->markAsFailed(Object(Spatie\Async\Process\ParallelProcess))
#4 /var/www/production/engine/vendor/symfony/process/Process.php(830): Spatie\Async\Pool->Spatie\Async\{closure}(17, Array)
#5 /var/www/production/engine/vendor/symfony/process/Process.php(168): Symfony\Component\Process\Process->stop(0)
#6 [internal function]: Symfony\Component\Process\Proces" while reading upstream

Seems like lose the global context

I tried to use this lib in Laravel but I get the error A facade root has not been set when I use the Storage inside of the closure:

$pool = Pool::create();

$pool[] = async(function() use ($path) {
  return Storage::disk('gcs')->exists($path);
})
->then(function($exist) use ($path) {
  if($exist) {
	Storage::disk('gcs')->delete($path);
  }
})
->catch(function($error) {
  throw new Exception($error);
});

await($pool);

if I don't use async it works fine.

Can't pass an argument to pool function

Hi there. PHP 7.4.0RC1, CentOS 7.6.1810. Setup using composer.
Trying to execute this code:

<?php
require_once('/root/vendor/autoload.php');
use Spatie\Async\Pool;
$pool = Pool::create();

$collect = 'COLLECT';
for ($i=0; $i < 3; $i++) { 
	$pool -> add(function() use($collect){
		$collect .= "\n" . 1;
	}) -> catch(function($exception){
		echo($exception . "\n");
	});
}
$pool->wait();

echo($collect);

Got 3 warnings like that:

Spatie\Async\Output\ParallelError: PHP Warning: include(): Opis\Closure\ClosureStream::stream_set_option is not implemented! in /root/vendor/opis/closure/src/SerializableClosure.php on line 257
in /root/vendor/spatie/async/src/Output/ParallelError.php:11
Stack trace:
#0 /root/vendor/spatie/async/src/Process/ParallelProcess.php(126): Spatie\Async\Output\ParallelError::fromException()
#1 /root/vendor/spatie/async/src/Process/ProcessCallbacks.php(54): Spatie\Async\Process\ParallelProcess->resolveErrorOutput()
#2 /root/vendor/spatie/async/src/Process/ProcessCallbacks.php(38): Spatie\Async\Process\ParallelProcess->triggerError()
#3 /root/vendor/spatie/async/src/Pool.php(182): Spatie\Async\Process\ParallelProcess->triggerSuccess()
#4 /root/vendor/spatie/async/src/Pool.php(295): Spatie\Async\Pool->markAsFinished()
#5 /root/vendor/spatie/async/src/Pool.php(131): Spatie\Async\Pool->Spatie\Async{closure}()
#6 /home/tor-fake/web/hydraruma6mcunvp.onion/public_html/test.php(14): Spatie\Async\Pool->wait()
#7 {main}

...but, most importantly, the function does not work at all, at the end php echoes just 'COLLECT', while it should be different as you may see.
Can anyone please say what exactly I do wrong?

Can't run this package on php 7.2

I used this package on server centos AWS . (it worked)
But not run with centos (server Vietnamese ) . and it show error

// log error like this
closure://function () use ($product, $orderId,$amount) {
$image = null;
$unit = $product['unit'] ?? $product['unit_name'];
$image = $product['product']['thumbnail'] ?? $product['thumbnail'];
$data = new \SHL\Order\Entities\OrderProduct();
$data->product_id = $product['pid'];
$data->name = $product['name'];
$data->thumbnail = $image;
$data->order_id = $orderId;
$data->quantity = $product['quantity'];
$data->price = $product['price'];
$data->unit = $unit;
$data->total_price = $amount;
$data->save();
\SHL\Product\Entities\Product::remainingProduct($product['pid'], $product['quantity']);
$output[] = $data;
return $output;
}(15): Illuminate\Database\Eloquent\Model->save()
vendor/spatie/async/src/Runtime/ChildRuntime.php(25): Opis\Closure\SerializableClosure->{closure}()

Support chunked execution

@sebastiandedeyne noticed a huge performance improvement when there are a lot of small tasks ran in parallel, by chunking them together. This way there can be a balance between the process creation overhead and the large amount of small tasks to be done.

This should be a configurable method on the Pool:

Pool::create()
    ->tasksPerProcess(20);

Support simple invokable class

A simple class with the __invoke method should be able to be serialised and ran in the child process, same like passing a closure.

The serialized output may only be 10240 bytes long. - Is there a reason for this limit?

I want to get html responses from my callback, but this limit isn't allowing me to. Just wondering if there's a reason for this limit? Could be be something that's overridable?

$pool[] = async(function () use ($url) {
    $response = parent::request('GET', $url);

    // ...

    return $response->getBody()->getContents();
})->then(function ($response) use ($pool) {
    // ...
});

This limit is set in vendor/spatie/async/src/Runtime/ChildRuntime.php:29
$outputLength = 1024 * 10;

Parallel Error

I installed the package for a week and it gives me the same error
i created simple api to test the package
i have already posix and pcntl extentions and i called isSupported function that came with the packege
and it returned true

my operting system ubuntu 16.04
php version 7.2

that is my code

`Route::get('spatie',function (){

$pool = Pool::create();
$things=[1,2,3];
foreach ($things as $thing) {
    $pool->add(function () use ($thing) {
        return $thing;
    })->then(function ($output) {
        return $output;
    })->catch(function (Throwable $exception) {
        dd($exception);
    });
}

dd($pool->wait());

});`

and this is the error came to me
spatie

ParallelError without knowing the error

I'm getting this error:

{
  "message": "",
  "exception": "Spatie\\Async\\Output\\ParallelError",
  "file": "/var/www/vendor/spatie/async/src/Output/ParallelError.php",
  "line": 11,
  "trace": [
    {
      "file": "/var/www/vendor/spatie/async/src/Process/ParallelProcess.php",
      "line": 126,
      "function": "fromException",
      "class": "Spatie\\Async\\Output\\ParallelError",
      "type": "::"
    },
    {
      "file": "/var/www/vendor/spatie/async/src/Process/ProcessCallbacks.php",
      "line": 54,
      "function": "resolveErrorOutput",
      "class": "Spatie\\Async\\Process\\ParallelProcess",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/spatie/async/src/Pool.php",
      "line": 203,
      "function": "triggerError",
      "class": "Spatie\\Async\\Process\\ParallelProcess",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/spatie/async/src/Pool.php",
      "line": 299,
      "function": "markAsFailed",
      "class": "Spatie\\Async\\Pool",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/opis/closure/src/SerializableClosure.php",
      "line": 600,
      "function": "Spatie\\Async\\{closure}",
      "class": "Spatie\\Async\\Pool",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/opis/closure/src/SerializableClosure.php",
      "line": 609,
      "function": "mapByReference",
      "class": "Opis\\Closure\\SerializableClosure",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/opis/closure/src/SerializableClosure.php",
      "line": 609,
      "function": "mapByReference",
      "class": "Opis\\Closure\\SerializableClosure",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/opis/closure/src/SerializableClosure.php",
      "line": 650,
      "function": "mapByReference",
      "class": "Opis\\Closure\\SerializableClosure",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/opis/closure/src/SerializableClosure.php",
      "line": 609,
      "function": "mapByReference",
      "class": "Opis\\Closure\\SerializableClosure",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/opis/closure/src/SerializableClosure.php",
      "line": 148,
      "function": "mapByReference",
      "class": "Opis\\Closure\\SerializableClosure",
      "type": "->"
    },
    {
      "function": "serialize",
      "class": "Opis\\Closure\\SerializableClosure",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/opis/closure/functions.php",
      "line": 20,
      "function": "serialize"
    },
    {
      "file": "/var/www/vendor/spatie/async/src/Runtime/ParentRuntime.php",
      "line": 87,
      "function": "Opis\\Closure\\serialize"
    },
    {
      "file": "/var/www/vendor/spatie/async/src/Runtime/ParentRuntime.php",
      "line": 70,
      "function": "encodeTask",
      "class": "Spatie\\Async\\Runtime\\ParentRuntime",
      "type": "::"
    },
    {
      "file": "/var/www/vendor/spatie/async/src/Pool.php",
      "line": 120,
      "function": "createProcess",
      "class": "Spatie\\Async\\Runtime\\ParentRuntime",
      "type": "::"
    },
    {
      "file": "/var/www/app/Http/Controllers/NewPathController.php",
      "line": 66,
      "function": "add",
      "class": "Spatie\\Async\\Pool",
      "type": "->"
    },
    {
      "function": "__invoke",
      "class": "App\\Http\\Controllers\\NewPathController",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
      "line": 54,
      "function": "call_user_func_array"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
      "line": 45,
      "function": "callAction",
      "class": "Illuminate\\Routing\\Controller",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
      "line": 212,
      "function": "dispatch",
      "class": "Illuminate\\Routing\\ControllerDispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
      "line": 169,
      "function": "runController",
      "class": "Illuminate\\Routing\\Route",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 665,
      "function": "run",
      "class": "Illuminate\\Routing\\Route",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 30,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/barryvdh/laravel-cors/src/HandleCors.php",
      "line": 36,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Barryvdh\\Cors\\HandleCors",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
      "line": 41,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 104,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 667,
      "function": "then",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 642,
      "function": "runRouteWithinStack",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 608,
      "function": "runRoute",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 597,
      "function": "dispatchToRoute",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 176,
      "function": "dispatch",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 30,
      "function": "Illuminate\\Foundation\\Http\\{closure}",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/fideloper/proxy/src/TrustProxies.php",
      "line": 57,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Fideloper\\Proxy\\TrustProxies",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
      "line": 31,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
      "line": 31,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
      "line": 27,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php",
      "line": 62,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/barryvdh/laravel-cors/src/HandlePreflight.php",
      "line": 29,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Barryvdh\\Cors\\HandlePreflight",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 104,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 151,
      "function": "then",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 116,
      "function": "sendRequestThroughRouter",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    },
    {
      "file": "/var/www/public/index.php",
      "line": 55,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    }
  ]
}

This is my code:

$pool = Pool::create();

$i = 1;

foreach ($stationsFrom as $stationFrom) {
            foreach ($stationsTo as $stationTo) {
                $pool->add(function () use ($dijkstra, $stationFrom, $stationTo, &$i) {
                    logger("ciclo {$i}", [$stationFrom->id, $stationTo->id]);

                    $i++;

                    return $dijkstra->shortestPaths($stationFrom->id, $stationTo->id);
                })->then(function (array $paths) use (&$alternatives) {
                    /** @var \Illuminate\Support\Collection|int[][] $shortestPaths */
                    $shortestPaths = collect($paths);

                    // El primero es el de menos costo dentro de la iteración.

                    /** @var int[] $stationIds */
                    $stationIds = $shortestPaths->first();

                    $alternatives->push($stationIds);
                    // $this->fillAlternatives($alternatives, $stationIds);
                })->catch(function ($exception) {
                    throw $exception;
                });
            }
        }

$pool->wait();

I'm using throw $exception; to see the details of the problem but I cannot see anything that helps me to debug. I don't even see the manual log that I use.

This is the log file:

[2019-07-04 16:04:29] local.ERROR:  {"exception":"[object] (Spatie\\Async\\Output\\ParallelError(code: 0):  at /var/www/vendor/spatie/async/src/Output/ParallelError.php:11)
[stacktrace]
#0 /var/www/vendor/spatie/async/src/Process/ParallelProcess.php(126): Spatie\\Async\\Output\\ParallelError::fromException('')
#1 /var/www/vendor/spatie/async/src/Process/ProcessCallbacks.php(54): Spatie\\Async\\Process\\ParallelProcess->resolveErrorOutput()
#2 /var/www/vendor/spatie/async/src/Pool.php(203): Spatie\\Async\\Process\\ParallelProcess->triggerError()
#3 /var/www/vendor/spatie/async/src/Pool.php(299): Spatie\\Async\\Pool->markAsFailed(Object(Spatie\\Async\\Process\\ParallelProcess))
#4 /var/www/vendor/opis/closure/src/SerializableClosure.php(600): Spatie\\Async\\Pool->Spatie\\Async\\{closure}(17, Array)
#5 /var/www/vendor/opis/closure/src/SerializableClosure.php(609): Opis\\Closure\\SerializableClosure->mapByReference(65)
#6 /var/www/vendor/opis/closure/src/SerializableClosure.php(609): Opis\\Closure\\SerializableClosure->mapByReference(Array)
#7 /var/www/vendor/opis/closure/src/SerializableClosure.php(650): Opis\\Closure\\SerializableClosure->mapByReference(Array)
#8 /var/www/vendor/opis/closure/src/SerializableClosure.php(609): Opis\\Closure\\SerializableClosure->mapByReference(Object(Fisharebest\\Algorithm\\Dijkstra))
#9 /var/www/vendor/opis/closure/src/SerializableClosure.php(148): Opis\\Closure\\SerializableClosure->mapByReference(Array)
#10 [internal function]: Opis\\Closure\\SerializableClosure->serialize()
#11 /var/www/vendor/opis/closure/functions.php(20): serialize(Object(Opis\\Closure\\SerializableClosure))
#12 /var/www/vendor/spatie/async/src/Runtime/ParentRuntime.php(87): Opis\\Closure\\serialize(Object(Opis\\Closure\\SerializableClosure))
#13 /var/www/vendor/spatie/async/src/Runtime/ParentRuntime.php(70): Spatie\\Async\\Runtime\\ParentRuntime::encodeTask(Object(Opis\\Closure\\SerializableClosure))
#14 /var/www/vendor/spatie/async/src/Pool.php(120): Spatie\\Async\\Runtime\\ParentRuntime::createProcess(Object(Closure))
#15 /var/www/app/Http/Controllers/NewPathController.php(66): Spatie\\Async\\Pool->add(Object(Closure))
#16 [internal function]: App\\Http\\Controllers\\NewPathController->__invoke(Object(App\\Http\\Requests\\PathRequest))
#17 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
#18 /var/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('__invoke', Array)
#19 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\NewPathController), '__invoke')
#20 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(169): Illuminate\\Routing\\Route->runController()
#21 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(665): Illuminate\\Routing\\Route->run()
#22 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#23 /var/www/vendor/barryvdh/laravel-cors/src/HandleCors.php(36): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#24 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Barryvdh\\Cors\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#25 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#26 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#27 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#28 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#29 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#30 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(667): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#31 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(642): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#32 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(608): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#33 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(597): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#34 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#35 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#36 /var/www/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#37 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#38 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#39 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(31): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#40 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#41 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#42 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(31): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#43 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#44 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#45 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#46 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#47 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#48 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#49 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#50 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#51 /var/www/vendor/barryvdh/laravel-cors/src/HandlePreflight.php(29): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#52 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Barryvdh\\Cors\\HandlePreflight->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#53 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#54 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#55 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#56 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#57 /var/www/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#58 {main}
"} 

Using this package would be really helpful for me. Thanks in advance!

Test timeout on Travis

The Travis build sometimes marks processes as timed out: https://travis-ci.org/spatie/async/jobs/324132071

We should further investigate this.

  • The error doesn't happen consistently.
  • We're not sure whether this can be reproduced in real environments - yet.
  • We're making assumptions about process execution time in our tests which aren't 100% accurate. For example: 5 parallel processes each sleeping for 1ms should have an execution time of less then 2ms. We're actually not in charge of managing process execution, the kernel is. So there is a chance these processes aren't executed in parallel. It's my guess that's what's happening with Travis, because you're only getting a small container to work with.

I think we need a few things:

  • Followup for similar issues in real environments, if this error occurs there, this issue needs to be prioritised.
  • More timeout information in PoolStatus.
  • A better way to test for process execution.

PHP Warning: stat(): stat failed in ClosureStream

Hi Spatie, firstly thank you for the amazing work!

The following code provides the above exception:

$pool = Pool::create();

for ($i = 0; $i < 100; $i++) {

    $pool[] = async(function () {
        return 1;
    });
}

$pool->wait();

Making the loop less than 50 fixes the issue. What could be the cause?

Serialization of xy is not allowed while passing objects as callback values to use

Thank for this library. I'm eager to try out and see the speedup on @Rector, just came across one issue while running this code:

$i = 0;

$pool = Pool::create();

/** @var SplFileInfo $fileInfo */
foreach ($fileInfos as $fileInfo) {
    $pool->add(function () use ($fileInfo, $i) {  // <--------------- here is the issue
        // long-durring process
        $this->processFile($fileInfo, $i);
    })->then(function () {
        // success
        $this->consoleStyle->progressAdvance();
    })->catch(function (Throwable $throwable) use ($fileInfo) {
        // fail
        $this->consoleStyle->newLine();
        throw new FileProcessingException(
            sprintf('Processing of "%s" file failed.', $fileInfo->getPathname()),
            $throwable->getCode(),
            $throwable
        );
    });
}

$pool->wait();

I get this exception:

In SerializableClosure.php line 156:
                                                                          
  [Exception]                                                             
  Serialization of 'Symfony\Component\Finder\SplFileInfo' is not allowed 

It's realated probably to object SplFileInfo serialization, which is one of arguments, by Opis\Closure\SerializableClosure. It's called in $pool->add()

Do you have any suggesstion how to solve this?

I cannot pass string, becase I work with the object further in the method.

can't install this package

I am trying to install it through composer require spatie/async and getting this error

[InvalidArgumentException] Could not find package spatie/async at any version matching your PHP version 7.0.32.0
also I tried
composer require spatie/async --ignore-platform-reqs
same error

error: undefined function Spatie\Async\pcntl_async_signals()

getting this error:

(1/1) FatalThrowableErrorCall to undefined function Spatie\Async\pcntl_async_signals()

in Pool.php line 263
at Pool->registerListener()in Pool.php line 42
at Pool->__construct()in Pool.php line 52

here is my code:
```php
$pool = Pool::create();

            $pool->add(function () use ($thing) { 
                $token = (array)json_decode($this->getRefreshedToken($user));
                \Log::info(json_encode( $token));
            })->then(function ($output) {
               // return $output;
                // Handle success
                  \Log::info($output);
            })->catch(function (Throwable $exception) {
                // Handle exception
            });

Can not handle multi error events

When an exception throw in child runtime process only one event can trigger because a break statement #67 ProcessCallbacks, I think we should remove it because some case need to catch multi exception like try catch, an exception throwed may match multi is_a parents exception and success, timeout can handle multi events but error is not?

Call to undefined method SynchronousProcess::resolveErrorOutput() in ProcessCallbacks.php:54

PHP Fatal error: Uncaught Error: Call to undefined method Spatie\Async\Process\SynchronousProcess::resolveErrorOutput() in vendor\spatie\async\src\Process\ProcessCallbacks.php:54

Library version: 1.0.2 & 1.0.3
Run on windows 10 via gitbash.

It seems that moving \Spatie\Async\Process\ParallelProcess::resolveErrorOutput to the \Spatie\Async\Process\ProcessCallbacks trait solves the issue but it doesnt look right cos of usage of \Spatie\Async\Output\ParallelError.

Configurable executable

My hoster has multiple php executables installed. The „php“ command defaults to php 5.6 which wont work as the parent app runs php 7.3 because this lib spawns childs at php 5.6.
I think its this line of code:

How can I get it to work so the child progess also uses PHP 7.3?

Module 'pcntl' already loaded

@zelin wasn't able to create an issue, so I'm doing it for you.

#0 Pushbot/src/Pushbot/Async/Process/ParallelProcess.php(126): Pushbot\Async\Output\ParallelError::fromException('PHP Warning:  M...')
#1 Pushbot/src/Pushbot/Async/Process/ProcessCallbacks.php(51): Pushbot\Async\Process\ParallelProcess->resolveErrorOutput()
#2 Pushbot/src/Pushbot/Async/Pool.php(201): Pushbot\Async\Process\ParallelProcess->triggerError()
#3 Pushbot/src/Pushbot/Async/Pool.php(297): Pushbot\Async\Pool->markAsFailed(Object(Pushbot\Async\Process\ParallelProcess))
#4 Pushbot/src/Pushbot/Async/Pool.php(128): Pushbot\Async\Pool->Pushbot\Async\{closure}(20, Array)
#5 Pushbot/src/Pushbot/Pushbot.php(421): Pushbot\Async\Pool->wait()

Parallel error: Spatie\Async\Output\ParallelError

Supported 1
Supported1
Supported1
Spatie\Async\Output\ParallelError in /home/el/Php Storm Projects/parallel/vendor/spatie/async/src/Output/ParallelError.php:11 Stack trace: #0 /home/el/Php Storm Projects/parallel/vendor/spatie/async/src/Process/ParallelProcess.php(126): Spatie\Async\Output\ParallelError::fromException('') #1 /home/el/Php Storm Projects/parallel/vendor/spatie/async/src/Process/ProcessCallbacks.php(51): Spatie\Async\Process\ParallelProcess->resolveErrorOutput() #2

code

$pool = Pool::create();
$supported = Pool::isSupported();
echo "Supported"." ".$supported." "."
";
echo "Supported".extension_loaded('posix')."
";
echo "Supported".extension_loaded('pcntl')."
";

$pool
    ->add(function () {
        // ...
    })
    ->then(function ($output) {
        // On success, `$output` is returned by the process or callable you passed to the queue.
    });
await($pool);

}
catch (Exception $ex)
{
echo $ex;
}
return "succeded";

Display output of forked scripts

I have scripts that have their own output messages (informative kind) that are not shown when scripts are forked with async.

Is there a way to get output of forked scripts with async library?

I know that there is an getOutput() function, but it throws an error that process needs to be started first to use the getOutput() on it.

I have used barracudanetworks/fork-daemon before i started using spatie/async and i was passing exec/passthrough or shell_exec depending on user selection how to display output of scripts, or not to display it at all.

I do use ->then to display message after script is done, but it is not quite there for my use case.

Debugging errors

My code:

        $pool = Pool::create();

    	foreach ($xmlNode->childNodes as $item) {
            $pool[] = async(function () use ($item) {
                     //do stuff
                      ...
                     //do more stuff
                     ...
                }
            })->then(function ($output) {
                //handle success
            })->catch(function ($ex) {
                echo PHP_EOL . "something happened, exception. Error: ".$ex->getMessage();
            })->timeout(function () {
                echo PHP_EOL . "timed out";
            });
    	}
        await($pool);

Output:

something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:
something happened, exception. Error:

How do I debug the issue? The exception message doesn't seem to be showing. If I just log the exception, instead of the message, I get:

something happened, exception. Error: Spatie\Async\Output\ParallelError in /home/sayan/Documents/Programming/spatie_test/vendor/spatie/async/src/Output/ParallelError.php:11
Stack trace:
#0 /home/sayan/Documents/Programming/spatie_test/vendor/spatie/async/src/Process/ParallelProcess.php(126): Spatie\Async\Output\ParallelError::fromException('')
#1 /home/sayan/Documents/Programming/spatie_test/vendor/spatie/async/src/Process/ProcessCallbacks.php(51): Spatie\Async\Process\ParallelProcess->resolveErrorOutput()
#2 /home/sayan/Documents/Programming/spatie_test/vendor/spatie/async/src/Pool.php(197): Spatie\Async\Process\ParallelProcess->triggerError()
#3 /home/sayan/Documents/Programming/spatie_test/vendor/spatie/async/src/Pool.php(285): Spatie\Async\Pool->markAsFailed(Object(Spatie\Async\Process\ParallelProcess))
#4 /home/sayan/Documents/Programming/spatie_test/vendor/spatie/async/src/Runtime/ParentRuntime.php(70): Spatie\Async\Pool->Spatie\Async{closure}(17, Array)
#5 /home/sayan/Documents/Programming/spatie_test/vendor/spatie/async/src/helpers.php(15): Spatie\Async\Runtime\ParentRuntime::createProcess(Object(Closure))
#6 /home/sayan/Documents/Programming/spatie_test/test.php(84): async(Object(Closure))
#7 /home/sayan/Documents/Programming/spatie_test/test.php(50): Test->getListings(Object(DOMElement))
#8 /home/sayan/Documents/Programming/spatie_test/test.php(221): Test->process()
#9 {main}

InvalidArgumentException : Unknown setter 'date'

In laravel i'm has exception:

InvalidArgumentException : Unknown setter 'date'

at /var/www/{PH}/data/www/{PH}/vendor/nesbot/carbon/src/Carbon/Traits/Date.php:1187
1183| break;
1184| }
1185|
1186| if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) {

1187| throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
1188| }
1189|
1190| $this->$name = $value;
1191| }

Exception trace:

1 Carbon\Carbon::set("date", "2019-12-16 11:16:44.617064")
/var/www/{PH}/data/www/{PH}/vendor/nesbot/carbon/src/Carbon/Traits/Date.php:1063

2 Carbon\Carbon::__set("date", "2019-12-16 11:16:44.617064")
[internal]:0

Please use the argument -v to see more details.

What is this?

Code in artisan command:

$pool->add(function () use ($task, $step, $sender, $login, $password, $key, $args, $que, $chanel, $_this) {
...
})->then( ... );

Never to use Carbon in my app, but him is give me exception on work.
If i'm disabled or removing Pool from script, him has normal work.

Process mails using it

I am really confused where to ask questions about (so asking here). Sorry if there is any mistake.

I have a scenario where there are some users. On performing certain requests there will be a mail sent to them and the user has to wait for the response (i.e till the mail is sent). I don't want this to happen. I want to make up a response alike 'you will be receiving mail in few minutes' and sent it to them. Then later I want to send the mail asynchronously. Is it possible with this package ??

Please comment if there are any misconceptions

Can't install on laravel 5.4

When I run the command (composer require spatie/async) it gives the below output -
Problem 1
- Installation request for spatie/async ^0.0.4 -> satisfiable by spatie/async[0.0.4].
- Conclusion: remove symfony/process v3.2.6
- Conclusion: don't install symfony/process v3.2.6
- spatie/async 0.0.4 requires symfony/process ^3.3 || ^4.0 -> satisfiable by symfony/process[v3.3.0, v3.3.1, v3.3.10, v3.3.11, v3.3.12, v3.3.13, v3.3.14, v3.3.15, v3.3.16, v3.3.17, v3.3.18, v3.3.2, v3.3.3, v3.3.4, v3.3.5, v3.3.6, v3.3.7, v3.3.8, v3.3.9, v3.4.0, v3.4.1, v3.4.10, v3.4.11, v3.4.12, v3.4.13, v3.4.14, v3.4.15, v3.4.16, v3.4.17, v3.4.2, v3.4.3, v3.4.4, v3.4.5, v3.4.6, v3.4.7, v3.4.8, v3.4.9, v4.0.0, v4.0.1, v4.0.10, v4.0.11, v4.0.12, v4.0.13, v4.0.14, v4.0.2, v4.0.3, v4.0.4, v4.0.5, v4.0.6, v4.0.7, v4.0.8, v4.0.9, v4.1.0, v4.1.1, v4.1.2, v4.1.3, v4.1.4, v4.1.5, v4.1.6].
- Can only install one of: symfony/process[v3.3.0, v3.2.6].
- Can only install one of: symfony/process[v3.3.1, v3.2.6].
- Can only install one of: symfony/process[v3.3.10, v3.2.6].
- Can only install one of: symfony/process[v3.3.11, v3.2.6].
- Can only install one of: symfony/process[v3.3.12, v3.2.6].
- Can only install one of: symfony/process[v3.3.13, v3.2.6].
- Can only install one of: symfony/process[v3.3.14, v3.2.6].
- Can only install one of: symfony/process[v3.3.15, v3.2.6].
- Can only install one of: symfony/process[v3.3.16, v3.2.6].
- Can only install one of: symfony/process[v3.3.17, v3.2.6].
- Can only install one of: symfony/process[v3.3.18, v3.2.6].
- Can only install one of: symfony/process[v3.3.2, v3.2.6].
- Can only install one of: symfony/process[v3.3.3, v3.2.6].
- Can only install one of: symfony/process[v3.3.4, v3.2.6].
- Can only install one of: symfony/process[v3.3.5, v3.2.6].
- Can only install one of: symfony/process[v3.3.6, v3.2.6].
- Can only install one of: symfony/process[v3.3.7, v3.2.6].
- Can only install one of: symfony/process[v3.3.8, v3.2.6].
- Can only install one of: symfony/process[v3.3.9, v3.2.6].
- Can only install one of: symfony/process[v3.4.0, v3.2.6].
- Can only install one of: symfony/process[v3.4.1, v3.2.6].
- Can only install one of: symfony/process[v3.4.10, v3.2.6].
- Can only install one of: symfony/process[v3.4.11, v3.2.6].
- Can only install one of: symfony/process[v3.4.12, v3.2.6].
- Can only install one of: symfony/process[v3.4.13, v3.2.6].
- Can only install one of: symfony/process[v3.4.14, v3.2.6].
- Can only install one of: symfony/process[v3.4.15, v3.2.6].
- Can only install one of: symfony/process[v3.4.16, v3.2.6].
- Can only install one of: symfony/process[v3.4.17, v3.2.6].
- Can only install one of: symfony/process[v3.4.2, v3.2.6].
- Can only install one of: symfony/process[v3.4.3, v3.2.6].
- Can only install one of: symfony/process[v3.4.4, v3.2.6].
- Can only install one of: symfony/process[v3.4.5, v3.2.6].
- Can only install one of: symfony/process[v3.4.6, v3.2.6].
- Can only install one of: symfony/process[v3.4.7, v3.2.6].
- Can only install one of: symfony/process[v3.4.8, v3.2.6].
- Can only install one of: symfony/process[v3.4.9, v3.2.6].
- Can only install one of: symfony/process[v4.0.0, v3.2.6].
- Can only install one of: symfony/process[v4.0.1, v3.2.6].
- Can only install one of: symfony/process[v4.0.10, v3.2.6].
- Can only install one of: symfony/process[v4.0.11, v3.2.6].
- Can only install one of: symfony/process[v4.0.12, v3.2.6].
- Can only install one of: symfony/process[v4.0.13, v3.2.6].
- Can only install one of: symfony/process[v4.0.14, v3.2.6].
- Can only install one of: symfony/process[v4.0.2, v3.2.6].
- Can only install one of: symfony/process[v4.0.3, v3.2.6].
- Can only install one of: symfony/process[v4.0.4, v3.2.6].
- Can only install one of: symfony/process[v4.0.5, v3.2.6].
- Can only install one of: symfony/process[v4.0.6, v3.2.6].
- Can only install one of: symfony/process[v4.0.7, v3.2.6].
- Can only install one of: symfony/process[v4.0.8, v3.2.6].
- Can only install one of: symfony/process[v4.0.9, v3.2.6].
- Can only install one of: symfony/process[v4.1.0, v3.2.6].
- Can only install one of: symfony/process[v4.1.1, v3.2.6].
- Can only install one of: symfony/process[v4.1.2, v3.2.6].
- Can only install one of: symfony/process[v4.1.3, v3.2.6].
- Can only install one of: symfony/process[v4.1.4, v3.2.6].
- Can only install one of: symfony/process[v4.1.5, v3.2.6].
- Can only install one of: symfony/process[v4.1.6, v3.2.6].
- Installation request for symfony/process (locked at v3.2.6) -> satisfiable by symfony/process[v3.2.6].
Installation failed, reverting ./composer.json to its original content.

Unable to install on Laravel 5.2

Required symfony/process version is ^3.3, but laravel 5.2 has symfony/process version 3.0.*
Is there something we can do about this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.