@Override
            public void onApply(Iterator iter) {
                while (iter.hasNext()) {
                    final LogId logId = new LogId(iter.getIndex(), iter.getTerm());
                    logs.add(logId);
                    //random snapshot
                    if (ThreadLocalRandom.current().nextInt(10) < 5) {
                        // commit before do snapshot
                        iter.commit();
                        running.incrementAndGet();
                        node.snapshotSync(new Closure() {

                            @Override
                            public void run(Status status) {
                                if (status.isOk()) {
                                    snapshotsExpected.add(logId.copy());
                                } else {
                                    assertEquals(status.getCode(), RaftError.EBUSY.getNumber());
                                }
                                running.countDown();

                            }
                        });
                    }
                    iter.done().run(Status.OK());
                    iter.next();
                }

            }
Test rollback stateMachine with readIndex for issue 317:
https://github.com/sofastack/sofa-jraft/issues/317
jraft-core/src/test/java/com/alipay/sofa/jraft/core/NodeTest.java