public function stop()
    {
        if (!$this->running) {
            return;
        }

        $this->running = false;

        $promise = call(function () {
            $promises = [];
            foreach (clone $this->workers as $worker) {
                \assert($worker instanceof Internal\IpcParent);
                $promises[] = call(function () use ($worker) {
                    list($process, $promise) = $this->workers[$worker];
                    \assert($process instanceof Process);

                    try {
                        yield $worker->shutdown();
                        yield Promise\timeout($promise, self::WORKER_TIMEOUT);
                    } catch (ContextException $exception) {
                        // Ignore if the worker has already died unexpectedly.
                    } finally {
                        if ($process->isRunning()) {
                            $process->kill();
                        }
                    }
                });
            }

            list($exceptions) = yield Promise\any($promises);

            $this->workers = new \SplObjectStorage;

            if (!empty($exceptions)) {
                $exception = new MultiReasonException($exceptions);
                $message = \implode('; ', \array_map(function (\Throwable $exception): string {
                    return $exception->getMessage();
                }, $exceptions));
                throw new ClusterException("Stopping the cluster failed: " . $message, 0, $exception);
            }
        });

        $this->deferred->resolve($promise);
    }