void block(final long startTimeMs, @SuppressWarnings("unused") final int errorCode) {
        // TODO: Currently we don't care about error_code which indicates why the
        // very RPC fails. To make it better there should be different timeout for
        // each individual error (e.g. we don't need check every
        // heartbeat_timeout_ms whether a dead follower has come back), but it's just
        // fine now.
        if(this.blockTimer != null) {
            // already in blocking state,return immediately.
            unlockId();
            return;
        }
        this.blockCounter++;
        final long dueTime = startTimeMs + this.options.getDynamicHeartBeatTimeoutMs();
        try {
            LOG.debug("Blocking {} for {} ms", this.options.getPeerId(), this.options.getDynamicHeartBeatTimeoutMs());
            this.blockTimer = this.timerManager.schedule(() -> onBlockTimeout(this.id), dueTime - Utils.nowMs(),
                TimeUnit.MILLISECONDS);
            this.statInfo.runningState = RunningState.BLOCKING;
            unlockId();
        } catch (final Exception e) {
            this.blockTimer = null;
            LOG.error("Fail to add timer for replicator {}", this, e);
            // id unlock in sendEmptyEntries.
            sendProbeRequest();
        }
    }
Unblock and continue sending right now.
jraft-core/src/main/java/com/alipay/sofa/jraft/core/Replicator.java