func TestBasicPing(t *testing.T) { // setup test database hd := GetTestDbConnection() ResetDb(hd) CreateTables(hd) masterhost := port("localhost", 58293) StartServer(masterhost, hd) workerhost := port("localhost", 13243) worker := client.MakeMasterClerk(workerhost, masterhost) // register and ping 1 worker if id := worker.Register(false); id < 0 { t.Fatalf("Worker1 could not register with master") } if ok := worker.Ping(false); ok != client.OK { t.Fatalf("Worker1 could not ping master, got %v", ok) } // register and ping a new worker at the same address worker2 := client.MakeMasterClerk(workerhost, masterhost) if id := worker2.Register(false); id < 0 { t.Fatalf("Worker2 could not register with master") } if ok := worker2.Ping(false); ok != client.OK { t.Fatalf("Worker1 could not ping master, got %v", ok) } // worker 1 should not be able to ping, since it was replaced by // worker 2 if ok := worker.Ping(false); ok != client.RESET { t.Fatalf("Worker1 should have received RESET, got %v", ok) } fmt.Printf(" ... Passed\n") }
func StartServer(hostname string, masterhost string) *Worker { // call gob.Register on structures you want // Go's RPC library to marshall/unmarshall. // gob.Register() runtime.GOMAXPROCS(7) gopath := os.Getenv("GOPATH") if _, err := os.Stat(gopath + "/src/segments"); err != nil { if os.IsNotExist(err) { os.Mkdir(gopath+"/src/segments", 0777) } else { panic(err) } } client.Debug("Starting worker") worker := new(Worker) worker.master = client.MakeMasterClerk(hostname, masterhost) worker.batches = make(map[int][]int64) worker.max_segments = 50000 rpcs := rpc.NewServer() rpcs.Register(worker) // ignore the domain name: listen on all urls splitName := strings.Split(hostname, ":") l, e := net.Listen("tcp", ":"+splitName[1]) if e != nil { log.Fatal("listen error: ", e) } worker.l = l // Register the worker to master client.Debug("Registering worker") worker.master.Register(true) client.Debug("Registered worker") worker.segments = NewLRU(worker.max_segments, worker.master.GetId()) go func() { for { if conn, err := worker.l.Accept(); err == nil { go rpcs.ServeConn(conn) } else { worker.kill() } } }() go func() { for { // Continuously ping the master so that the master is notified // when a network partition is resolved. reply := worker.master.Ping(true) if reply == client.RESET { panic("ping rejected by master") } time.Sleep(1 * time.Second) } }() return worker }