Xline
Xline copied to clipboard
Refactor: revision generation
Why
In #254 we added a prepare
stage in the command executor to assign each command with a revision. However, in current logic the prepare
method is called inside the conflict_checked_mpmc
, this present the following behaviour:
- the commands is executed in the conflict order
- the leader may call
send_sp_exe
on a command and the follower always callssend_after_sync
These may result in revision is assigned in different order between leader and followers.
Refactor
I plan to move the calls of prepare
to raw_curp
. As soon as a server gets a new valid log, it assign a prepare result to it.
This include the following changes:
- move command executor from
conflict_checked_mpmc
toraw_curp
- add a
prepare_board
toraw_curp
context to temporarily store the prepare result - On the leader calls
prepare
inhandle_propose
- On the follower calls
prepare
inhandle_append_entries
- In
apply
, before the call ofsend_after_sync
, remove the prepare result and send it to theconflict_checked_mpmc
.
This guarantees the revisions is assigned in the order of log index and consistency among servers.
In handle_propose
the leader need to generate the prepare result(revision) for the execution stage(beacuse the revision need to return to user in speculative execute), but this prepare result may get reverted if the leadership changes. So the command executor need to introdue another method called prepare_commit
. This method is called after the leader knows that the log is commited.
After this change, the prepare
stage should not increment the revision generator, but pre-assign a revsion(use another counter to store this), and the revision is actually incremented after prepare_commit
is called. If the leader steps down, it need to clear the pre-assign counter.