private void maybeScheduleNextWriteNoOpRecord() {
        if (!noOpRecordScheduled &&
            maxIdleIntervalNs.isPresent() &&
            featureControl.metadataVersion().isNoOpRecordSupported()) {

            log.debug(
                "Scheduling write event for {} because maxIdleIntervalNs ({}) and metadataVersion ({})",
                WRITE_NO_OP_RECORD,
                maxIdleIntervalNs.getAsLong(),
                featureControl.metadataVersion()
            );

            ControllerWriteEvent<Void> event = new ControllerWriteEvent<>(
                WRITE_NO_OP_RECORD,
                () -> {
                    noOpRecordScheduled = false;
                    maybeScheduleNextWriteNoOpRecord();

                    return ControllerResult.of(
                        Collections.singletonList(new ApiMessageAndVersion(new NoOpRecord(), (short) 0)),
                        null
                    );
                },
                EnumSet.of(DOES_NOT_UPDATE_QUEUE_TIME, RUNS_IN_PREMIGRATION)
            );

            long delayNs = time.nanoseconds() + maxIdleIntervalNs.getAsLong();
            queue.scheduleDeferred(WRITE_NO_OP_RECORD, new EarliestDeadlineFunction(delayNs), event);
            noOpRecordScheduled = true;
        }
    }
Append records to the Raft log. They will be written out asynchronously.

@param log                   The log4j logger.
@param result                The controller result we are writing out.
@param maxRecordsPerBatch    The maximum number of records to allow in a batch.
@param appender              The callback to invoke for each batch. The arguments are last
                             write offset, record list, and the return result is the new
                             last write offset.
@return                      The final offset that was returned from the Raft layer.
metadata/src/main/java/org/apache/kafka/controller/QuorumController.java