1
1
use super :: super :: { Address , Event , Instruction , Message , RequestID , Response } ;
2
- use super :: { rand_election_timeout, Candidate , Node , NodeID , RoleNode , Term , Ticks } ;
2
+ use super :: { rand_election_timeout, BoxedNode , Candidate , DynNode , NodeID , RoleNode , Term , Ticks } ;
3
3
use crate :: error:: { Error , Result } ;
4
4
5
5
use :: log:: { debug, error, info, warn} ;
@@ -94,22 +94,46 @@ impl RoleNode<Follower> {
94
94
Ok ( self )
95
95
}
96
96
97
- /// Processes a message.
98
- pub fn step ( mut self , msg : Message ) -> Result < Node > {
97
+ /// Aborts all forwarded requests.
98
+ fn abort_forwarded ( & mut self ) -> Result < ( ) > {
99
+ for id in std:: mem:: take ( & mut self . role . forwarded ) {
100
+ debug ! ( "Aborting forwarded request {:x?}" , id) ;
101
+ self . send ( Address :: Client , Event :: ClientResponse { id, response : Err ( Error :: Abort ) } ) ?;
102
+ }
103
+ Ok ( ( ) )
104
+ }
105
+
106
+ /// Checks if an address is the current leader.
107
+ fn is_leader ( & self , from : & Address ) -> bool {
108
+ if let Some ( leader) = & self . role . leader {
109
+ if let Address :: Node ( from) = from {
110
+ return leader == from;
111
+ }
112
+ }
113
+ false
114
+ }
115
+ }
116
+
117
+ impl DynNode for RoleNode < Follower > {
118
+ fn id ( & self ) -> NodeID {
119
+ self . id
120
+ }
121
+
122
+ fn step ( mut self : Box < Self > , msg : Message ) -> Result < BoxedNode > {
99
123
self . assert ( ) ?;
100
124
self . assert_step ( & msg) ;
101
125
102
126
// Drop messages from past terms.
103
127
if msg. term < self . term && msg. term > 0 {
104
128
debug ! ( "Dropping message from past term ({:?})" , msg) ;
105
- return Ok ( self . into ( ) ) ;
129
+ return Ok ( self ) ;
106
130
}
107
131
108
132
// If we receive a message for a future term, become a leaderless
109
133
// follower in it and step the message. If the message is a Heartbeat or
110
134
// AppendEntries from the leader, stepping it will follow the leader.
111
135
if msg. term > self . term {
112
- return self . become_follower ( None , msg. term ) ?. step ( msg) ;
136
+ return Box :: new ( self . become_follower ( None , msg. term ) ?) . step ( msg) ;
113
137
}
114
138
115
139
// Record when we last saw a message from the leader (if any).
@@ -126,7 +150,7 @@ impl RoleNode<Follower> {
126
150
let from = msg. from . unwrap ( ) ;
127
151
match self . role . leader {
128
152
Some ( leader) => assert_eq ! ( from, leader, "Multiple leaders in term" ) ,
129
- None => self = self . become_follower ( Some ( from) , msg. term ) ?,
153
+ None => self = Box :: new ( self . become_follower ( Some ( from) , msg. term ) ?) ,
130
154
}
131
155
132
156
// Advance commit index and apply entries if possible.
@@ -149,7 +173,7 @@ impl RoleNode<Follower> {
149
173
let from = msg. from . unwrap ( ) ;
150
174
match self . role . leader {
151
175
Some ( leader) => assert_eq ! ( from, leader, "Multiple leaders in term" ) ,
152
- None => self = self . become_follower ( Some ( from) , msg. term ) ?,
176
+ None => self = Box :: new ( self . become_follower ( Some ( from) , msg. term ) ?) ,
153
177
}
154
178
155
179
// Append the entries, if possible.
@@ -169,7 +193,7 @@ impl RoleNode<Follower> {
169
193
// If we already voted for someone else in this term, ignore it.
170
194
if let Some ( voted_for) = self . role . voted_for {
171
195
if from != voted_for {
172
- return Ok ( self . into ( ) ) ;
196
+ return Ok ( self ) ;
173
197
}
174
198
}
175
199
@@ -189,7 +213,7 @@ impl RoleNode<Follower> {
189
213
Event :: ClientRequest { ref id, .. } => {
190
214
if msg. from != Address :: Client {
191
215
error ! ( "Received client request from non-client {:?}" , msg. from) ;
192
- return Ok ( self . into ( ) ) ;
216
+ return Ok ( self ) ;
193
217
}
194
218
195
219
let id = id. clone ( ) ;
@@ -206,7 +230,7 @@ impl RoleNode<Follower> {
206
230
Event :: ClientResponse { id, mut response } => {
207
231
if !self . is_leader ( & msg. from ) {
208
232
error ! ( "Received client response from non-leader {:?}" , msg. from) ;
209
- return Ok ( self . into ( ) ) ;
233
+ return Ok ( self ) ;
210
234
}
211
235
212
236
// TODO: Get rid of this field, it should be returned at the RPC
@@ -225,37 +249,17 @@ impl RoleNode<Follower> {
225
249
| Event :: RejectEntries { .. }
226
250
| Event :: GrantVote { .. } => warn ! ( "Received unexpected message {:?}" , msg) ,
227
251
} ;
228
- Ok ( self . into ( ) )
252
+ Ok ( self )
229
253
}
230
254
231
- /// Processes a logical clock tick.
232
- pub fn tick ( mut self ) -> Result < Node > {
255
+ fn tick ( mut self : Box < Self > ) -> Result < BoxedNode > {
233
256
self . assert ( ) ?;
234
257
235
258
self . role . leader_seen += 1 ;
236
259
if self . role . leader_seen >= self . role . election_timeout {
237
- return Ok ( self . become_candidate ( ) ?. into ( ) ) ;
238
- }
239
- Ok ( self . into ( ) )
240
- }
241
-
242
- /// Aborts all forwarded requests.
243
- fn abort_forwarded ( & mut self ) -> Result < ( ) > {
244
- for id in std:: mem:: take ( & mut self . role . forwarded ) {
245
- debug ! ( "Aborting forwarded request {:x?}" , id) ;
246
- self . send ( Address :: Client , Event :: ClientResponse { id, response : Err ( Error :: Abort ) } ) ?;
247
- }
248
- Ok ( ( ) )
249
- }
250
-
251
- /// Checks if an address is the current leader.
252
- fn is_leader ( & self , from : & Address ) -> bool {
253
- if let Some ( leader) = & self . role . leader {
254
- if let Address :: Node ( from) = from {
255
- return leader == from;
256
- }
260
+ return Ok ( Box :: new ( self . become_candidate ( ) ?) ) ;
257
261
}
258
- false
262
+ Ok ( self )
259
263
}
260
264
}
261
265
@@ -278,7 +282,7 @@ pub mod tests {
278
282
279
283
#[ allow( clippy:: type_complexity) ]
280
284
fn setup ( ) -> Result < (
281
- RoleNode < Follower > ,
285
+ Box < RoleNode < Follower > > ,
282
286
mpsc:: UnboundedReceiver < Message > ,
283
287
mpsc:: UnboundedReceiver < Instruction > ,
284
288
) > {
@@ -300,7 +304,7 @@ pub mod tests {
300
304
state_tx,
301
305
role : Follower :: new ( Some ( 2 ) , None ) ,
302
306
} ;
303
- Ok ( ( node, node_rx, state_rx) )
307
+ Ok ( ( Box :: new ( node) , node_rx, state_rx) )
304
308
}
305
309
306
310
#[ test]
@@ -620,7 +624,7 @@ pub mod tests {
620
624
role : Follower :: new ( Some ( 2 ) , None ) ,
621
625
} ;
622
626
623
- let mut node = follower. step ( Message {
627
+ let mut node = Box :: new ( follower) . step ( Message {
624
628
from : Address :: Node ( 2 ) ,
625
629
to : Address :: Node ( 1 ) ,
626
630
term : 3 ,
@@ -863,7 +867,7 @@ pub mod tests {
863
867
// ClientRequest is forwarded, as is the response.
864
868
fn step_clientrequest_clientresponse ( ) -> Result < ( ) > {
865
869
let ( follower, mut node_rx, mut state_rx) = setup ( ) ?;
866
- let mut node = Node :: Follower ( follower) ;
870
+ let mut node: BoxedNode = follower;
867
871
868
872
node = node. step ( Message {
869
873
from : Address :: Client ,
@@ -917,7 +921,7 @@ pub mod tests {
917
921
fn step_clientrequest_no_leader ( ) -> Result < ( ) > {
918
922
let ( mut follower, mut node_rx, mut state_rx) = setup ( ) ?;
919
923
follower. role = Follower :: new ( None , None ) ;
920
- let mut node = Node :: Follower ( follower) ;
924
+ let mut node: BoxedNode = follower;
921
925
922
926
node = node. step ( Message {
923
927
from : Address :: Client ,
@@ -943,7 +947,7 @@ pub mod tests {
943
947
#[ test]
944
948
fn step_clientrequest_aborted ( ) -> Result < ( ) > {
945
949
let ( follower, mut node_rx, mut state_rx) = setup ( ) ?;
946
- let mut node = Node :: Follower ( follower) ;
950
+ let mut node: BoxedNode = follower;
947
951
948
952
node = node. step ( Message {
949
953
from : Address :: Client ,
@@ -1004,7 +1008,7 @@ pub mod tests {
1004
1008
fn tick ( ) -> Result < ( ) > {
1005
1009
let ( follower, mut node_rx, mut state_rx) = setup ( ) ?;
1006
1010
let timeout = follower. role . election_timeout ;
1007
- let mut node = Node :: Follower ( follower) ;
1011
+ let mut node: BoxedNode = follower;
1008
1012
1009
1013
// Make sure heartbeats reset election timeout
1010
1014
assert ! ( timeout > 0 ) ;
0 commit comments