follow :: (RaftLog l e v) => Raft l e v -> IO ()
follow vRaft = do
    initialRaft <- atomically $ do
        modifyTVar (raftContext vRaft) $ \oldRaft -> 
            setRaftMembers M.empty
                $ setRaftLeader Nothing oldRaft
        readTVar (raftContext vRaft)
    let name = raftName initialRaft
        term = raftCurrentTerm initialRaft
    infoM _log $ printf "Server %v following in term %v" name term
    raceAll_ [doFollow vRaft,
                doVote vRaft,
                doRedirect vRaft]

{-|
    As a follower, wait for 'AppendEntries' requests and process them,
    commit new changes as necessary, and stop when no heartbeat received.
-}
follow :: (RaftLog l e v) => Raft l e v -> IO ()
follow vRaft = do
    initialRaft <- atomically $ do
        modifyTVar (raftContext vRaft) $ \oldRaft -> 
            setRaftMembers M.empty
                $ setRaftLeader Nothing oldRaft
        readTVar (raftContext vRaft)
    let name = raftName initialRaft
        term = raftCurrentTerm initialRaft
    infoM _log $ printf "Server %v following in term %v" name term
    raceAll_ [doFollow vRaft,
                doVote vRaft,
                doRedirect vRaft]

{-|
    As a follower, wait for 'AppendEntries' requests and process them,
    commit new changes as necessary, and stop when no heartbeat received.
-}
follow vRaft = do
    initialRaft <- atomically $ do
        modifyTVar (raftContext vRaft) $ \oldRaft -> 
            setRaftMembers M.empty
                $ setRaftLeader Nothing oldRaft
        readTVar (raftContext vRaft)
    let name = raftName initialRaft
        term = raftCurrentTerm initialRaft
    infoM _log $ printf "Server %v following in term %v" name term
    raceAll_ [doFollow vRaft,
                doVote vRaft,
                doRedirect vRaft]

{-|
    As a follower, wait for 'AppendEntries' requests and process them,
    commit new changes as necessary, and stop when no heartbeat received.
-}