docs: def send_message(self, message, callback):
          """ send a message over the wire; callback=None indicates a safe=False call where we write and forget about it"""
          
          if self.__callback is not None:
              raise ProgrammingError('connection already in use')
  
          if callback:
              err_callback = functools.partial(callback, None)
          else:
              err_callback = None
  
          # Go and update err_callback for async jobs in queue if any
          for job in self.__job_queue:
              # this is a dirty hack and I hate it, but there is no way of setting the correct
              # err_callback during the connection time
              if isinstance(job, asyncjobs.AsyncJob):
                  job.update_err_callback(err_callback)
  
          if not self.__alive:
              if self.__autoreconnect:
                  self.__connect(err_callback)
              else:
                  raise InterfaceError('connection invalid. autoreconnect=False')
          
          # Put the current message on the bottom of the queue
          self._put_job(asyncjobs.AsyncMessage(self, message, callback), 0)
          self._next_job()