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,36 +249,16 @@ 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 ( ) ) ;
260
+ return Ok ( Box :: new ( self . become_candidate ( ) ?) ) ;
238
261
}
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
- }
257
- }
258
- false
262
+ Ok ( self )
259
263
}
260
264
}
0 commit comments