Skip to content

Conversation

@suraj44
Copy link
Contributor

@suraj44 suraj44 commented Aug 14, 2020

Resolves #16

This pull request adds the ability to host SimpleLockService on a cluster of nodes in consensus. Consensus is maintained using the Raft algorithm. The Hashicorp implementation of the algorithm has been used.

A struct of type RaftStore has been created. It has the following fields -

  • a listener
  • an instance of SimpleLockService
  • the HTTP address of the listener
  • fields required by Hashicorp's implementation - (RaftDir, RaftAddr, RaftServer)

Each Raft node has an associated HTTP listener. If a request is sent to the listener of the leader of a cluster, then the listener commits the operation on the associated Raft node if possible. If a request is sent to the listener of a follower in the cluster, this request is redirected to the listener of the leader. The implementation is such that the listener has an IP address with a port number that is one more than the port number of the associated Raft node. (for example, if the IP address of a Raft node is 127.0.0.1:5000, then the IP address of its listener is 127.0.0.1:5001). getHTTPAddr() and getListenerAddr() functions implement this mapping.

Redirection of HTTP requests to the listener of the leader node has been tested in simple_client_test.go along with the tests that are already present.

@suraj44 suraj44 added the enhancement New feature or request label Aug 14, 2020
@suraj44 suraj44 requested a review from SUMUKHA-PK August 14, 2020 11:52
Copy link
Contributor

@SUMUKHA-PK SUMUKHA-PK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not gonna review the core lockclient or lockservice yet as this is gonna be merged after my PR.

This is a first round of review just for code semantics, I'll have future rounds based on the correctness.

So far, good job!

func (f *fsm) Apply(l *raft.Log) interface{} {
var c command
if err := json.Unmarshal(l.Data, &c); err != nil {
panic(fmt.Sprintf("failed to unmarshal command: %s", err.Error()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you not panic and return the error?
Panics stop the system function, we shouldn't allow that.

return f.applyRelease(c.Key, c.Value)

default:
panic(fmt.Sprintf("unrecognized command op: %s", c.Op))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for panic here


// Snapshot returns a snapshot of the key-value store. We wrap
// the things we need in fsmSnapshot and then send that over to Persist.
// Persist encodes the needed data from fsmsnapshot and transport it to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Persist encodes the needed data from fsmsnapshot and transport it to
// Persist encodes the needed data from fsmsnapshot and transports it to

}

// Set the state from snapshot. No need to use mutex lock according
// to Hasicorp doc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// to Hasicorp doc
// to Hasicorp doc.


func (f *fsmSnapshot) Persist(sink raft.SnapshotSink) error {
err := func() error {
// Encode data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Encode data

// If a node already exists with either the joining node's ID or address,
// that node may need to be removed from the config first.
if srv.ID == raft.ServerID(nodeID) || srv.Address == raft.ServerAddress(addr) {
// However if *both* the ID and the address are the same, then nothing -- not even
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// However if *both* the ID and the address are the same, then nothing -- not even
// However if BOTH the ID and the address are the same, then nothing, not even

// that node may need to be removed from the config first.
if srv.ID == raft.ServerID(nodeID) || srv.Address == raft.ServerAddress(addr) {
// However if *both* the ID and the address are the same, then nothing -- not even
// a join operation -- is needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// a join operation -- is needed.
// a join operation, is needed.

"github.com/gorilla/mux"
)

// func (rs *lockservice.RaftStore) Start() error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed.

// lockservice's lock map.
// This function is used by the Snapshot() function of the
// finite state machine of the distributed consensus algorithm
func (ls *SimpleLockService) GetLockMap() map[string]string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You said copy, return the copy.
Here locking is of no use since you're returning the actual map anyway.

// function
func (ls *SimpleLockService) SetLockMap(lockMapSnapshot map[string]string) {
// Set the state from snapshot. No need to use mutex lock according
// to Hasicorp doc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// to Hasicorp doc
// to Hashicorp doc

@SUMUKHA-PK SUMUKHA-PK changed the title Adds the ability to host SimpleLockService using a cluster of nodes in consensus with Raft Going Distributed Aug 23, 2020
@SUMUKHA-PK
Copy link
Contributor

This PR will be kept on hold until #24 and #25 are resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lockservice: Go distributed.

3 participants