Skip to content

Commit

Permalink
Merge pull request #213 from gazugafan/master
Browse files Browse the repository at this point in the history
Serialize very large tasks to a temporary file
  • Loading branch information
AlexVanderbist authored Aug 25, 2023
2 parents 24a8ffa + a1eb29a commit 7f7a60f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
13 changes: 13 additions & 0 deletions src/FileTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Spatie\Async;

class FileTask
{
public string $file;

public function __construct(string $file)
{
$this->file = $file;
}
}
12 changes: 11 additions & 1 deletion src/Pool.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class Pool implements ArrayAccess

protected $binary = PHP_BINARY;

protected $max_input_size = 100000;

public function __construct()
{
if (static::isSupported()) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
);
}

Expand Down
28 changes: 23 additions & 5 deletions src/Runtime/ParentRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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,
]);

Expand All @@ -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
Expand Down

0 comments on commit 7f7a60f

Please sign in to comment.