public function connectAsync(ConnectionContext $ctx): \Generator
    {
        $this->API->logger->logger("Trying connection via $ctx", \danog\MadelineProto\Logger::WARNING);

        $this->ctx = $ctx->getCtx();
        $this->datacenter = $ctx->getDc();
        $this->stream = yield $ctx->getStream();
        if (isset($this->old)) {
            unset($this->old);
        }

        if (!isset($this->writer)) {
            $this->writer = new WriteLoop($this->API, $this->datacenter);
        }
        if (!isset($this->reader)) {
            $this->reader = new ReadLoop($this->API, $this->datacenter);
        }
        if (!isset($this->checker)) {
            $this->checker = new CheckLoop($this->API, $this->datacenter);
        }
        if (!isset($this->waiter)) {
            $this->waiter = new HttpWaitLoop($this->API, $this->datacenter);
        }
        if (!isset($this->updater)) {
            $this->updater = new UpdateLoop($this->API, $this->datacenter);
        }
        foreach ($this->new_outgoing as $message_id) {
            if ($this->outgoing_messages[$message_id]['unencrypted']) {
                $promise = $this->outgoing_messages[$message_id]['promise'];
                \Amp\Loop::defer(function () use ($promise) {
                    $promise->fail(new Exception('Restart'));
                });
                unset($this->new_outgoing[$message_id]);
                unset($this->outgoing_messages[$message_id]);
            }
        }
        $this->http_req_count = 0;
        $this->http_res_count = 0;

        $this->writer->start();
        $this->reader->start();
        if (!$this->checker->start()) {
            $this->checker->resume();
        }
        $this->waiter->start();

        if ($this->datacenter === $this->API->settings['connection_settings']['default_dc']) {
            $this->updater->start();
        }
    }