func (k *Kademlia) DoFindValueIter(contact Contact, searchKey ID, chnl chan FindValueResult) string { // The recipient must return k triples if at all possible. // It may only return fewer than k if it is returning all of the contacts that it has knowledge of. port_str := strconv.Itoa(int(contact.Port)) client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str) if err != nil { log.Fatal("DialHTTP: ", err) } defer client.Close() request := new(FindValueRequest) result := new(FindValueResult) request.MsgID = NewRandomID() request.Sender = k.SelfContact request.Key = searchKey err = client.Call("KademliaCore.FindValue", request, &result) if err != nil { log.Fatal("Call: ", err) return "ERR:DoFindValue call err" } if request.MsgID == result.MsgID { result.SenderContact = contact k.SelfTable.Update(contact) chnl <- *result return "OK: Findvalue" } else { return "ERR: FindValue: req.MsgID != res.MsgID" } }
//-----------------------------------------------------------------// func (k *Kademlia) DoFindNodeIter(contact Contact, searchKey ID, chnl chan FindNodeResult) string { // TODO: Implement // Warining:The recipient must return k triples if at all possible. // It may only return fewer than k if it is returning all of the contacts that it has knowledge of. -----FIXME port_str := strconv.Itoa(int(contact.Port)) client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str) if err != nil { return "DialHTTP:err" } defer client.Close() request := new(FindNodeRequest) result := new(FindNodeResult) request.MsgID = NewRandomID() request.Sender = k.SelfContact request.NodeID = searchKey err = client.Call("KademliaCore.FindNode", request, &result) if err != nil { return "ERR:DoFindValue call err" } if request.MsgID == result.MsgID { /* put returned contact into channel */ result.SenderContact = contact chnl <- *result return "OK, Found Nodes" } return "ERR: FindNOde->req.MsgID!=res.MsgID" // If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>" }
func (k *Kademlia) DoGetVDO(contact Contact, vdoId ID) (string, error) { port_str := strconv.Itoa(int(contact.Port)) client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str) if err != nil { log.Fatal("DialHTTP: ", err) } defer client.Close() req := new(GetVDORequest) res := new(GetVDOResult) req.Sender = k.SelfContact req.MsgID = NewRandomID() req.VdoID = vdoId err = client.Call("KademliaCore.GetVDO", req, &res) if err != nil { log.Fatal("Call: ", err) return "ERR:Doping call err", nil } // If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>" if req.MsgID == res.MsgID { k.SelfTable.Update(res.SenderContact) secret := UnvanishData(k, res.VDO) return string(secret), nil } else { return "ERR: req.MsgID != res.MsgID", nil } }
func (k *Kademlia) DoFindNode(contact *Contact, searchKey ID) (string, FindNodeResult) { // TODO: Implement // Warining:The recipient must return k triples if at all possible. // It may only return fewer than k if it is returning all of the contacts that it has knowledge of. -----FIXME port_str := strconv.Itoa(int(contact.Port)) client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str) if err != nil { log.Fatal("DialHTTP: ", err) } defer client.Close() request := new(FindNodeRequest) result := new(FindNodeResult) request.MsgID = NewRandomID() request.Sender = k.SelfContact request.NodeID = searchKey err = client.Call("KademliaCore.FindNode", request, &result) if err != nil { log.Fatal("Call: ", err) return "ERR:DoFindNode call err", *result } if request.MsgID == result.MsgID { k.SelfTable.Update(*contact) //print the contacts fmt.Println("--------Closest Nodes to", searchKey.AsString(), "---------") for i := 0; i < len(result.Nodes); i++ { fmt.Println(result.Nodes[i].NodeID.AsString()) } return "OK : FindNode", *result } return "ERR: FindNOde->req.MsgID!=res.MsgID", *result // If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>" }
func Test_Proto_HTTP_Large_Timeout(t *testing.T) { t.Skip() srv := &httpTestServer{&baseTestServer{}} port, err := srv.listen() assert.NoError(t, err) srv.start() defer srv.Stop() client, err := rpc.DialHTTPPath("tcp", fmt.Sprintf("127.0.0.1:%d", port), "/v1/rpc") assert.NoError(t, err) defer client.Close() var res, res1 TestMessage req := TestMessage{ "12345678910", []byte(strings.Repeat("0", 1024*1024)), } err = client.Call("ServiceFixture.Ping", &req, &res) assert.NoError(t, err) assert.Equal(t, req, res) time.Sleep(time.Second) err = client.Call("ServiceFixture.Ping", &req, &res1) assert.NoError(t, err) assert.Equal(t, req, res1) }
// This is the function to perform the RPC func (k *Kademlia) DoPing(host net.IP, port uint16) string { // TODO: Implement // dstHostPort := HostPortGenerator(host, port) port_str := strconv.Itoa(int(port)) client, err := rpc.DialHTTPPath("tcp", host.String()+":"+port_str, rpc.DefaultRPCPath+port_str) if err != nil { log.Fatal("DialHTTP: ", err) } defer client.Close() ping := new(PingMessage) pong := new(PongMessage) ping.MsgID = NewRandomID() ping.Sender = k.SelfContact err = client.Call("KademliaCore.Ping", ping, &pong) if err != nil { log.Fatal("Call: ", err) return "ERR:Doping call err" } // If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>" if pong.MsgID == ping.MsgID { k.SelfTable.Update(pong.Sender) return "OK: PONG" } else { return "ERR: PONG.MsgID != ping.MsgID" } }
// Start starts an agreement on new instance. func (p *Paxos) Start(seq int, v Value) { var clients []*rpc.Client for _, peer := range p.peers { addrAndPath := strings.Split(peer, "/") if len(addrAndPath) != 2 { panic(fmt.Sprintf("got: %v, want: ${HOSTNAME}:${PORT}/${RPC_PATH}", addrAndPath)) } addr := addrAndPath[0] rpcPath := addrAndPath[1] client, err := rpc.DialHTTPPath("tcp", addr, rpcPath) if err == nil { clients = append(clients, client) } else { fmt.Printf("Error: %v\n", err) clients = append(clients, nil) } } p.maxSeq++ for _, c := range clients { if c != nil { c.Go("Handler.OnReceiveProposal", &Request{ FromID: p.ID(), Seq: p.Max(), }, &Response{}, nil) } } }
/*** * if the least recently used contact has response, then * ignore the new element. If the least recently used contact * doesn't have response, then delete it and add the new contact. */ func pingToRemove(bucket *[]Contact, contact *Contact, self *Contact) { ping := PingMessage{*self, NewRandomID()} var pong PongMessage remove := 0 port_str := strconv.Itoa(int((*bucket)[0].Port)) client, err := rpc.DialHTTPPath("tcp", Dest((*bucket)[0].Host, (*bucket)[0].Port), rpc.DefaultRPCPath+port_str) if err != nil { remove = 1 } defer client.Close() err = client.Call("KademliaCore.Ping", ping, &pong) if err != nil { remove = 1 } if remove == 1 { *bucket = (*bucket)[1:] *bucket = append(*bucket, *contact) } else { tmp := (*bucket)[0] *bucket = (*bucket)[1:] *bucket = append(*bucket, tmp) } }
func main() { // By default, Go seeds its RNG with 1. This would cause every program to // generate the same sequence of IDs. Use the current nano time to // random numbers rand.Seed(time.Now().UnixNano()) // Get the bind and connect connection strings from command-line arguments. flag.Parse() args := flag.Args() if len(args) != 2 { log.Fatal("Must be invoked with exactly two arguments!\n") } listenStr := args[0] firstPeerStr := args[1] // Create the Kademlia instance fmt.Printf("kademlia starting up!\n") kadem := kademlia.NewKademlia(listenStr) // Confirm our server is up with a PING request and then exit. // Your code should loop forever, reading instructions from stdin and // printing their results to stdout. See README.txt for more details. _, port, _ := net.SplitHostPort(firstPeerStr) client, err := rpc.DialHTTPPath("tcp", firstPeerStr, rpc.DefaultRPCPath+port) if err != nil { log.Fatal("DialHTTP: ", err) } ping := new(kademlia.PingMessage) ping.MsgID = kademlia.NewRandomID() ping.Sender = kadem.Routes.SelfContact var pong kademlia.PongMessage err = client.Call("KademliaCore.Ping", ping, &pong) if err != nil { log.Fatal("Call: ", err) } log.Printf("ping msgID: %s\n", ping.MsgID.AsString()) log.Printf("pong msgID: %s\n", pong.MsgID.AsString()) kadem.Routes.Update(&pong.Sender) in := bufio.NewReader(os.Stdin) quit := false for !quit { line, err := in.ReadString('\n') if err != nil { log.Fatal(err) } line = strings.TrimSpace(line) if line == "" { continue } resp := executeLine(kadem, line) if resp == "quit" { quit = true } else if resp != "" { fmt.Printf("%v\n", resp) } } }
func (k *Kademlia) DoStore(contact *Contact, key ID, value []byte) string { // TODO: Implement // If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>" port_str := strconv.Itoa(int(contact.Port)) client, err := rpc.DialHTTPPath("tcp", contact.Host.String()+":"+port_str, rpc.DefaultRPCPath+port_str) if err != nil { log.Fatal("DialHTTP: ", err) } defer client.Close() storeRequest := new(StoreRequest) storeResult := new(StoreResult) storeRequest.MsgID = NewRandomID() storeRequest.Sender = k.SelfContact storeRequest.Key = key storeRequest.Value = value err = client.Call("KademliaCore.Store", storeRequest, &storeResult) if err != nil { log.Fatal("Call: ", err) return "ERR: Dostore call err" } // If all goes well, return "OK: <output>", otherwise print "ERR: <messsage>" if storeRequest.MsgID == storeResult.MsgID { k.SelfTable.Update(*contact) fmt.Println("\"", string(value), "\" stored in \"", contact.NodeID.AsString(), "\"") return "OK: Store" } else { return "ERR: storeRequest.MsgID != storeResult.MsgID" } return "ERR: Not implemented" }
func sendQuery(c Contact, active *ConcurrMap, waitChan chan int, nodeChan chan Contact) { args := FindNodeRequest{c, NewRandomID(), c.NodeID} var reply FindNodeResult active.Lock() active.m[c.NodeID] = 1 active.Unlock() port_str := strconv.Itoa(int(c.Port)) client, err := rpc.DialHTTPPath("tcp", Dest(c.Host, c.Port), rpc.DefaultRPCPath+port_str) if err != nil { log.Fatal("DialHTTP", err) active.Lock() active.m[c.NodeID] = 0 active.Unlock() } defer client.Close() err = client.Call("KademliaCore.FindNode", args, &reply) if err != nil { log.Fatal("Call: ", err) active.Lock() active.m[c.NodeID] = 0 active.Unlock() } active.RLock() a := active.m[c.NodeID] active.RUnlock() if a == 1 { for _, node := range reply.Nodes { nodeChan <- node } } waitChan <- 1 }
func Benchmark_Proto_HTTP_Large(b *testing.B) { b.Skip() srv := &httpTestServer{&baseTestServer{}} port, err := srv.listen() assert.NoError(b, err) srv.start() defer srv.Stop() client, err := rpc.DialHTTPPath("tcp", fmt.Sprintf("127.0.0.1:%d", port), "/v1/rpc") assert.NoError(b, err) defer client.Close() b.Log(port, b.N) b.ResetTimer() for i := 0; i < b.N; i++ { b.StartTimer() var res TestMessage req := TestMessage{ fmt.Sprintf("%d", i), []byte(strings.Repeat("0", 1024*1024)), } err = client.Call("ServiceFixture.Ping", &req, &res) b.StopTimer() assert.NoError(b, err) assert.Equal(b, req, res) b.SetBytes(int64(len(req.Data) * 2)) } }
func BenchmarkRPCGet(b *testing.B) { b.StopTimer() client, _ := rpc.DialHTTPPath("tcp", "localhost:2000", "/rpc") b.StartTimer() var reply string for i := 0; i < b.N; i++ { client.Call("Responder.Get", "test", &reply) } }
func (c *RPCClient) Connect() (err error) { if c.client == nil { c.client, err = rpc.DialHTTPPath( "tcp", c.endpoint.Host, c.endpoint.Path+"/rpc") } return }
func NewRunner(rpcService string, port int) *Run { client, err := rpc.DialHTTPPath("tcp", fmt.Sprintf(":%d", port), "/") if err != nil { panic(err.Error()) } return &Run{ client: client, rpcService: rpcService, } }
func DialHTTPPath(network string, dialer Address, path string) (*Client, error) { client, err := rpc.DialHTTPPath(network, dialer.String(), path) if err != nil { return nil, err } return &Client{ network: network, dialer: dialer, mu: new(sync.RWMutex), c: client, }, nil }
func MakePingCall(k *Kademlia, remoteHost net.IP, remotePort uint16) bool { var localContact *Contact var client *rpc.Client var remoteAddrStr string var err error localContact = &(k.ContactInfo) remoteAddrStr = remoteHost.String() + ":" + strconv.FormatUint(uint64(remotePort), 10) Printf("MakePingCall: From %s --> To %s:%d\n", k, Verbose, localContact.AsString(), remoteHost.String(), remotePort) ping := new(Ping) ping.MsgID = NewRandomID() ping.Sender = CopyContact(localContact) pong := new(Pong) //Dial the server if RunningTests == true { var portstr string = RpcPath + strconv.FormatInt(int64(remotePort), 10) Printf("test ping to rpcPath:%s\n", k, Verbose, portstr) client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", remoteAddrStr) } if err != nil { Printf("Error: MakePingCall, DialHTTP, %s\n", k, Verbose, err) return false } //make rpc err = client.Call("Kademlia.Ping", ping, &pong) if err != nil { Printf("Error: MakePingCall, Call, %s\n", k, Verbose, err) return false } client.Close() //log.Printf("About to update with our pong...") //log.Printf("update buffer len: %d\n", len(k.UpdateChannel)) //update the remote node contact information k.UpdateChannel <- pong.Sender //log.Printf("update buffer len: %d\n", len(k.UpdateChannel)) //log.Printf("Stuffed out pong in the channel for the sender...") return true }
func MakeStore(k *Kademlia, remoteContact *Contact, Key ID, Value []byte) bool { var client *rpc.Client var localContact *Contact var storeReq *StoreRequest var storeRes *StoreResult var remoteAddrStr string var remotePortStr string var err error localContact = &(k.ContactInfo) remoteAddrStr = remoteContact.Host.String() + ":" + strconv.Itoa(int(remoteContact.Port)) dbg.Printf("MakeStore: From %s --> To %s\n", Verbose, localContact.AsString(), remoteContact.AsString()) storeReq = new(StoreRequest) storeReq.MsgID = NewRandomID() storeReq.Sender = CopyContact(localContact) storeReq.Key = CopyID(Key) storeReq.Value = Value storeRes = new(StoreResult) remotePortStr = strconv.Itoa(int(remoteContact.Port)) //Dial the server if RunningTests == true { //if we're running tests, need to DialHTTPPath var portstr string = RpcPath + remotePortStr client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", remoteAddrStr) } if err != nil { Printf("Error: MakeStore, DialHTTP, %s\n", k, Verbose, err) return false } //make the rpc err = client.Call("Kademlia.Store", storeReq, &storeRes) if err != nil { Printf("Error: MakeStore, Call, %s\n", k, Verbose, err) return false } client.Close() //update the remote node contact information k.UpdateChannel <- *remoteContact return true }
// dialRPCClient tries to establish a connection to the server in a safe manner func (rpcClient *RPCClient) dialRPCClient() (*rpc.Client, error) { rpcClient.mu.Lock() defer rpcClient.mu.Unlock() // After acquiring lock, check whether another thread may not have already dialed and established connection if rpcClient.rpcPrivate != nil { return rpcClient.rpcPrivate, nil } rpc, err := rpc.DialHTTPPath("tcp", rpcClient.node, rpcClient.rpcPath) if err != nil { return nil, err } else if rpc == nil { return nil, errors.New("No valid RPC Client created after dial") } rpcClient.rpcPrivate = rpc return rpcClient.rpcPrivate, nil }
func (server *Server) rpcCallback(subscribeArg *SubscribeArg) func(args ...interface{}) { return func(args ...interface{}) { client, connErr := rpc.DialHTTPPath("tcp", subscribeArg.ClientAddr, subscribeArg.ClientPath) defer client.Close() if connErr != nil { fmt.Errorf("Dialing", connErr) } clientArg := new(ClientArg) clientArg.Topic = subscribeArg.Topic clientArg.Args = args var reply bool err := client.Call(subscribeArg.ServiceMethod, clientArg, &reply) if err != nil { fmt.Errorf("Dialing", err) } } }
func New(host, path, name string) *slave { // Connect to master cl, err := rpc.DialHTTPPath("tcp", host, path) if err != nil { return nil } // Register at master var result bool cl.Call("master.RegisterSlave", name, &result) if !result { return nil } return &slave{ client: cl, name: name, } }
//calls the RPC function 'CreateCircuit' on the next DryMartini in the route func MakeCircuitCreateCall(dm *DryMartini, nextNodeAddrStr string, encryptedArray [][]byte) bool { var client *rpc.Client var err error dbg.Printf("MakeCircuitCreateCall: %s\n", Verbose, nextNodeAddrStr) if kademlia.RunningTests == true { //log.Printf("Unimplemented\n") //panic(1) var nextNodePort string = strings.Split(nextNodeAddrStr, ":")[1] if nextNodePort == "" { dbg.Printf("error getting next port: MakeSendCall\n", ERRORS) return false } var portstr string = kademlia.RpcPath + nextNodePort dbg.Printf("test makeCircuitCreateCall to rpcPath:%s\n", Verbose, portstr) client, err = rpc.DialHTTPPath("tcp", nextNodeAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", nextNodeAddrStr) } if err != nil { dbg.Printf("Error: MakeCircuitCreateCall, DialHTTP, %s\n", ERRORS, err) return false } //make rpc var req *CCRequest = new(CCRequest) req.EncryptedData = encryptedArray var res *CCResponse = new(CCResponse) err = client.Call("DryMartini.CreateCircuit", req, res) if err != nil { dbg.Printf("Error: CreateCircuit, Call, %s\n", ERRORS, err) return false } dbg.Printf("got DistributeSymm response: %s:%v\n", Verbose, nextNodeAddrStr, res.Success) client.Close() return res.Success }
//makes a DryMartini.ServeDrink call on address with the Olive data, returning success and returned data if any func MakeSendCall(dataLump Olive, nextNodeAddrStr string) (bool, []byte) { var client *rpc.Client var err error dbg.Printf("MakeSendCall:: next: %s!", Verbose, nextNodeAddrStr) if kademlia.RunningTests == true { //log.Printf("Unimplemented\n") //panic(1) var nextNodePort string = strings.Split(nextNodeAddrStr, ":")[1] if nextNodePort == "" { log.Printf("error getting next port: MakeSendCall\n") panic(1) } var portstr string = kademlia.RpcPath + nextNodePort log.Printf("test MakeSendCall to rpcPath:%s\n", portstr) client, err = rpc.DialHTTPPath("tcp", nextNodeAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", nextNodeAddrStr) } if err != nil { log.Printf("Error: MakeSendCall, DialHTTP, %s\n", err) return false, nil } //make rpc var res *ServerResp = new(ServerResp) var req *ServerData = new(ServerData) req.Sent = dataLump err = client.Call("DryMartini.ServeDrink", req, res) if err != nil { log.Printf("Error: SendCall, Call, %s\n", err) return false, nil } dbg.Printf("got SendCall response: %s:%v\n", Verbose, nextNodeAddrStr, res.Success) client.Close() return res.Success, res.Data }
func Test_Proto_HTTP(t *testing.T) { t.Skip() srv := &httpTestServer{&baseTestServer{}} port, err := srv.listen() assert.NoError(t, err) srv.start() defer srv.Stop() client, err := rpc.DialHTTPPath("tcp", fmt.Sprintf("127.0.0.1:%d", port), "/v1/rpc") assert.NoError(t, err) defer client.Close() var res TestMessage req := TestMessage{ "12345678910", []byte("mama myla ramu"), } err = client.Call("ServiceFixture.Ping", &req, &res) assert.NoError(t, err) assert.Equal(t, req, res) }
func (client *Client) doSubscribe(topic string, fn interface{}, serverAddr, serverPath string, subscribeType SubscribeType) { defer func() { if r := recover(); r != nil { fmt.Println("Server not found -", r) } }() rpcClient, err := rpc.DialHTTPPath("tcp", serverAddr, serverPath) defer rpcClient.Close() if err != nil { fmt.Errorf("dialing:", err) } args := &SubscribeArg{client.address, client.path, PublishService, subscribeType, topic} reply := new(bool) err = rpcClient.Call(RegisterService, args, reply) if err != nil { fmt.Errorf("Register error:", err) } if *reply { client.eventBus.Subscribe(topic, fn) } }
// Initialize new rpc client. func newRPCClient(networkPath string) (StorageAPI, error) { // Input validation. if networkPath == "" || strings.LastIndex(networkPath, ":") == -1 { return nil, errInvalidArgument } // TODO validate netAddr and netPath. netAddr, netPath := splitNetPath(networkPath) // Dial minio rpc storage http path. rpcClient, err := rpc.DialHTTPPath("tcp", netAddr, storageRPCPath) if err != nil { return nil, err } // Initialize http client. httpClient := &http.Client{ // Setting a sensible time out of 6minutes to wait for // response headers. Request is pro-actively cancelled // after 6minutes if no response was received from server. Timeout: 6 * time.Minute, Transport: http.DefaultTransport, } // Initialize network storage. ndisk := &networkStorage{ netScheme: "http", // TODO: fix for ssl rpc support. netAddr: netAddr, netPath: netPath, rpcClient: rpcClient, httpClient: httpClient, } // Returns successfully here. return ndisk, nil }
func TestServerRPC(t *testing.T) { hooksServerPort := 61322 var addr = fmt.Sprintf(":%d", hooksServerPort) if os.Getenv("RUN_HOOKS") == "1" { server := NewServer(&run) fmt.Println("Running the server") server.Serve() defer server.Listener.Close() return } cmd := exec.Command(os.Args[0], "-test.run=TestServerRPC", fmt.Sprintf("-port=%d", hooksServerPort)) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Env = append(os.Environ(), "RUN_HOOKS=1") go func() { err := cmd.Run() fmt.Println("Command exited with error " + err.Error()) }() time.Sleep(2000 * time.Millisecond) client, err := rpc.DialHTTPPath("tcp", addr, "/") defer cmd.Process.Kill() defer client.Close() if err != nil { log.Fatal("dialing:", err) } testCases := []struct { Method string args interface{} reply interface{} }{ { Method: "RunBeforeEach", args: trans.Transaction{Name: "Test"}, reply: trans.Transaction{}, }, { Method: "RunBefore", args: trans.Transaction{Name: "Test"}, reply: trans.Transaction{}, }, { Method: "RunBeforeValidation", args: trans.Transaction{Name: "Test"}, reply: trans.Transaction{}, }, { Method: "RunBeforeEachValidation", args: trans.Transaction{Name: "Test"}, reply: trans.Transaction{}, }, { Method: "RunAfterEach", args: trans.Transaction{Name: "Test"}, reply: trans.Transaction{}, }, { Method: "RunAfter", args: trans.Transaction{Name: "Test"}, reply: trans.Transaction{}, }, } for _, test := range testCases { args := test.args.(trans.Transaction) reply := test.reply.(trans.Transaction) method := test.Method err = client.Call("DummyRunner."+method, args, &reply) if err != nil { t.Errorf("rpc client failed to connect to server: %s", err.Error()) } // DummyRunner will set the transaction to the value of the args variable. // See rpc.go for more detail. if reply.Name != "Test" { t.Errorf("RPC method %s was never invoked", method) } } // Testing for RunBeforeAll and RunAfter All allCases := []struct { Method string args []*trans.Transaction }{ { Method: "RunBeforeAll", args: []*trans.Transaction{&trans.Transaction{Name: "Test"}}, }, { Method: "RunAfterAll", args: []*trans.Transaction{&trans.Transaction{Name: "Test"}}, }, } for _, test := range allCases { args := test.args var reply []*trans.Transaction method := test.Method err = client.Call("DummyRunner."+method, args, &reply) if err != nil { t.Errorf("rpc client failed to connect to server: %s", err.Error()) } // DummyRunner will set the transaction to the value of the args variable. // See rpc.go for more detail. if reply[0].Name != "Test" { t.Errorf("RPC method %s was never invoked", method) } } }
//func MakeFindValue(k *Kademlia, remoteContact *Contact, Key ID, fvChan chan *FindValueCallResponse) (bool, []byte, *[]FoundNode) { func MakeFindValueCall(k *Kademlia, remoteContact *Contact, Key ID, fvChan chan *FindStarCallResponse) { var findValueReq *FindValueRequest var findValueRes *FindValueResult var remoteAddrStr string var remotePortStr string var client *rpc.Client var localContact *Contact var resultSet *FindStarCallResponse var err error localContact = &(k.ContactInfo) remoteAddrStr = remoteContact.Host.String() + ":" + strconv.Itoa(int(remoteContact.Port)) dbg.Printf("MakeFindValue[%s]: From %s --> To %s\n", Verbose, Key.AsString(), localContact.AsString(), remoteContact.AsString()) findValueReq = new(FindValueRequest) findValueReq.MsgID = NewRandomID() findValueReq.Sender = CopyContact(localContact) findValueReq.Key = CopyID(Key) findValueRes = new(FindValueResult) resultSet = new(FindStarCallResponse) resultSet.ReturnedFVRes = findValueRes resultSet.ReturnedFNRes = nil resultSet.Responder = remoteContact.ContactToFoundNode() resultSet.Responded = false remotePortStr = strconv.Itoa(int(remoteContact.Port)) //Dial the server if RunningTests == true { //if we're running tests, need to DialHTTPPath var portstr string = RpcPath + remotePortStr //log.Printf("test FindNodeValue to rpcPath:%s\n", portstr) client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", remoteAddrStr) } if err != nil { dbg.Printf("Error: MakeFindValueCall, DialHTTP, %s\n", Verbose, err) fvChan <- resultSet return } //make rpc err = client.Call("Kademlia.FindValue", findValueReq, &findValueRes) if err != nil { Printf("Error: MakeFindValue, Call, %s\n", k, Verbose, err) fvChan <- resultSet return } //Mark the result as being good resultSet.Responded = true fvChan <- resultSet client.Close() //update the remote node contact information k.UpdateChannel <- *remoteContact return }
//Makes a FindNodeCall on remoteContact. returns list of KClosest nodes on that contact, and the id of the remote node //REVIEW //George: On the ground that this should be an asynchronous call, I modified the definition of the function //func MakeFindNodeCall(localContact *Contact, remoteContact *Contact, NodeChan chan *FindNodeCallResponse) (*FindNodeResult, bool) { func MakeFindNodeCall(k *Kademlia, remoteContact *Contact, searchKey ID, NodeChan chan *FindStarCallResponse) { var fnRequest *FindNodeRequest var fnResult *FindNodeResult var remoteAddrStr string var remotePortStr string var client *rpc.Client var resultSet *FindStarCallResponse var err error var localContact *Contact localContact = &(k.ContactInfo) remoteAddrStr = remoteContact.Host.String() + ":" + strconv.Itoa(int(remoteContact.Port)) dbg.Printf("MakeFindNodeCall: From %s --> To %s\n", Verbose, localContact.AsString(), remoteContact.AsString()) fnRequest = new(FindNodeRequest) fnRequest.MsgID = NewRandomID() fnRequest.Sender = CopyContact(localContact) fnRequest.NodeID = CopyID(searchKey) fnResult = new(FindNodeResult) resultSet = new(FindStarCallResponse) resultSet.ReturnedFNRes = fnResult resultSet.ReturnedFVRes = nil resultSet.Responder = remoteContact.ContactToFoundNode() resultSet.Responded = false remotePortStr = strconv.Itoa(int(remoteContact.Port)) //Dial the server if RunningTests == true { //if we're running tests, need to DialHTTPPath var portstr string = RpcPath + remotePortStr //log.Printf("test FindNodeCall to rpcPath:%s\n", portstr) client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", remoteAddrStr) } if err != nil { dbg.Printf("Error: MakeFindNodeCall, DialHTTP, %s\n", Verbose, err) NodeChan <- resultSet return } err = client.Call("Kademlia.FindNode", fnRequest, &fnResult) if err != nil { Printf("Error: MakeFindNodeCall, Call, %s\n", k, Verbose, err) NodeChan <- resultSet return } //if you get any nodes update you kbuckets with them //Jack: REVIEW: I'm not sure if we do want to update on only //'heard of' nodes. Only when we make direct contact no? //Also look at similar block in MakeFindValueCall /* for _, node := range fnResult.Nodes { k.UpdateChannel <- *(node.FoundNodeToContact()) }*/ // Mark the result as being good resultSet.Responded = true NodeChan <- resultSet client.Close() //update the remote node contact information k.UpdateChannel <- *remoteContact return }