docs: async def _reconnect(self, last_error):
          """
          Cleanly disconnects and then reconnects.
          """
          self._log.debug('Closing current connection...')
          await self._connection.disconnect()
  
          await helpers._cancel(
              self._log,
              send_loop_handle=self._send_loop_handle,
              recv_loop_handle=self._recv_loop_handle
          )
  
          # TODO See comment in `_start_reconnect`
          # Perhaps this should be the last thing to do?
          # But _connect() creates tasks which may run and,
          # if they see that reconnecting is True, they will end.
          # Perhaps that task creation should not belong in connect?
          self._reconnecting = False
  
          # Start with a clean state (and thus session ID) to avoid old msgs
          self._state.reset()
  
          retries = self._retries if self._auto_reconnect else 0
          for attempt in retry_range(retries):
              try:
                  await self._connect()
              except (IOError, asyncio.TimeoutError) as e:
                  last_error = e
                  self._log.info('Failed reconnection attempt %d with %s',
                                 attempt, e.__class__.__name__)
  
                  await asyncio.sleep(self._delay)
              except Exception as e:
                  last_error = e
                  self._log.exception('Unexpected exception reconnecting on '
                                      'attempt %d', attempt)
  
                  await asyncio.sleep(self._delay)
              else:
                  self._send_queue.extend(self._pending_state.values())
                  self._pending_state.clear()
  
                  if self._auto_reconnect_callback:
                      self._loop.create_task(self._auto_reconnect_callback())
  
                  break
          else:
              self._log.error('Automatic reconnection failed {} time(s)'
                              .format(attempt))
              await self._disconnect(error=last_error.with_traceback(None))