Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add method to get leader node/address or make submitQuery be public #13

Open
jxnu-liguobin opened this issue Jun 1, 2022 · 2 comments

Comments

@jxnu-liguobin
Copy link
Contributor

  • Because this code cannot be used in third-party packages.
// in server
  private[server] def getState: ZIO[Any, Nothing, NodeState] = raftRef.get.flatMap(_.nodeState)

// in test
        _ <- ZIO.collectAll(servers.map(_.getState)).repeatUntil { states =>
          states.count(_ == NodeState.Leader) == 1 &&
          states.count(_ == NodeState.Follower) == 2
        }

So, raft is now unable to return to the current leader node, maybe a method should be added,like getLeader?

  • I use zio-grpc to implement the server, but raft's submitQuery is private, so I can't query based on that.

These are two different ways, if I can get the leader (direct connection) or have access to the query (multiple forwarding), both can provide the service. If you think it is feasible, I will work on this.

@jxnu-liguobin jxnu-liguobin changed the title Add method to get leader node/address or make submitQuery to public Add method to get leader node/address or make submitQuery be public Jun 1, 2022
@ariskk
Copy link
Owner

ariskk commented Jun 1, 2022

submitQuery is private because the implementation is incomplete.
This method should respond only if the current node is still the leader. I think it would be best if submitQuery was properly implemented. If you just add a getLeader and then make submitQuery public you don't verify leader status before reading.

From spec:

Read-only operations can be handled without writing
anything into the log. However, with no additional measures,
this would run the risk of returning stale data, since
the leader responding to the request might have been superseded
by a newer leader of which it is unaware. Linearizable reads must not return stale data, and Raft needs
two extra precautions to guarantee this without using the
log. First, a leader must have the latest information on
which entries are committed. The Leader Completeness
Property guarantees that a leader has all committed entries, but at the start of its term, it may not know which
those are. To find out, it needs to commit an entry from
its term. Raft handles this by having each leader commit
a blank no-op entry into the log at the start of its
term. Second, a leader must check whether it has been
deposed before processing a read-only request (its information may be stale if a more recent leader has been elected).
Raft handles this by having the leader exchange heartbeat messages with a majority of the cluster before responding to read-only requests. Alternatively, the leader
could rely on the heartbeat mechanism to provide a form
of lease [9], but this would rely on timing for safety (it
assumes bounded clock skew).

So basically a heartbeat round-trip is needed before responding.

Ideally, we need two methods:

  • a proper sumbitQuery that either redirects or checks leadership and responds
  • a second method to check node state for testing.

@jxnu-liguobin
Copy link
Contributor Author

Thanks for your reply. I'm trending to implement sumbitQuery correctly and making it public.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants