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 } ;
@@ -52,8 +52,6 @@ pub struct Leader {
52
52
///
53
53
/// If the leader loses leadership, all pending write requests are aborted
54
54
/// by returning Error::Abort.
55
- ///
56
- /// TODO: Actually return responses when applied.
57
55
writes : HashMap < Index , Write > ,
58
56
/// Keeps track of pending read requests. To guarantee linearizability, read
59
57
/// requests are assigned a sequence number and registered here when
@@ -110,7 +108,6 @@ impl RawNode<Leader> {
110
108
info ! ( "Discovered new term {}" , term) ;
111
109
112
110
// Cancel in-flight requests.
113
- self . state_tx . send ( Instruction :: Abort ) ?;
114
111
for write in std:: mem:: take ( & mut self . role . writes ) . into_values ( ) {
115
112
self . send (
116
113
write. from ,
@@ -157,16 +154,10 @@ impl RawNode<Leader> {
157
154
// are its leader. If it doesn't have the commit index in its local
158
155
// log, replicate the log to it. If the peer's read sequence number
159
156
// increased, process any pending reads.
160
- Event :: ConfirmLeader { commit_index , has_committed, read_seq } => {
157
+ Event :: ConfirmLeader { has_committed, read_seq } => {
161
158
assert ! ( read_seq <= self . role. read_seq, "Future read sequence number" ) ;
162
159
163
160
let from = msg. from . unwrap ( ) ;
164
- self . state_tx . send ( Instruction :: Vote {
165
- term : msg. term ,
166
- index : commit_index,
167
- address : msg. from ,
168
- } ) ?;
169
-
170
161
let progress = self . role . progress . get_mut ( & from) . unwrap ( ) ;
171
162
if read_seq > progress. read_seq {
172
163
progress. read_seq = read_seq;
@@ -191,7 +182,7 @@ impl RawNode<Leader> {
191
182
if last_index > progress. last {
192
183
progress. last = last_index;
193
184
progress. next = last_index + 1 ;
194
- self . maybe_commit ( ) ?;
185
+ self . maybe_commit_and_apply ( ) ?;
195
186
}
196
187
}
197
188
@@ -220,23 +211,9 @@ impl RawNode<Leader> {
220
211
self . role . reads . push_back ( Read {
221
212
seq : self . role . read_seq ,
222
213
from : msg. from ,
223
- id : id. clone ( ) ,
224
- command : command. clone ( ) ,
225
- } ) ;
226
- let ( commit_index, _) = self . log . get_commit_index ( ) ;
227
- self . state_tx . send ( Instruction :: Query {
228
214
id,
229
- address : msg. from ,
230
215
command,
231
- term : self . term ,
232
- index : commit_index,
233
- quorum : self . quorum_size ( ) ,
234
- } ) ?;
235
- self . state_tx . send ( Instruction :: Vote {
236
- term : self . term ,
237
- index : commit_index,
238
- address : Address :: Node ( self . id ) ,
239
- } ) ?;
216
+ } ) ;
240
217
if self . peers . is_empty ( ) {
241
218
self . maybe_read ( ) ?;
242
219
}
@@ -248,15 +225,14 @@ impl RawNode<Leader> {
248
225
Event :: ClientRequest { id, request : Request :: Mutate ( command) } => {
249
226
let index = self . propose ( Some ( command) ) ?;
250
227
self . role . writes . insert ( index, Write { from : msg. from , id : id. clone ( ) } ) ;
251
- self . state_tx . send ( Instruction :: Notify { id, address : msg. from , index } ) ?;
252
228
if self . peers . is_empty ( ) {
253
- self . maybe_commit ( ) ?;
229
+ self . maybe_commit_and_apply ( ) ?;
254
230
}
255
231
}
256
232
257
233
Event :: ClientRequest { id, request : Request :: Status } => {
258
234
let engine_status = self . log . status ( ) ?;
259
- let status = Box :: new ( Status {
235
+ let status = Status {
260
236
server : self . id ,
261
237
leader : self . id ,
262
238
term : self . term ,
@@ -268,11 +244,14 @@ impl RawNode<Leader> {
268
244
. chain ( std:: iter:: once ( ( self . id , self . log . get_last_index ( ) . 0 ) ) )
269
245
. collect ( ) ,
270
246
commit_index : self . log . get_commit_index ( ) . 0 ,
271
- apply_index : 0 ,
247
+ apply_index : self . state . get_applied_index ( ) ,
272
248
storage : engine_status. name . clone ( ) ,
273
249
storage_size : engine_status. size ,
274
- } ) ;
275
- self . state_tx . send ( Instruction :: Status { id, address : msg. from , status } ) ?
250
+ } ;
251
+ self . send (
252
+ msg. from ,
253
+ Event :: ClientResponse { id, response : Ok ( Response :: Status ( status) ) } ,
254
+ ) ?;
276
255
}
277
256
278
257
// Votes can come in after we won the election, ignore them.
@@ -319,9 +298,9 @@ impl RawNode<Leader> {
319
298
Ok ( index)
320
299
}
321
300
322
- /// Commits any new log entries that have been replicated to a quorum,
323
- /// and schedules them for state machine application .
324
- fn maybe_commit ( & mut self ) -> Result < Index > {
301
+ /// Commits any new log entries that have been replicated to a quorum, and
302
+ /// applies them to the state machine.
303
+ fn maybe_commit_and_apply ( & mut self ) -> Result < Index > {
325
304
// Determine the new commit index, i.e. the last index replicated to a
326
305
// quorum of peers.
327
306
let commit_index = self . quorum_value (
@@ -355,15 +334,28 @@ impl RawNode<Leader> {
355
334
None => panic ! ( "Commit index {} missing" , commit_index) ,
356
335
} ;
357
336
358
- // Commit and apply the new entries.
337
+ // Commit the new entries.
359
338
if commit_index > prev_commit_index {
360
339
self . log . commit ( commit_index) ?;
361
- // TODO: Move application elsewhere, but needs access to applied index.
362
- let mut scan = self . log . scan ( ( prev_commit_index + 1 ) ..=commit_index) ?;
340
+ }
341
+
342
+ // Apply entries.
343
+ let applied_index = self . state . get_applied_index ( ) ;
344
+ if applied_index < commit_index {
345
+ let mut scan = self . log . scan ( ( applied_index + 1 ) ..=commit_index) ?;
363
346
while let Some ( entry) = scan. next ( ) . transpose ( ) ? {
364
- // TODO: Send response.
365
- self . role . writes . remove ( & entry. index ) ;
366
- self . state_tx . send ( Instruction :: Apply { entry } ) ?;
347
+ let index = entry. index ;
348
+ let result = Self :: apply ( & mut self . state , entry) ?;
349
+ if let Some ( write) = self . role . writes . remove ( & index) {
350
+ let response = result. map ( Response :: Mutate ) ;
351
+ // TODO: use self.send() or something.
352
+ self . node_tx . send ( Message {
353
+ from : Address :: Node ( self . id ) ,
354
+ to : write. from ,
355
+ term : self . term ,
356
+ event : Event :: ClientResponse { id : write. id , response } ,
357
+ } ) ?;
358
+ }
367
359
}
368
360
}
369
361
Ok ( commit_index)
@@ -391,8 +383,12 @@ impl RawNode<Leader> {
391
383
if read. seq > read_seq {
392
384
break ;
393
385
}
394
- self . role . reads . pop_front ( ) . unwrap ( ) ;
395
- // TODO: Actually execute the reads.
386
+ let read = self . role . reads . pop_front ( ) . unwrap ( ) ;
387
+ let result = self . state . query ( read. command ) ;
388
+ self . send (
389
+ read. from ,
390
+ Event :: ClientResponse { id : read. id , response : result. map ( Response :: Query ) } ,
391
+ ) ?;
396
392
}
397
393
398
394
Ok ( ( ) )
@@ -417,6 +413,7 @@ impl RawNode<Leader> {
417
413
}
418
414
419
415
#[ cfg( test) ]
416
+ #[ cfg( never) ] // TODO
420
417
mod tests {
421
418
use super :: super :: super :: { Entry , Log } ;
422
419
use super :: super :: tests:: { assert_messages, assert_node} ;
0 commit comments