func (chordNode *ChordNode) ForwardRequest(reqPar []interface{}) (ServerInfoWithID, error) { //Unmarshal into array of interfaces var parameters []interface{} parameters = reqPar //Use dict3 struct to unmarshall var key string var relation string for k, v := range parameters { if k == 0 { key = v.(string) } else if k == 1 { relation = v.(string) } else if k == 2 { //dict3.Value = v } } var finalChordID uint32 finalChordID = chordNode.GetHashFromKeyAndValue(key, relation) //findsuccessor for finalChordID //create json message jsonMessage := rpcclient.RequestParameters{} jsonMessage.Method = "findSuccessor" jsonMessage.Params = make([]interface{}, 1) jsonMessage.Params[0] = finalChordID jsonBytes, err := json.Marshal(jsonMessage) if err != nil { chordNode.Logger.Println(err) return ServerInfoWithID{}, err } chordNode.Logger.Println(string(jsonBytes)) //make FindSuccessor call on the same node - chordNode.MyServerInfo client := &rpcclient.RPCClient{} err, response := client.RpcCall(chordNode.MyServerInfo, string(jsonBytes)) if err != nil { chordNode.Logger.Println(err) return ServerInfoWithID{}, err } var successorInfo ServerInfoWithID successorInfo.Id = uint32((response.(*(rpcclient.ResponseParameters)).Result[0]).(float64)) //again marshal and unmarshal - reason it was getting marshalled into map[string]interface{} serverInfoBytes, _ := json.Marshal(response.(*(rpcclient.ResponseParameters)).Result[1]) if err = json.Unmarshal(serverInfoBytes, &(successorInfo.ServerInfo)); err != nil { chordNode.Logger.Println(err) return ServerInfoWithID{}, err } return successorInfo, nil }
/* Called in Shutdown - keys are transferred to successor */ func (rpcServer *RPCServer) makeInsertsToSuccessor() { //open a read transaction rpcServer.boltDB.View(func(tx *bolt.Tx) error { var cursor *bolt.Cursor cursor = tx.Cursor() var bucket *bolt.Bucket //traverse through all keys for k, _ := cursor.First(); k != nil; k, _ = cursor.Next() { bucket = tx.Bucket(k) //traverse through all relation and value pairs bucket.ForEach(func(relation, value []byte) error { //create paramter - successor //add to array of interface parameterArray := make([]interface{}, 3) parameterArray[0] = string(k) parameterArray[1] = string(relation) parameterArray[2] = string(value) //create json message jsonMessage := rpcclient.RequestParameters{} jsonMessage.Method = "Insert" jsonMessage.Params = parameterArray jsonBytes, err := json.Marshal(jsonMessage) if err != nil { rpcServer.logger.Println(err) return err } rpcServer.logger.Println(string(jsonBytes)) clientServerInfo, err := rpcServer.chordNode.PrepareClientServerInfo(rpcServer.chordNode.FingerTable[1]) if err != nil { rpcServer.logger.Println(err) return nil } client := &rpcclient.RPCClient{} err, _ = client.RpcCall(clientServerInfo, string(jsonBytes)) if err != nil { rpcServer.logger.Println(err) return nil } return nil }) } return nil }) }
//transfer keys to successor //n has to notify its predecessor p and successor s before leaving func (chordNode *ChordNode) NotifyShutDownToRing() { if !chordNode.isPredecessorNil { //rpc call to successor - tell successor about my predecessor //create paramter to be sent - predecessor parameter := ServerInfoWithID{} parameter.Id = chordNode.Predecessor parameter.ServerInfo = chordNode.FtServerMapping[chordNode.Predecessor] //create json message jsonMessage := rpcclient.RequestParameters{} jsonMessage.Method = "PredecessorLeft" jsonMessage.Params = make([]interface{}, 1) jsonMessage.Params[0] = parameter jsonBytes, err := json.Marshal(jsonMessage) if err != nil { chordNode.Logger.Println(err) return } chordNode.Logger.Println(string(jsonBytes)) //prepare server info clientServerInfo, err := chordNode.PrepareClientServerInfo(chordNode.FingerTable[1]) if err == nil { client := &rpcclient.RPCClient{} err, _ := client.RpcCall(clientServerInfo, string(jsonBytes)) if err != nil { chordNode.Logger.Println(err) } } else { chordNode.Logger.Println(err) } //rpc call to predecessor - tell predecessor about my successor //create paramter - successor parameter = ServerInfoWithID{} parameter.Id = chordNode.FingerTable[1] parameter.ServerInfo = chordNode.FtServerMapping[chordNode.FingerTable[1]] //create json message jsonMessage = rpcclient.RequestParameters{} jsonMessage.Method = "SuccessorLeft" jsonMessage.Params = make([]interface{}, 1) jsonMessage.Params[0] = parameter jsonBytes, err = json.Marshal(jsonMessage) if err != nil { chordNode.Logger.Println(err) return } chordNode.Logger.Println(string(jsonBytes)) clientServerInfo, err = chordNode.PrepareClientServerInfo(chordNode.Predecessor) if err == nil { client := &rpcclient.RPCClient{} err, _ := client.RpcCall(clientServerInfo, string(jsonBytes)) if err != nil { chordNode.Logger.Println(err) } } else { chordNode.Logger.Println(err) } } //if not predecessor nil }