read = $read; $this->write = $write; $this->received = new \SplQueue; $this->parser = new ChannelParser([$this->received, 'push']); } /** * {@inheritdoc} */ public function send($data): Promise { return new Coroutine($this->doSend($data)); } private function doSend($data): \Generator { try { return yield $this->write->write($this->parser->encode($data)); } catch (StreamException $exception) { throw new ChannelException("Sending on the channel failed. Did the context die?", $exception); } } /** * {@inheritdoc} */ public function receive(): Promise { return new Coroutine($this->doReceive()); } private function doReceive(): \Generator { while ($this->received->isEmpty()) { if (($chunk = yield $this->read->read()) === null) { throw new ChannelException("The channel closed. Did the context die?"); } try { $this->parser->push($chunk); } catch (StreamException $exception) { throw new ChannelException("Reading from the channel failed. Did the context die?", $exception); } } return $this->received->shift(); } }