126 lines
2.8 KiB
PHP
126 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace PHPNative\Async;
|
|
|
|
use parallel\Runtime;
|
|
use parallel\Future;
|
|
|
|
class AsyncTask
|
|
{
|
|
private ?Future $future = null;
|
|
private mixed $result = null;
|
|
private bool $completed = false;
|
|
private bool $failed = false;
|
|
private mixed $error = null;
|
|
private mixed $onComplete = null;
|
|
private mixed $onError = null;
|
|
private mixed $task = null;
|
|
|
|
public function __construct(
|
|
callable $task
|
|
) {
|
|
$this->task = $task;
|
|
}
|
|
|
|
/**
|
|
* Start the async task execution
|
|
*/
|
|
public function start(): void
|
|
{
|
|
if ($this->future !== null) {
|
|
return; // Already started
|
|
}
|
|
|
|
try {
|
|
// Create runtime with bootstrap file to load autoloader
|
|
$bootstrapPath = __DIR__ . '/bootstrap.php';
|
|
$runtime = new Runtime($bootstrapPath);
|
|
$this->future = $runtime->run($this->task);
|
|
} catch (\Throwable $e) {
|
|
$this->failed = true;
|
|
$this->error = $e;
|
|
$this->completed = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if task is completed and process result
|
|
*/
|
|
public function update(): void
|
|
{
|
|
if ($this->completed || $this->future === null) {
|
|
return;
|
|
}
|
|
|
|
// Check if future is done without blocking
|
|
if ($this->future->done()) {
|
|
try {
|
|
$this->result = $this->future->value();
|
|
$this->completed = true;
|
|
|
|
if ($this->onComplete !== null) {
|
|
($this->onComplete)($this->result);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
$this->failed = true;
|
|
$this->error = $e;
|
|
$this->completed = true;
|
|
|
|
if ($this->onError !== null) {
|
|
($this->onError)($this->error);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set callback for successful completion
|
|
*/
|
|
public function onComplete(callable $callback): self
|
|
{
|
|
$this->onComplete = $callback;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set callback for errors
|
|
*/
|
|
public function onError(callable $callback): self
|
|
{
|
|
$this->onError = $callback;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Check if task is completed
|
|
*/
|
|
public function isCompleted(): bool
|
|
{
|
|
return $this->completed;
|
|
}
|
|
|
|
/**
|
|
* Check if task failed
|
|
*/
|
|
public function isFailed(): bool
|
|
{
|
|
return $this->failed;
|
|
}
|
|
|
|
/**
|
|
* Get the result (only available after completion)
|
|
*/
|
|
public function getResult(): mixed
|
|
{
|
|
return $this->result;
|
|
}
|
|
|
|
/**
|
|
* Get the error (only available after failure)
|
|
*/
|
|
public function getError(): mixed
|
|
{
|
|
return $this->error;
|
|
}
|
|
}
|