Skip to content

Add template types #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"php": "^8.2",
"ext-parallel": "*",
"react-parallel/event-loop": "^2@dev",
"react/event-loop": "^1.1",
"react/promise": "^2.7 || ^3.0",
"react/event-loop": "^1.5",
"react/promise": "^3.1",
"wyrihaximus/constants": "^1.6"
},
"require-dev": {
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions etc/qa/phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ parameters:
- ReactParallel\EventLoop\CancelledException
- ReactParallel\EventLoop\CanceledFuture
- ReactParallel\EventLoop\KilledRuntime
# stubFiles:
# - ../../stubs/Event.stub
# - ../../stubs/Future.stub
# - ../../stubs/Channel.stub
stubFiles:
- ../../stubs/Event.stub
- ../../stubs/Future.stub
- ../../stubs/Channel.stub

includes:
- ../../vendor/wyrihaximus/async-test-utilities/rules.neon
18 changes: 11 additions & 7 deletions src/Runtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@
use Closure;
use parallel\Future;
use parallel\Runtime as ParallelRuntime;
use React\Promise\PromiseInterface;
use ReactParallel\EventLoop\EventLoopBridge;

use function React\Promise\resolve;

use const WyriHaximus\Constants\ComposerAutoloader\LOCATION;

final class Runtime
Expand All @@ -28,16 +25,23 @@ public function __construct(private EventLoopBridge $eventLoopBridge, string $au
$this->runtime = new ParallelRuntime($autoload);
}

/** @param array<int, mixed> $args */
public function run(Closure $callable, array $args = []): PromiseInterface
/**
* @param (Closure():?T) $callable
* @param array<int, mixed> $args
*
* @return ?T
*
* @template T
*/
public function run(Closure $callable, array $args = []): mixed
{
$future = $this->runtime->run($callable, $args);

if ($future instanceof Future) {
return resolve($this->eventLoopBridge->await($future));
return $this->eventLoopBridge->await($future);
}

return resolve($future);
return $future;
}

public function close(): void
Expand Down
82 changes: 82 additions & 0 deletions stubs/Channel.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace parallel;

/**
* @template T
*/
final class Channel
{
/**
* Constant for Infinitely Buffered
*/
public const Infinite = -1;

/* Anonymous Constructor */

/**
* Shall make an anonymous unbuffered channel
* Shall make an anonymous buffered channel with the given capacity
*
* @param null|int $capacity May be Channel::Infinite or a positive integer
*/
public function __construct(?int $capacity = null) {}

/* Access */

/**
* Shall make an unbuffered channel with the given name
* Shall make a buffered channel with the given name and capacity
*
* @param string $name The name of the channel.
* @param null|int $capacity May be Channel::Infinite or a positive integer
*
* @return Channel<T>
*
* @throws Channel\Error\Existence if channel already exists.
*/
public static function make(string $name, ?int $capacity = null): Channel {}

/**
* Shall open the channel with the given name
*
* @param string $name
* @return Channel<T>
*
* @throws Channel\Error\Existence if channel does not exist.
*/
public static function open(string $name): Channel {}

/* Sharing */

/**
* Shall send the given value on this channel
* @param T $value
*
* @throws Channel\Error\Closed if channel is closed.
* @throws Channel\Error\IllegalValue if value is illegal.
*/
public function send($value): void {}

/**
* Shall recv a value from this channel
* @return T
*
* @throws Channel\Error\Closed if channel is closed.
*/
public function recv() {}

/* Closing */

/**
* Shall close this channel
* @throws Channel\Error\Closed if channel is closed.
*/
public function close(): void {}

/**
* Returns name of channel
* @return string
*/
public function __toString(): string {}
}
36 changes: 36 additions & 0 deletions stubs/Event.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace parallel\Events;

use parallel\Channel;
use parallel\Future;

/**
* @template T
*/
final class Event
{
/**
* Shall be one of Event\Type constants
* @var int
*/
public $type;

/**
* Shall be the source of the event (target name)
* @var string
*/
public $source;

/**
* Shall be either Future or Channel
* @var Future<T>|Channel<T>
*/
public $object;

/**
* Shall be set for Read/Error events
* @var T
*/
public $value;
}
54 changes: 54 additions & 0 deletions stubs/Future.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace parallel;

use Throwable;

/**
* @template T
*/
final class Future
{
/* Resolution */

/**
* Shall return (and if necessary wait for) return from task
*
* @return T
*
* @throws Future\Error if waiting failed (internal error).
* @throws Future\Error\Killed if \parallel\Runtime executing task was killed.
* @throws Future\Error\Cancelled if task was cancelled.
* @throws Future\Error\Foreign if task raised an unrecognized uncaught exception.
* @throws Throwable Shall rethrow \Throwable uncaught in task
*/
public function value() {}

/* State */

/**
* Shall indicate if the task is completed
* @return bool
*/
public function done(): bool {}

/**
* Shall indicate if the task was cancelled
* @return bool
*/
public function cancelled(): bool {}

/* Cancellation */

/**
* Shall try to cancel the task
* Note: If task is running, it will be interrupted.
* Warning: Internal function calls in progress cannot be interrupted.
*
* @return bool
*
* @throws Future\Error\Killed if \parallel\Runtime executing task was killed.
* @throws Future\Error\Cancelled if task was already cancelled.
*/
public function cancel(): bool {}
}
38 changes: 17 additions & 21 deletions tests/RuntimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@ public function convertSuccess(): void
{
$runtime = Runtime::create(new EventLoopBridge());

$promise = $runtime->run(static function (): int {
sleep(3);
try {
$three = $runtime->run(static function (): int {
sleep(3);

return 3;
});

$promise->always(static function () use ($runtime): void {
return 3;
});
} finally {
$runtime->kill();
});

$three = await($promise); /** @phpstan-ignore-line */
}

self::assertSame(3, $three);
}
Expand All @@ -45,19 +43,17 @@ public function convertFailure(): void

$runtime = Runtime::create(new EventLoopBridge());

$promise = $runtime->run(static function (): void {
sleep(3);
try {
$three = $runtime->run(static function (): void {
sleep(3);

throw new LatchcombException('Rethrow exception');
});

$promise->always(static function () use ($runtime): void {
throw new LatchcombException('Rethrow exception');
});
} finally {
$runtime->close();
});

$three = await($promise); /** @phpstan-ignore-line */
}

self::assertSame(3, $three);
// self::assertSame(3, $three);
}

/** @test */
Expand All @@ -78,7 +74,7 @@ public function weClosedTheThread(): void
$runtime->close();
});

await($promise); /** @phpstan-ignore-line */
await($promise);
}

/** @test */
Expand All @@ -99,6 +95,6 @@ public function weKilledTheThread(): void
$runtime->kill();
});

await($promise); /** @phpstan-ignore-line */
await($promise);
}
}