diff --git a/src/FileTask.php b/src/FileTask.php new file mode 100644 index 0000000..9e568b5 --- /dev/null +++ b/src/FileTask.php @@ -0,0 +1,13 @@ +file = $file; + } +} diff --git a/src/Pool.php b/src/Pool.php index 424cfc9..b3e0ad6 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -41,6 +41,8 @@ class Pool implements ArrayAccess protected $binary = PHP_BINARY; + protected $max_input_size = 100000; + public function __construct() { if (static::isSupported()) { @@ -109,6 +111,13 @@ public function withBinary(string $binary): self return $this; } + public function maxInputSize(int $max_size): self + { + $this->max_input_size = $max_size; + + return $this; + } + public function notify() { if (count($this->inProgress) >= $this->concurrency) { @@ -140,7 +149,8 @@ public function add($process, ?int $outputLength = null): Runnable $process = ParentRuntime::createProcess( $process, $outputLength, - $this->binary + $this->binary, + $this->max_input_size ); } diff --git a/src/Runtime/ParentRuntime.php b/src/Runtime/ParentRuntime.php index 181e91f..8616211 100644 --- a/src/Runtime/ParentRuntime.php +++ b/src/Runtime/ParentRuntime.php @@ -4,6 +4,7 @@ use Closure; use Laravel\SerializableClosure\SerializableClosure; +use Spatie\Async\FileTask; use Spatie\Async\Pool; use Spatie\Async\Process\ParallelProcess; use Spatie\Async\Process\Runnable; @@ -52,7 +53,7 @@ public static function init(string $autoloader = null) * * @return \Spatie\Async\Process\Runnable */ - public static function createProcess($task, ?int $outputLength = null, ?string $binary = 'php'): Runnable + public static function createProcess($task, ?int $outputLength = null, ?string $binary = 'php', ?int $max_input_size = 100000): Runnable { if (! self::$isInitialised) { self::init(); @@ -66,7 +67,7 @@ public static function createProcess($task, ?int $outputLength = null, ?string $ $binary, self::$childProcessScript, self::$autoloader, - self::encodeTask($task), + self::encodeTask($task, $max_input_size), $outputLength, ]); @@ -78,18 +79,35 @@ public static function createProcess($task, ?int $outputLength = null, ?string $ * * @return string */ - public static function encodeTask($task): string + public static function encodeTask($task, ?int $max_input_size = 100000): string { if ($task instanceof Closure) { $task = new SerializableClosure($task); } - return base64_encode(serialize($task)); + //serialize the task. If it's too big to pass on the command line, then we'll have to write it to a file and pass the filename instead... + $serialized_task = base64_encode(serialize($task)); + if (strlen($serialized_task) > $max_input_size) { + //write the serialized task to a temporary file... + $filename = tempnam(sys_get_temp_dir(), 'spatie_async_task_'); + file_put_contents($filename, $serialized_task); + $file_task = new FileTask($filename); + $serialized_task = base64_encode(serialize($file_task)); + } + + return $serialized_task; } public static function decodeTask(string $task) { - return unserialize(base64_decode($task)); + $decoded_task = unserialize(base64_decode($task)); + if (get_class($decoded_task) == 'Spatie\Async\FileTask') { + $filename = $decoded_task->file; + $decoded_task = unserialize(base64_decode(file_get_contents($filename))); + unlink($filename); + } + + return $decoded_task; } protected static function getId(): string