@@ -844,6 +844,63 @@ impl<T: Storage> RaftCore<T> {
844
844
true
845
845
}
846
846
847
+ fn send_forward (
848
+ & mut self ,
849
+ from : u64 ,
850
+ commit : u64 ,
851
+ commit_term : u64 ,
852
+ forward : & Forward ,
853
+ msgs : & mut Vec < Message > ,
854
+ ) {
855
+ let mut m = Message :: default ( ) ;
856
+ m. to = forward. to ;
857
+ m. from = from;
858
+ m. commit = commit;
859
+ m. commit_term = commit_term;
860
+ m. set_msg_type ( MessageType :: MsgAppend ) ;
861
+ // Fetch log entries from the forward.index to the last index of log.
862
+ if self
863
+ . raft_log
864
+ . match_term ( forward. get_index ( ) , forward. get_log_term ( ) )
865
+ {
866
+ let ents = self . raft_log . entries (
867
+ forward. get_index ( ) + 1 ,
868
+ self . max_msg_size ,
869
+ GetEntriesContext ( GetEntriesFor :: SendForward {
870
+ from,
871
+ commit,
872
+ commit_term,
873
+ term : self . term ,
874
+ forward : forward. clone ( ) ,
875
+ } ) ,
876
+ ) ;
877
+
878
+ match ents {
879
+ Ok ( ents) => {
880
+ m. index = forward. get_index ( ) ;
881
+ m. log_term = forward. get_log_term ( ) ;
882
+ m. set_entries ( ents. into ( ) ) ;
883
+ self . send ( m, msgs) ;
884
+ }
885
+ Err ( Error :: Store ( StorageError :: LogTemporarilyUnavailable ) ) => { }
886
+ _ => {
887
+ // Forward MsgAppend with empty entries in order to update commit
888
+ // or trigger decrementing next_idx.
889
+ m. index = forward. get_index ( ) ;
890
+ m. log_term = forward. get_log_term ( ) ;
891
+ self . send ( m, msgs) ;
892
+ warn ! (
893
+ self . logger,
894
+ "The agent fails to fetch entries, index {} log term {} in forward message to peer {}." ,
895
+ forward. get_index( ) ,
896
+ forward. get_log_term( ) ,
897
+ forward. get_to( )
898
+ ) ;
899
+ }
900
+ }
901
+ }
902
+ }
903
+
847
904
// send_heartbeat sends an empty MsgAppend
848
905
fn send_heartbeat (
849
906
& mut self ,
@@ -904,6 +961,12 @@ impl<T: Storage> Raft<T> {
904
961
. for_each ( |( id, pr) | core. send_append ( * id, pr, msgs) ) ;
905
962
}
906
963
964
+ /// Forwards an append RPC from the leader to the given peer.
965
+ pub fn send_forward ( & mut self , from : u64 , commit : u64 , commit_term : u64 , forward : & Forward ) {
966
+ self . r
967
+ . send_forward ( from, commit, commit_term, forward, & mut self . msgs ) ;
968
+ }
969
+
907
970
/// Broadcasts heartbeats to all the followers if it's leader.
908
971
pub fn ping ( & mut self ) {
909
972
if self . state == StateRole :: Leader {
@@ -2541,59 +2604,20 @@ impl<T: Storage> Raft<T> {
2541
2604
// If the agent fails to append entries from the leader,
2542
2605
// the agent cannot forward MsgAppend.
2543
2606
for forward in m. get_forwards ( ) {
2544
- // Fetch log entries from the forward.index to the last index of log.
2545
- if self
2546
- . raft_log
2547
- . match_term ( forward. get_index ( ) , forward. get_log_term ( ) )
2548
- {
2549
- let ents = self . raft_log . entries (
2550
- forward. get_index ( ) + 1 ,
2551
- self . max_msg_size ,
2552
- GetEntriesContext ( GetEntriesFor :: SendAppend {
2553
- to : forward. get_to ( ) ,
2554
- term : m. term ,
2555
- aggressively : false ,
2556
- } ) ,
2557
- ) ;
2558
-
2559
- match ents {
2560
- Ok ( ents) => {
2561
- let mut m_append = Message :: default ( ) ;
2562
- m_append. to = forward. get_to ( ) ;
2563
- m_append. from = m. get_from ( ) ;
2564
- m_append. set_msg_type ( MessageType :: MsgAppend ) ;
2565
- m_append. index = forward. get_index ( ) ;
2566
- m_append. log_term = forward. get_log_term ( ) ;
2567
- m_append. set_entries ( ents. into ( ) ) ;
2568
- m_append. commit = m. get_commit ( ) ;
2569
- m_append. commit_term = m. get_commit_term ( ) ;
2570
- self . r . send ( m_append, & mut self . msgs ) ;
2571
- }
2572
- Err ( _) => {
2573
- self . dummy_forward ( m, forward) ;
2574
- warn ! (
2575
- self . logger,
2576
- "The agent fails to fetch entries, index {} log term {} in forward message to peer {}." ,
2577
- forward. get_index( ) ,
2578
- forward. get_log_term( ) ,
2579
- forward. get_to( )
2580
- ) ;
2581
- }
2582
- }
2583
- } else {
2584
- self . dummy_forward ( m, forward) ;
2585
- warn ! (
2586
- self . logger,
2587
- "The agent's log does not match with index {} log term {} in forward message to peer {}." ,
2588
- forward. get_index( ) ,
2589
- forward. get_log_term( ) ,
2590
- forward. get_to( )
2591
- ) ;
2592
- }
2607
+ self . r
2608
+ . send_forward ( m. from , m. commit , m. commit_term , forward, & mut self . msgs ) ;
2593
2609
}
2594
2610
} else {
2595
2611
for forward in m. get_forwards ( ) {
2596
- self . dummy_forward ( m, forward) ;
2612
+ let mut m_append = Message :: default ( ) ;
2613
+ m_append. to = forward. to ;
2614
+ m_append. from = m. from ;
2615
+ m_append. commit = m. commit ;
2616
+ m_append. commit_term = m. commit_term ;
2617
+ m_append. set_msg_type ( MessageType :: MsgAppend ) ;
2618
+ m_append. index = forward. get_index ( ) ;
2619
+ m_append. log_term = forward. get_log_term ( ) ;
2620
+ self . r . send ( m_append, & mut self . msgs ) ;
2597
2621
}
2598
2622
info ! (
2599
2623
self . logger,
@@ -2937,29 +2961,6 @@ impl<T: Storage> Raft<T> {
2937
2961
self . lead_transferee = None ;
2938
2962
}
2939
2963
2940
- // Forward MsgAppend with empty entries in order to update commit
2941
- // or trigger decrementing next_idx.
2942
- fn dummy_forward ( & mut self , m : & Message , forward : & Forward ) {
2943
- let mut m_append = Message :: default ( ) ;
2944
- m_append. to = forward. get_to ( ) ;
2945
- m_append. from = m. get_from ( ) ;
2946
- m_append. set_msg_type ( MessageType :: MsgAppend ) ;
2947
- m_append. index = forward. get_index ( ) ;
2948
- m_append. log_term = forward. get_log_term ( ) ;
2949
- m_append. commit = m. get_commit ( ) ;
2950
- m_append. commit_term = m. get_commit_term ( ) ;
2951
-
2952
- info ! (
2953
- self . logger,
2954
- "The agent forwards reserved empty log entry [logterm: {msg_log_term}, index: {msg_index}] \
2955
- to peer {id}",
2956
- msg_log_term = forward. log_term,
2957
- msg_index = forward. index,
2958
- id = forward. to;
2959
- ) ;
2960
- self . r . send ( m_append, & mut self . msgs ) ;
2961
- }
2962
-
2963
2964
fn send_request_snapshot ( & mut self ) {
2964
2965
let mut m = Message :: default ( ) ;
2965
2966
m. set_msg_type ( MessageType :: MsgAppendResponse ) ;
0 commit comments