/** * @param \Icicle\Observable\Observable[] $observables * * @return \Icicle\Observable\Observable */ function merge(array $observables) : Observable { return new Emitter(function (callable $emit) use($observables) : \Generator { /** @var \Icicle\Observable\Observable[] $observables */ $observables = array_map(__NAMESPACE__ . '\\from', $observables); $callback = function ($value) use(&$emitting, $emit) : \Generator { while (null !== $emitting) { (yield $emitting); // Prevents simultaneous calls to $emit. } $emitting = new Delayed(); yield from $emit($value); $emitting->resolve(); $emitting = null; }; /** @var \Icicle\Coroutine\Coroutine[] $coroutines */ $coroutines = array_map(function (Observable $observable) use($callback) : Coroutine { return new Coroutine($observable->each($callback)); }, $observables); try { return (yield Awaitable\all($coroutines)); } catch (\Throwable $exception) { foreach ($coroutines as $coroutine) { $coroutine->cancel($exception); } throw $exception; } }); }
public function onRequest(Request $request, Socket $socket) { $data = ''; $body = $request->getBody(); while ($body->isReadable()) { $data .= (yield $body->read()); } $requestData = json_decode($data, true); if (isset($requestData['type'])) { $type = $requestData['type']; if ($type === 'confirmation') { $confirmToken = (yield from $this->confirmToken($requestData['group_id'])); return yield from $this->ok($confirmToken); } if (!empty($this->listeners[$type])) { /** @var Coroutine\Coroutine[] $coroutines */ $coroutines = []; foreach ($this->listeners[$type] as $listener) { $coroutines[] = $listener($requestData); } Awaitable\all($coroutines)->wait(); } } return yield from $this->ok(); }
/** * {@inheritdoc} */ public function log(int $level, string $format, ...$args) : \Generator { (yield Awaitable\all(array_map(function (Log $log) use($level, $format, $args) : Coroutine { return new Coroutine($log->log($level, $format, ...$args)); }, $this->logs))); return true; }
/** * Creates an observable that emits values emitted from any observable in the array of observables. Values in the * array are passed through the from() function, so they may be observables, arrays of values to emit, awaitables, * or any other value. * * @param \Icicle\Observable\Observable[] $observables * * @return \Icicle\Observable\Observable */ function merge(array $observables) : Observable { /** @var \Icicle\Observable\Observable[] $observables */ $observables = array_map(__NAMESPACE__ . '\\from', $observables); return new Emitter(function (callable $emit) use($observables) : \Generator { /** @var \Icicle\Coroutine\Coroutine[] $coroutines */ $coroutines = array_map(function (Observable $observable) use($emit) : Coroutine { return new Coroutine($observable->each($emit)); }, $observables); (yield Awaitable\all($coroutines)->then(null, function (\Throwable $exception) use($coroutines) { foreach ($coroutines as $coroutine) { $coroutine->cancel($exception); } throw $exception; })); }); }
{ $this->callable = $callable; $this->args = $args; } public function run(Environment $environment) { ($this->callable)(...$this->args); } } function wait() { $sleep = rand(1, 200) / 100; echo "Sleep {$sleep} seconds\n"; sleep($sleep); echo "Awake\n"; return true; } Coroutine\create(function () { $pool = new DefaultPool(); $pool->start(); $coroutines = []; for ($i = 0; $i < 50; $i++) { $coroutines[] = Coroutine\create(function () use($pool) { $result = (yield from $pool->enqueue(new CallableTask('wait'))); return $result; }); } (yield Awaitable\all($coroutines)); return yield from $pool->shutdown(); })->done(); Loop\run();