public function enqueue(Task $task) : \Generator
{
if (!$this->context->isRunning()) {
throw new StatusError('The worker has not been started.');
}
if ($this->shutdown) {
throw new StatusError('The worker has been shut down.');
}
// If the worker is currently busy, store the task in a busy queue.
if (null !== $this->active) {
$delayed = new Delayed();
$this->busyQueue->enqueue($delayed);
(yield $delayed);
}
$this->active = new Coroutine($this->send($task));
try {
$result = (yield $this->active);
} catch (\Throwable $exception) {
$this->kill();
throw new WorkerException('Sending the task to the worker failed.', $exception);
} finally {
$this->active = null;
}
// We're no longer busy at the moment, so dequeue a waiting task.
if (!$this->busyQueue->isEmpty()) {
$this->busyQueue->dequeue()->resolve();
}
if ($result instanceof TaskFailure) {
throw $result->getException();
}
return $result;
}