diff --git a/examples/BlockingTask.php b/examples/BlockingTask.php deleted file mode 100644 index 361a271..0000000 --- a/examples/BlockingTask.php +++ /dev/null @@ -1,42 +0,0 @@ -function = $function; - $this->args = $args; - } - - /** - * {@inheritdoc} - */ - public function run(Environment $environment) - { - return ($this->function)(...$this->args); - } - - public function getArgs() - { - return $this->args; - } -} diff --git a/examples/worker-pool-simple.php b/examples/worker-pool-simple.php new file mode 100644 index 0000000..bf66224 --- /dev/null +++ b/examples/worker-pool-simple.php @@ -0,0 +1,24 @@ +#!/usr/bin/env php + $response) { + \printf("Read %d bytes from %s\n", \strlen($response), $url); +} diff --git a/examples/worker-pool.php b/examples/worker-pool.php index 71bc9f1..d21216c 100755 --- a/examples/worker-pool.php +++ b/examples/worker-pool.php @@ -1,9 +1,10 @@ #!/usr/bin/env php create(); - $result = yield $worker->enqueue(new BlockingTask('file_get_contents', 'https://google.com')); + $result = yield $worker->enqueue(new CallableTask('file_get_contents', 'https://google.com')); \printf("Read %d bytes\n", \strlen($result)); $code = yield $worker->shutdown(); diff --git a/lib/Worker/CallableTask.php b/lib/Worker/CallableTask.php new file mode 100644 index 0000000..5c93a8a --- /dev/null +++ b/lib/Worker/CallableTask.php @@ -0,0 +1,38 @@ +callable = $callable; + $this->args = $args; + } + + public function run(Environment $environment) + { + if ($this->callable instanceof \__PHP_Incomplete_Class) { + throw new \Error('When using a class instance as a callable, the class must be autoloadable'); + } + + if (\is_array($this->callable) && ($this->callable[0] ?? null) instanceof \__PHP_Incomplete_Class) { + throw new \Error('When using a class instance method as a callable, the class must be autoloadable'); + } + + return ($this->callable)(...$this->args); + } +} diff --git a/lib/Worker/functions.php b/lib/Worker/functions.php index 8e096ef..90b97b6 100644 --- a/lib/Worker/functions.php +++ b/lib/Worker/functions.php @@ -33,15 +33,28 @@ function pool(Pool $pool = null): Pool /** * Enqueues a task to be executed by the global worker pool. * - * @param \Amp\Parallel\Worker\Task $task The task to enqueue. + * @param Task $task The task to enqueue. * - * @return \Amp\Promise + * @return Promise */ function enqueue(Task $task): Promise { return pool()->enqueue($task); } +/** + * Enqueues a callable to be executed by the global worker pool. + * + * @param callable $callable Callable needs to be serializable. + * @param mixed ...$args Arguments have to be serializable. + * + * @return Promise + */ +function enqueueCallable(callable $callable, ...$args) +{ + return enqueue(new CallableTask($callable, $args)); +} + /** * Gets a worker from the global worker pool. * diff --git a/test/Worker/FunctionsTest.php b/test/Worker/FunctionsTest.php index ea1d269..a639e4b 100644 --- a/test/Worker/FunctionsTest.php +++ b/test/Worker/FunctionsTest.php @@ -44,6 +44,40 @@ class FunctionsTest extends TestCase $this->assertSame($value, Promise\wait($awaitable)); } + /** + * @depends testPool + */ + public function testEnqueueCallable() + { + $pool = $this->createMock(Pool::class); + $pool->method('enqueue') + ->will($this->returnCallback(function (Task $task): Promise { + return new Success($task->run($this->createMock(Environment::class))); + })); + + Worker\pool($pool); + + $value = 42; + + $promise = Worker\enqueueCallable('strval', $value); + + $this->assertSame('42', Promise\wait($promise)); + } + + /** + * @depends testEnqueueCallable + */ + public function testEnqueueCallableIntegration() + { + Worker\pool(new Worker\DefaultPool()); + + $value = 42; + + $promise = Worker\enqueueCallable('strval', $value); + + $this->assertSame('42', Promise\wait($promise)); + } + /** * @depends testPool */ @@ -79,7 +113,6 @@ class FunctionsTest extends TestCase ->will($this->returnValue($this->createMock(Worker\Worker::class))); Worker\factory($factory); - - $worker = Worker\create(); + Worker\create(); // shouldn't throw } }