1
1
use super :: super :: {
2
- Address , Event , Index , Instruction , Message , ReadSequence , Request , RequestID , Status ,
2
+ Address , Event , Index , Message , ReadSequence , Request , RequestID , Response , Status ,
3
3
} ;
4
4
use super :: { Follower , Node , NodeID , RawNode , Role , Term , Ticks , HEARTBEAT_INTERVAL } ;
5
5
use crate :: error:: { Error , Result } ;
@@ -30,8 +30,6 @@ pub struct Leader {
30
30
///
31
31
/// If we lose leadership before the command is processed, all pending write
32
32
/// requests are aborted by returning Error::Abort.
33
- ///
34
- /// TODO: Actually return responses when applied.
35
33
writes : HashMap < Index , ( Address , RequestID ) > ,
36
34
/// Keeps track of pending read requests. To guarantee linearizability, read
37
35
/// requests are assigned a sequence number and registered here when
@@ -88,7 +86,6 @@ impl RawNode<Leader> {
88
86
info ! ( "Discovered new term {}" , term) ;
89
87
90
88
// Cancel in-flight requests.
91
- self . state_tx . send ( Instruction :: Abort ) ?;
92
89
for ( address, id) in std:: mem:: take ( & mut self . role . writes ) . into_values ( ) {
93
90
self . send ( address, Event :: ClientResponse { id, response : Err ( Error :: Abort ) } ) ?;
94
91
}
@@ -129,16 +126,10 @@ impl RawNode<Leader> {
129
126
// are its leader. If it doesn't have the commit index in its local
130
127
// log, replicate the log to it. If the peer's read sequence number
131
128
// increased, process any pending reads.
132
- Event :: ConfirmLeader { commit_index , has_committed, read_seq } => {
129
+ Event :: ConfirmLeader { has_committed, read_seq } => {
133
130
assert ! ( read_seq <= self . role. read_seq, "Future read sequence number" ) ;
134
131
135
132
let from = msg. from . unwrap ( ) ;
136
- self . state_tx . send ( Instruction :: Vote {
137
- term : msg. term ,
138
- index : commit_index,
139
- address : msg. from ,
140
- } ) ?;
141
-
142
133
let mut read_seq_advanced = false ;
143
134
self . role . progress . entry ( from) . and_modify ( |p| {
144
135
if read_seq > p. read_seq {
@@ -167,7 +158,7 @@ impl RawNode<Leader> {
167
158
p. last = last_index;
168
159
p. next = last_index + 1 ;
169
160
} ) ;
170
- self . maybe_commit ( ) ?;
161
+ self . maybe_commit_and_apply ( ) ?;
171
162
}
172
163
173
164
// A follower rejected log entries we sent it, typically because it
@@ -198,20 +189,6 @@ impl RawNode<Leader> {
198
189
id. clone ( ) ,
199
190
command. clone ( ) ,
200
191
) ) ;
201
- let ( commit_index, _) = self . log . get_commit_index ( ) ;
202
- self . state_tx . send ( Instruction :: Query {
203
- id,
204
- address : msg. from ,
205
- command,
206
- term : self . term ,
207
- index : commit_index,
208
- quorum : self . quorum ( ) ,
209
- } ) ?;
210
- self . state_tx . send ( Instruction :: Vote {
211
- term : self . term ,
212
- index : commit_index,
213
- address : Address :: Node ( self . id ) ,
214
- } ) ?;
215
192
if self . peers . is_empty ( ) {
216
193
self . maybe_read ( ) ?;
217
194
}
@@ -223,15 +200,14 @@ impl RawNode<Leader> {
223
200
Event :: ClientRequest { id, request : Request :: Mutate ( command) } => {
224
201
let index = self . propose ( Some ( command) ) ?;
225
202
self . role . writes . insert ( index, ( msg. from , id. clone ( ) ) ) ;
226
- self . state_tx . send ( Instruction :: Notify { id, address : msg. from , index } ) ?;
227
203
if self . peers . is_empty ( ) {
228
- self . maybe_commit ( ) ?;
204
+ self . maybe_commit_and_apply ( ) ?;
229
205
}
230
206
}
231
207
232
208
Event :: ClientRequest { id, request : Request :: Status } => {
233
209
let engine_status = self . log . status ( ) ?;
234
- let status = Box :: new ( Status {
210
+ let status = Status {
235
211
server : self . id ,
236
212
leader : self . id ,
237
213
term : self . term ,
@@ -243,11 +219,14 @@ impl RawNode<Leader> {
243
219
. chain ( std:: iter:: once ( ( self . id , self . log . get_last_index ( ) . 0 ) ) )
244
220
. collect ( ) ,
245
221
commit_index : self . log . get_commit_index ( ) . 0 ,
246
- apply_index : 0 ,
222
+ apply_index : self . state . get_applied_index ( ) ,
247
223
storage : engine_status. name . clone ( ) ,
248
224
storage_size : engine_status. size ,
249
- } ) ;
250
- self . state_tx . send ( Instruction :: Status { id, address : msg. from , status } ) ?
225
+ } ;
226
+ self . send (
227
+ msg. from ,
228
+ Event :: ClientResponse { id, response : Ok ( Response :: Status ( status) ) } ,
229
+ ) ?;
251
230
}
252
231
253
232
// Votes can come in after we won the election, ignore them.
@@ -294,9 +273,9 @@ impl RawNode<Leader> {
294
273
Ok ( index)
295
274
}
296
275
297
- /// Commits any new log entries that have been replicated to a quorum,
298
- /// and schedules them for state machine application .
299
- fn maybe_commit ( & mut self ) -> Result < Index > {
276
+ /// Commits any new log entries that have been replicated to a quorum, and
277
+ /// applies them to the state machine.
278
+ fn maybe_commit_and_apply ( & mut self ) -> Result < Index > {
300
279
// Determine the new commit index, i.e. the last index replicated to a
301
280
// quorum of peers.
302
281
let mut last_indexes = self
@@ -332,15 +311,28 @@ impl RawNode<Leader> {
332
311
None => panic ! ( "Commit index {} missing" , commit_index) ,
333
312
} ;
334
313
335
- // Commit and apply the new entries.
314
+ // Commit the new entries.
336
315
if commit_index > prev_commit_index {
337
316
self . log . commit ( commit_index) ?;
338
- // TODO: Move application elsewhere, but needs access to applied index.
339
- let mut scan = self . log . scan ( ( prev_commit_index + 1 ) ..=commit_index) ?;
317
+ }
318
+
319
+ // Apply entries.
320
+ let applied_index = self . state . get_applied_index ( ) ;
321
+ if applied_index < commit_index {
322
+ let mut scan = self . log . scan ( ( applied_index + 1 ) ..=commit_index) ?;
340
323
while let Some ( entry) = scan. next ( ) . transpose ( ) ? {
341
- // TODO: Send response.
342
- self . role . writes . remove ( & entry. index ) ;
343
- self . state_tx . send ( Instruction :: Apply { entry } ) ?;
324
+ let index = entry. index ;
325
+ let result = Self :: apply ( & mut self . state , entry) ?;
326
+ if let Some ( ( from, id) ) = self . role . writes . remove ( & index) {
327
+ let response = result. map ( Response :: Mutate ) ;
328
+ // TODO: use self.send() or something.
329
+ self . node_tx . send ( Message {
330
+ from : Address :: Node ( self . id ) ,
331
+ to : from,
332
+ term : self . term ,
333
+ event : Event :: ClientResponse { id, response } ,
334
+ } ) ?;
335
+ }
344
336
}
345
337
}
346
338
Ok ( commit_index)
@@ -366,8 +358,10 @@ impl RawNode<Leader> {
366
358
if * rs > read_seq {
367
359
break ;
368
360
}
369
- self . role . reads . pop_front ( ) . unwrap ( ) ;
370
- // TODO: Actually execute the reads.
361
+ let ( _, from, id, command) = self . role . reads . pop_front ( ) . unwrap ( ) ;
362
+ let result = self . state . query ( command) ;
363
+ let response = result. map ( Response :: Query ) ;
364
+ self . send ( from, Event :: ClientResponse { id, response } ) ?;
371
365
}
372
366
373
367
Ok ( read_seq)
@@ -392,6 +386,7 @@ impl RawNode<Leader> {
392
386
}
393
387
394
388
#[ cfg( test) ]
389
+ #[ cfg( never) ] // TODO
395
390
mod tests {
396
391
use super :: super :: super :: { Entry , Log } ;
397
392
use super :: super :: tests:: { assert_messages, assert_node} ;
0 commit comments