code: def wait(self, progress=None):
      
      if not len(self._threads):
        return self
  
      desc = None
      if type(progress) is str:
        desc = progress
  
      last = self._inserted
      with tqdm(total=self._inserted, disable=(not progress), desc=desc) as pbar:
        # Allow queue to consume, but check up on
        # progress and errors every tenth of a second
        while not self._queue.empty():
          size = self._queue.qsize()
          delta = last - size
          if delta != 0: # We should crash on negative numbers
            pbar.update(delta)
          last = size
          self._check_errors()
          time.sleep(0.1)
  
        # Wait until all tasks in the queue are 
        # fully processed. queue.task_done must be
        # called for each task.
        self._queue.join() 
        self._check_errors()
  
        final = self._inserted - last
        if final:
          pbar.update(final)
  
      if self._queue.empty():
        self._inserted = 0
  
      return self
docs: Allow background threads to process until the
      task queue is empty. If there are no threads,
      in theory the queue should always be empty
      as processing happens immediately on the main thread.
  
      Optional:
        progress: (bool or str) show a tqdm progress bar optionally
          with a description if a string is provided
      
      Returns: self (for chaining)
  
      Raises: The first exception recieved from threads