onData = $onData; $this->onError = $onError; } protected function cancelTimer(): void { if ($this->timer === null) { return; } $this->loop->cancelTimer($this->timer); $this->timer = null; } /** Cancels the timeout timer and ends the writable side of the connection. */ protected function endConnection(): void { $this->cancelTimer(); if ($this->in === null) { return; } $this->in->end(); } /** * @param mixed[] $data */ public function request(array $data): void { $this->cancelTimer(); if ($this->in === null) { throw new ShouldNotHappenException(); } $this->in->write($data); $this->timer = $this->loop->addTimer($this->timeoutSeconds, function (): void { $onError = $this->onError; $onError(new ProcessTimedOutException(sprintf('Child process timed out after %.1f seconds. Try making it longer with parallel.processTimeout setting.', $this->timeoutSeconds))); }); } public function bindConnection(ReadableStreamInterface $out, WritableStreamInterface $in): void { $out->on('data', function (array $json): void { $this->cancelTimer(); if ($json['action'] !== 'result') { return; } $onData = $this->onData; $onData($json['result']); }); $this->in = $in; $out->on('error', function (Throwable $error): void { $onError = $this->onError; $onError($error); }); $in->on('error', function (Throwable $error): void { $onError = $this->onError; $onError($error); }); } }