async
async copied to clipboard
Fatal error: Uncaught TypeError: call_user_func_array(): Argument #1 ($callback) must be a valid callback, no array or string given
Hi. I was experimenting with Spatie/Async and I was able to have it working on a Symfony console Command. But if I grab the same code, adapt it and to run it without the Symfony framework, I get the following error:
1
Fatal error: Uncaught TypeError: call_user_func_array(): Argument #1 ($callback) must be a valid callback, no array or string given
#0 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/laravel/serializable-closure/src/Serializers/Native.php(91): call_user_func_array(NULL, Array)
#1 [internal function]: Laravel\SerializableClosure\Serializers\Native->__invoke()
#2 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/laravel/serializable-closure/src/SerializableClosure.php(48): call_user_func_array(Object(Laravel\SerializableClosure\Serializers\Native), Array)
#3 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Runtime/ChildRuntime.php(26): Laravel\SerializableClosure\SerializableClosure->__invoke()
#4 {main} in /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Output/SerializableException.php:29
Stack trace:
#0 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Process/ParallelProcess.php(121): Spatie\Async\Output\SerializableException->asThrowable()
#1 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Process/ProcessCallbacks.php(54): Spatie\Async\Process\ParallelProcess->resolveErrorOutput()
#2 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Pool.php(246): Spatie\Async\Process\ParallelProcess->triggerError()
#3 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Pool.php(363): Spatie\Async\Pool->markAsFailed(Object(Spatie\Async\Process\ParallelProcess))
#4 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Pool.php(344): Spatie\Async\Pool->handleFinishedProcess(41131, 1)
#5 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Pool.php(168): Spatie\Async\Pool->Spatie\Async\{closure}(20, Array)
#6 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/helpers.php(22): Spatie\Async\Pool->wait()
#7 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/index.php(57): await(Object(Spatie\Async\Pool))
#8 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/index.php(14): ParallelSumCommand->calculate(1)
#9 /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/index.php(69): ParallelSumCommand->execute()
#10 {main}
thrown in /Users/pedropiedade/Documents/http/pedro/code-challenges/sums/vendor/spatie/async/src/Output/SerializableException.php on line 29
Here is the code:
include './vendor/autoload.php';
use Spatie\Async\Pool;
class ParallelSumCommand
{
protected int $sum = 0;
public function execute(): int
{
$test = $this->calculate(1);
echo sprintf("The sum of all even numbers from %d to %d is %d", $test['min'], $test['max'], $test['sum']);
echo sprintf("This sum took %d miliseconds to calculate using %d parallel threads\n", $test['time'], $test['channels']);
$test = $this->calculate(5);
echo sprintf("The sum of all even numbers from %d to %d is %d", $test['min'], $test['max'], $test['sum']);
echo sprintf("This sum took %d miliseconds to calculate using %d parallel threads\n", $test['time'], $test['channels']);
$test = $this->calculate(10);
echo sprintf("The sum of all even numbers from %d to %d is %d", $test['min'], $test['max'], $test['sum']);
echo sprintf("This sum took %d miliseconds to calculate using %d parallel threads\n", $test['time'], $test['channels']);
$test = $this->calculate(20);
echo sprintf("The sum of all even numbers from %d to %d is %d", $test['min'], $test['max'], $test['sum']);
echo sprintf("This sum took %d miliseconds to calculate using %d parallel threads\n", $test['time'], $test['channels']);
return 1;
}
protected function calculate(int $channels): array
{
$pool = Pool::create()->concurrency($channels);
$rangeMin = 1;
$rangeMax = 100000000;
$currentMin = $rangeMin;
$step = intval(($rangeMax - $rangeMin) / $channels);
$start = microtime(true);
$this->sum = 0;
for ($i=0; $i <= $channels; $i++) {
$currentMax = $currentMin + $step;
$pool[] = async(function () use ($currentMin, $currentMax, $rangeMax) {
$sum = 0;
$max = min($currentMax, $rangeMax);
for ($i=$currentMin; $i <= $max; $i++) {
if($i % 2 === 0) {
$sum += $i;
}
}
return $sum;
})->then(function (int $output) {
$this->sum += $output;
});
$currentMin = $currentMax + 1;
}
await($pool);
$end = microtime(true);
return [
'min' => $rangeMin,
'max' => $rangeMax,
'channels' => $channels,
'time' => ($end - $start) * 1000,
'sum' => $this->sum
];
}
}
(new ParallelSumCommand())->execute();
The calculate method is the exact same code in the Symfony and non-Symfony version, just the execute method that changes slightly. Is this some bug or am I doing something wrong?