def done(self, base_offset=None, timestamp_ms=None, exception=None):
        """
        Finalize the state of a batch. Final state, once set, is immutable. This function may be called
        once or twice on a batch. It may be called twice if
            1. An inflight batch expires before a response from the broker is received. The batch's final
            state is set to FAILED. But it could succeed on the broker and second time around batch.done() may
            try to set SUCCEEDED final state.

            2. If a transaction abortion happens or if the producer is closed forcefully, the final state is
            ABORTED but again it could succeed if broker responds with a success.

        Attempted transitions from [FAILED | ABORTED] --> SUCCEEDED are logged.
        Attempted transitions from one failure state to the same or a different failed state are ignored.
        Attempted transitions from SUCCEEDED to the same or a failed state throw an exception.
        """
        final_state = FinalState.SUCCEEDED if exception is None else FinalState.FAILED
        if self._final_state is None:
            self._final_state = final_state
            if final_state is FinalState.SUCCEEDED:
                log.debug("Successfully produced messages to %s with base offset %s", self.topic_partition, base_offset)
            else:
                log.warning("Failed to produce messages to topic-partition %s with base offset %s: %s",
                            self.topic_partition, base_offset, exception)
            self._complete_future(base_offset, timestamp_ms, exception)
            return True

        elif self._final_state is not FinalState.SUCCEEDED:
            if final_state is FinalState.SUCCEEDED:
                # Log if a previously unsuccessful batch succeeded later on.
                log.debug("ProduceResponse returned %s for %s after batch with base offset %s had already been %s.",
                          final_state, self.topic_partition, base_offset, self._final_state)
            else:
                # FAILED --> FAILED and ABORTED --> FAILED transitions are ignored.
                log.debug("Ignored state transition %s -> %s for %s batch with base offset %s",
                          self._final_state, final_state, self.topic_partition, base_offset)
        else:
            # A SUCCESSFUL batch must not attempt another state change.
            raise Errors.IllegalStateError("A %s batch must not attempt another state change to %s" % (self._final_state, final_state))
        return False

        Finalize the state of a batch. Final state, once set, is immutable. This function may be called
        once or twice on a batch. It may be called twice if
            1. An inflight batch expires before a response from the broker is received. The batch's final
            state is set to FAILED. But it could succeed on the broker and second time around batch.done() may
            try to set SUCCEEDED final state.

            2. If a transaction abortion happens or if the producer is closed forcefully, the final state is
            ABORTED but again it could succeed if broker responds with a success.

        Attempted transitions from [FAILED | ABORTED] --> SUCCEEDED are logged.
        Attempted transitions from one failure state to the same or a different failed state are ignored.
        Attempted transitions from SUCCEEDED to the same or a failed state throw an exception.
        
kafka/producer/record_accumulator.py