@ file : Suppress (" UNUSED _ PARAMETER ", Ġ" UNUSED _ VARIABLE ") Ċ Ċ package Ġdev . sv ilen iv an ov . raft kt . core Ċ Ċ import Ġdev . sv ilen iv an ov . raft kt . core . Node Role . FOL LOWER Ċ import Ġkotlinx . datetime . Clock Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġorg . slf 4 j . Logger Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġorg . slf 4 j . Marker Ċ Ċ @ Serializable Ċ data Ġclass ĠRpc Header ( val Ġprotocol Version : ĠProtocol Version ) Ċ Ċ interface ĠWith Header Ġ{ ĊĠĠĠ Ġval Ġheader : ĠRpc Header Ċ } Ċ Ċ sealed Ġclass ĠRpc Ġ: ĠWith Header Ġ{ ĊĠĠĠ Ġsealed Ġclass ĠRequest Ġ: ĠRpc () Ġ{ ĊĠĠĠĠĠĠĠ Ġabstract Ġval Ġterm : ĠLong ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsealed Ġclass ĠResponse Ġ: ĠRpc () ĊĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġdata Ġclass ĠAppend Entries Request ( ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġheader : ĠRpc Header , ĊĊĠĠĠĠĠĠĠ Ġ// ĠProvide Ġthe Ġcurrent Ġterm Ġand Ġleader ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġterm : ĠLong , ĊĠĠĠĠĠĠĠ Ġval Ġleader : ĠNode , ĊĠĠĠĠĠĠĠ Ġ// ĠProvide Ġthe Ġprevious Ġentries Ġfor Ġintegrity Ġchecking ĊĠĠĠĠĠĠĠ Ġval Ġprev Log : ĠPosition , ĊĠĠĠĠĠĠĠ Ġ// ĠNew Ġentries Ġto Ġcommit ĊĠĠĠĠĠĠĠ Ġval Ġentries : ĠList < Log >, ĊĠĠĠĠĠĠĠ Ġ// ĠCommit Ġindex Ġon Ġthe Ġleader ĊĠĠĠĠĠĠĠ Ġval Ġleader Commit Index : ĠLong ĊĠĠĠ Ġ) Ġ: ĠRpc . Request () ĊĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġdata Ġclass ĠAppend Entries Response ( ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġheader : ĠRpc Header , ĊĊĠĠĠĠĠĠĠ Ġ// ĠNew er Ġterm Ġif Ġleader Ġis Ġout Ġof Ġdate ĊĠĠĠĠĠĠĠ Ġval Ġterm : ĠLong , ĊĠĠĠĠĠĠĠ Ġ// ĠLast ĠLog Ġis Ġa Ġhint Ġto Ġhelp Ġaccel erate Ġre building Ġslow Ġnodes ĊĠĠĠĠĠĠĠ Ġval Ġlast Log : ĠPosition , ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġmay Ġnot Ġsucceed Ġif Ġwe Ġhave Ġa Ġconflicting Ġentry ĊĠĠĠĠĠĠĠ Ġval Ġsuccess : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġ// ĠThere Ġare Ġscenarios Ġwhere Ġthis Ġrequest Ġdidn 't Ġsucceed ĊĠĠĠĠĠĠĠ Ġ// Ġbut Ġthere 's Ġno Ġneed Ġto Ġwait / back - off Ġthe Ġnext Ġattempt . ĊĠĠĠĠĠĠĠ Ġval Ġno Retry Backoff : ĠBoolean ĊĠĠĠ Ġ) Ġ: ĠRpc . Response () ĊĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġdata Ġclass ĠRequest Vote Request ( ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġheader : ĠRpc Header , ĊĊĠĠĠĠĠĠĠ Ġ// ĠProvide Ġthe Ġterm Ġand Ġour Ġid ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġterm : ĠLong , ĊĠĠĠĠĠĠĠ Ġval Ġcandidate : ĠNode , ĊĊĠĠĠĠĠĠĠ Ġ// ĠUsed Ġto Ġensure Ġsafety ĊĠĠĠĠĠĠĠ Ġval Ġlast Log : ĠPosition , ĊĊĠĠĠĠĠĠĠ Ġ// ĠUsed Ġto Ġindicate Ġto Ġpeers Ġif Ġthis Ġvote Ġwas Ġtriggered Ġby Ġa Ġle adership ĊĠĠĠĠĠĠĠ Ġ// Ġtransfer . ĠIt Ġis Ġrequired Ġfor Ġle adership Ġtransfer Ġto Ġwork , Ġbecause Ġservers ĊĠĠĠĠĠĠĠ Ġ// Ġwouldn 't Ġvote Ġotherwise Ġif Ġthey Ġare Ġaware Ġof Ġan Ġexisting Ġleader . ĊĠĠĠĠĠĠĠ Ġval Ġle adership Transfer : ĠBoolean ĊĠĠĠ Ġ) Ġ: ĠRpc . Request () ĊĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġdata Ġclass ĠRequest Vote Response ( ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġheader : ĠRpc Header , ĊĊĠĠĠĠĠĠĠ Ġ// ĠNew er Ġterm Ġif Ġleader Ġis Ġout Ġof Ġdate . ĊĠĠĠĠĠĠĠ Ġval Ġterm : ĠLong , ĊĠĠĠĠĠĠĠ Ġ// ĠIs Ġthe Ġvote Ġgranted . ĊĠĠĠĠĠĠĠ Ġval Ġgranted : ĠBoolean ĊĠĠĠ Ġ) Ġ: ĠRpc . Response () Ċ Ċ } Ċ Ċ class ĠRpc Handler ( ĊĠĠĠ Ġprivate Ġval Ġconsensus : ĠCons ensus , ĊĠĠĠ Ġprivate Ġval Ġf sm Apply : ĠF sm Apply , ĊĠĠĠ Ġprivate Ġval Ġmarker : ĠMarker , ĊĠĠĠ Ġprivate Ġval Ġheader : ĠRpc Header , ĊĠĠĠ Ġprivate Ġval Ġclock : ĠClock Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġlogger : ĠLogger Ġ= ĠLoggerFactory . getLogger ( Rpc Handler :: class . java ) ĊĊĠĠĠ Ġsuspend Ġfun Ġrespond ( req : ĠRpc . Request ): ĠRpc . Response Ġ= Ġconsensus . use Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( req ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRpc . Append Entries Request Ġ-> Ġappend Entries ( req ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRpc . Request Vote Request Ġ-> Ġrequest Vote ( req ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvolatile . last Contact Ġ= Ġclock . now () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun ĠCons ensus . append Entries ( req : ĠRpc . Append Entries Request ): ĠRpc . Append Entries Response Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( req . term Ġ> Ġpersistent . current Term Ġ|| Ġrole Ġ!= ĠFOL LOWER ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . current Term Ġ= Ġreq . term ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( marker , Ġ" Ste pping Ġdown Ġdue Ġto Ġreceiving Ġappend Ġentries Ġwith Ġterm Ġ{}", Ġreq . term ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrole Ġ= ĠFOL LOWER ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġleader Ġ= Ġreq . leader . id ĊĠĠĠĠĠĠĠ Ġ// ĠIgnore Ġan Ġolder Ġterm ĊĠĠĠĠĠĠĠ Ġif Ġ( req . term Ġ< Ġpersistent . current Term ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmarker , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" reject ing Ġappend Ġfrom Ġleader Ġ{} Ġfor Ġterm Ġ{}, Ġour Ġterm Ġ{} Ġis Ġnewer ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . leader , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . term , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . current Term ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠRpc . Append Entries Response ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheader Ġ= Ġheader , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġterm Ġ= Ġpersistent . current Term , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Log Ġ= Ġpersistent . last Log , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġno Retry Backoff Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( req . prev Log . index Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Log Term Ġ= Ġif Ġ( req . prev Log Ġ== Ġpersistent . last Log ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . last Log . term ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . log . getLog ( req . prev Log . index )?. position ?. term ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prev Log Term Ġ!= Ġreq . prev Log . term ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmarker , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" previous Ġlog Ġterm Ġmis - match Ġat Ġindex Ġ{}, Ġour Ġlog Ġentry Ġterm Ġ{}, Ġremote Ġlog Ġentry Ġterm Ġ{}", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . prev Log . index , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Log Term , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . prev Log . term ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠRpc . Append Entries Response ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheader Ġ= Ġheader , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġterm Ġ= Ġpersistent . current Term , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Log Ġ= Ġpersistent . last Log , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġno Retry Backoff Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġnew Entries : ĠList < Log > Ġ= Ġempty List () ĊĠĠĠĠĠĠĠ Ġfor Ġ(( i , Ġentry ) Ġin Ġreq . entries . with Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . position . index Ġ> Ġpersistent . last Log . index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Entries Ġ= Ġreq . entries . sub List ( i , Ġreq . entries . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstore Entry Ġ= Ġpersistent . log . getLog ( entry . position . index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( store Entry Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn ( marker , Ġ" log Ġentry Ġat Ġposition Ġ{} Ġis Ġnot Ġfound ", Ġentry . position . index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠRpc . Append Entries Response ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheader Ġ= Ġheader , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġterm Ġ= Ġpersistent . current Term , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Log Ġ= Ġpersistent . last Log , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġno Retry Backoff Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . position . term Ġ!= Ġstore Entry . position . term ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn ( marker , Ġ" clear ing Ġlog Ġsuffix Ġfrom Ġ{} Ġto Ġ{}", Ġentry . position . index , Ġpersistent . last Log . index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . log . delete Range ( entry . position . index .. persistent . last Log . index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Entries Ġ= Ġreq . entries . sub List ( i , Ġreq . entries . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġnew Entries . forEach Ġ{ Ġpersistent . log . store Log ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġnew Entries . last OrNull ()?. also Ġ{ Ġpersistent . last Log Ġ= Ġit . position Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( req . leader Commit Index Ġ> Ġ 0 Ġ&& Ġreq . leader Commit Index Ġ> Ġvolatile . commit Index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġidx Ġ= Ġmin Of ( req . leader Commit Index , Ġpersistent . last Log . index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvolatile . commit Index Ġ= Ġidx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġf sm Apply . process Logs ( this , Ġidx ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠRpc . Append Entries Response ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġheader Ġ= Ġheader , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġterm Ġ= Ġpersistent . current Term , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Log Ġ= Ġpersistent . last Log , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuccess Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġno Retry Backoff Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun ĠCons ensus . request Vote ( req : ĠRpc . Request Vote Request ): ĠRpc . Request Vote Response Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġv oted For Ġ= Ġpersistent . v oted For ĊĊĠĠĠĠĠĠĠ Ġif Ġ( req . term Ġ> Ġpersistent . current Term ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . current Term Ġ= Ġreq . term ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( marker , Ġ" Ste pping Ġdown Ġdue Ġto Ġreceiving Ġnew Ġterm Ġ{}", Ġreq . term ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrole Ġ= ĠFOL LOWER ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġgranted Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġwe Ġhave Ġan Ġexisting Ġleader Ġ[ who 's Ġnot Ġthe Ġcandidate ] Ġand Ġalso ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġthe ĠLe adership Transfer Ġflag Ġis Ġset . ĠUsually Ġvotes Ġare Ġrejected Ġif ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthere Ġis Ġa Ġknown Ġleader . ĠBut Ġif Ġthe Ġleader Ġinitiated Ġa Ġle adership Ġtransfer , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġvote ! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġleader Ġ!= Ġnull Ġ&& Ġleader Ġ!= Ġreq . candidate . id Ġ&& Ġ! req . le adership Transfer Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn ( marker , Ġ" reject ing Ġvote Ġrequest Ġfrom Ġ{} Ġsince Ġwe Ġhave Ġa Ġleader Ġ{}", Ġreq . candidate , Ġleader ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreq . term Ġ< Ġpersistent . current Term Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmarker , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" reject ing Ġvote Ġto Ġcandidate Ġ{} Ġfor Ġterm Ġ{}, Ġour Ġterm Ġ{} Ġis Ġnewer ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . candidate , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . term , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . current Term ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġv oted For Ġ!= Ġnull Ġ&& Ġv oted For . term Ġ== Ġreq . term Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgranted Ġ= Ġv oted For . id Ġ== Ġreq . candidate . id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmarker , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" duplicate Ġrequest Vote Ġfor Ġsame Ġterm Ġ{} Ġfrom Ġ{} Ġ( gr anted ={ })", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . term , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . candidate , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgranted ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgranted ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . last Log . term Ġ> Ġreq . last Log . term ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġ( persistent . last Log . term Ġ== Ġreq . last Log . term Ġ&& Ġpersistent . last Log . index Ġ> Ġreq . last Log . index ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmarker , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" reject ing Ġvote Ġrequest Ġsince Ġour Ġposition Ġ{} Ġis Ġgreater Ġthan Ġcandidate 's Ġ{} Ġposition Ġ{}", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . last Log , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . candidate , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . last Log ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmarker , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" grant ing Ġvote Ġrequest Ġto Ġ{} Ġbecause Ġits Ġlog Ġis Ġat Ġleast Ġas Ġup Ġto Ġdate Ġ({ }) Ġas Ġour s Ġ({ })", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . candidate , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreq . last Log , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . last Log ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpersistent . v oted For Ġ= ĠV ote For ( req . candidate . id , Ġreq . term ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠRpc . Request Vote Response ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġheader Ġ= Ġheader , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġterm Ġ= Ġpersistent . current Term , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgranted Ġ= Ġgranted ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ } ĊĊ