docs: def Run(self):
      """The main run method of the client.
  
      This method does not normally return. Only if there have been more than
      connection_error_limit failures, the method returns and allows the
      client to exit.
      """
      while True:
        if self.http_manager.ErrorLimitReached():
          return
  
        # Check if there is a message from the nanny to be sent.
        self.client_worker.SendNannyMessage()
  
        now = time.time()
        # Check with the foreman if we need to
        if (now > self.last_foreman_check +
            config.CONFIG["Client.foreman_check_frequency"]):
          # We must not queue messages from the comms thread with blocking=True
          # or we might deadlock. If the output queue is full, we can't accept
          # more work from the foreman anyways so it's ok to drop the message.
          try:
            self.client_worker.SendReply(
                rdf_protodict.DataBlob(),
                session_id=rdfvalue.FlowSessionID(flow_name="Foreman"),
                require_fastpoll=False,
                blocking=False)
            self.last_foreman_check = now
          except queue.Full:
            pass
  
        try:
          self.RunOnce()
        except Exception:  # pylint: disable=broad-except
          # Catch everything, yes, this is terrible but necessary
          logging.warning("Uncaught exception caught: %s", traceback.format_exc())
          if flags.FLAGS.pdb_post_mortem:
            pdb.post_mortem()
  
        # We suicide if our memory is exceeded, and there is no more work to do
        # right now. Our death should not result in loss of messages since we are
        # not holding any requests in our input queues.
        if (self.client_worker.MemoryExceeded() and
            not self.client_worker.IsActive() and
            self.client_worker.InQueueSize() == 0 and
            self.client_worker.OutQueueSize() == 0):
          logging.warning("Memory exceeded - exiting.")
          self.client_worker.SendClientAlert("Memory limit exceeded, exiting.")
          # Make sure this will return True so we don't get more work.
          # pylint: disable=g-bad-name
          self.client_worker.MemoryExceeded = lambda: True
          # pylint: enable=g-bad-name
          # Now send back the client message.
          self.RunOnce()
          # And done for now.
          sys.exit(-1)
  
        self.timer.Wait()