docs: def abort_incomplete_batches(self):
          """
          This function is only called when sender is closed forcefully. It will fail all the
          incomplete batches and return.
          """
          # We need to keep aborting the incomplete batch until no thread is trying to append to
          # 1. Avoid losing batches.
          # 2. Free up memory in case appending threads are blocked on buffer full.
          # This is a tight loop but should be able to get through very quickly.
          while True:
              self._abort_batches()
              if not self._appends_in_progress.get():
                  break
          # After this point, no thread will append any messages because they will see the close
          # flag set. We need to do the last abort after no thread was appending in case the there was a new
          # batch appended by the last appending thread.
          self._abort_batches()
          self._batches.clear()