Closed patriknw closed 10 years ago
Awesome!, thanks a lof for the comments Patrick!
Some of these I totally missed, so super grateful about the feedback - I'll address those today after work :-)
Q1: While we're at it, I did have a question about style of passing data around in an FSM.
So my replicatedLog
is as an actor's field (same with nextIndex
and matchIndex
): https://github.com/ktoso/akka-raft/blob/master/src/main/scala/pl/project13/scala/akka/raft/RaftActor.scala#L28
On one hand it feels normal to have this here - it's the member's state; but I was thinking that I use the FSM state (Meta
, LeaderMeta
etc) for passing around "some" (where "some" is not clearly defined yet) parts of the state. Do you think it's worth it to move everything (replicatedLog
and friends) to the Meta
class, and keep the actor's body more empty? Testing wise I do access replicatedLog direcly via underlyingActor
in a few "single state" tests.
Q2:
I'm thinking if it's worth-while to provide an RaftClientActor
, which would take care of tracking "who is the leader right now", so you could raft ! "test"
without having (as user of this pattern), to worry about reacting to responses like "oh but the leader isn't me anymore, it's member-3". Might be a nice bonus to make this lib more usable I guess, thoughts?
Something like:
trait RaftClientActor {
var leader: Option[ActorRef] = None
// pseudocode
def aroundReceive(...) = msg match {
case LeaderChanged(newLeader, inReplyToThisMsg) => // so we sent the message to a follower / candidate, it told us about the new leader
leader = newLeader
leader ! inReplyToThisMsg
case _ =>
receive(msg)
}
}
class Client extends RaftClientActor {
def receive = { case _ => leader ! "hello" }
}
So it would hide the fact the leader is changing from the end-user-api, and try to redeliver the message to the right leader. Do you think it's a good idea to provide this?
Thanks a a lot in advance :-)
Q1: It's possible to put all state in the FSM, but if it's something that exists for all FSM states it can be more convenient to have them as instance variables as you have done.
Q2: RaftClientActor is a good idea. An alternative (not sure if it's better or not) to a trait is to provide RaftClientActor as a concrete actor that you send the messages via, like a proxy. It could also stash messages if there is no leader at the moment.
Yes, I considered a proxy actor too hm hm, let's see what looks nicer when implementeed... Thanks for the feedback! :-)
Thanks again for the comments, addressed most of them, some left for the weekend :-)
Great work Konrad! I was curious to see how you had used Akka in this interesting project. Wrote a few minor comments. Let me know if you have any questions.