func main() { rand.Seed(time.Now().UnixNano()) var debug bool cli := command.App() cli.Global(func(flag command.Flags) { flag.BoolVar(&debug, "debug", false, "Show debug messages") }) cli.Command("datanode", "Run storage node", func(flag command.Flags) { listener := command.ListenerFlag(flag, "port", 0, "") dataDir := flag.String("dataDir", "_data", "") leaderAddress := flag.String("leaderAddress", "[::1]:5051", "") heartbeatInterval := flag.Duration("heartbeatInterval", 3*time.Second, "") flag.Parse() conf := datanode.Config{ DataDir: *dataDir, Debug: debug, Listener: listener.Get(), HeartbeatInterval: *heartbeatInterval, LeaderAddress: *leaderAddress} datanode.Create(conf) // Wait on goroutines <-make(chan bool) }) cli.Command("metadatanode", "Run leader", func(flag command.Flags) { clientListener := command.ListenerFlag(flag, "clientPort", 5050, "") clusterListener := command.ListenerFlag(flag, "clusterPort", 5051, "") replicationFactor := flag.Int("replicationFactor", 2, "") flag.Parse() log.Println("Replication factor of", *replicationFactor) conf := metadatanode.Config{ clientListener.Get(), clusterListener.Get(), *replicationFactor, "metadata.db"} metadatanode.Create(conf) // Wait on goroutines <-make(chan bool) }) cli.Command("upload", "Upload a file", func(flag command.Flags) { file := command.FileFlag(flag, "file", "") leaderAddress := flag.String("leaderAddress", "[::1]:5050", "") flag.Parse() upload.Upload(file.Get(), debug, *leaderAddress) }) cli.Run() }
// Here's a test. It uploads 18 small blobs onto 2 data nodes, then starts // 2 additional datanodes, then downloads the blobs. // TODO: // - Decommission nodes // - Check that files are the same // - Random data // - Bigger blobs / more blocks func TestIntegration(*testing.T) { mdnClientListener, err := net.Listen("tcp", "[::1]:0") if err != nil { log.Fatal(err) } mdnClusterListener, err := net.Listen("tcp", "[::1]:0") if err != nil { log.Fatal(err) } _, _ = metadatanode.Create(metadatanode.Config{ ClientListener: mdnClientListener, ClusterListener: mdnClusterListener, ReplicationFactor: 2, DatabaseFile: "metadata.test.db", }) log.Println(mdnClusterListener.Addr().String()) dnListener1, err := net.Listen("tcp", ":0") if err != nil { log.Fatal(err) } _, _ = datanode.Create(datanode.Config{ Listener: dnListener1, LeaderAddress: mdnClusterListener.Addr().String(), DataDir: "_data", HeartbeatInterval: 1 * time.Second, }) dnListener2, err := net.Listen("tcp", ":0") if err != nil { log.Fatal(err) } _, _ = datanode.Create(datanode.Config{ Listener: dnListener2, LeaderAddress: mdnClusterListener.Addr().String(), DataDir: "_data2", HeartbeatInterval: 1 * time.Second, }) wg := new(sync.WaitGroup) wg2 := new(sync.WaitGroup) doneBalancing := new(sync.WaitGroup) for _, _ = range make([]bool, 18) { wg.Add(1) wg2.Add(1) doneBalancing.Add(1) go func() { file, err := os.Open("Makefile") if err != nil { panic(err) } blobID := upload.Upload(file, false, mdnClientListener.Addr().String()) wg.Done() doneBalancing.Wait() conn, err := net.Dial("tcp", mdnClientListener.Addr().String()) if err != nil { log.Fatal("Dial error:", err) } defer conn.Close() codec := jsonrpc.NewClientCodec(conn) client := rpc.NewClientWithCodec(codec) var blocks []BlockID fmt.Println(blobID) if err := client.Call("GetBlob", blobID, &blocks); err != nil { log.Fatal("GetBlob error:", err) } fmt.Println(blocks) for _, b := range blocks { for { conn, err := net.Dial("tcp", mdnClientListener.Addr().String()) if err != nil { log.Fatal("Dial error:", err) } defer conn.Close() codec := jsonrpc.NewClientCodec(conn) client := rpc.NewClientWithCodec(codec) var nodes []string if err := client.Call("GetBlock", b, &nodes); err != nil { log.Fatal("GetBlock error:", err) } fmt.Println(nodes) sort.Sort(ByRandom(nodes)) conn, err = net.Dial("tcp", nodes[0]) if err != nil { log.Fatalln("Dial error:", err) } defer conn.Close() codec = jsonrpc.NewClientCodec(conn) client = rpc.NewClientWithCodec(codec) if err := client.Call("Get", b, nil); err != nil { if fmt.Sprint(err) == "Couldn't get read lock" { time.Sleep(100 * time.Millisecond) continue } log.Fatalln(err) } if _, err := io.Copy(ioutil.Discard, conn); err != nil { log.Fatalln(err) } break } } wg2.Done() }() } wg.Wait() dnListener3, err := net.Listen("tcp", ":0") if err != nil { log.Fatal(err) } _, _ = datanode.Create(datanode.Config{ Listener: dnListener3, LeaderAddress: mdnClusterListener.Addr().String(), DataDir: "_data3", HeartbeatInterval: 1 * time.Second, }) dnListener4, err := net.Listen("tcp", ":0") if err != nil { log.Fatal(err) } _, _ = datanode.Create(datanode.Config{ Listener: dnListener4, LeaderAddress: mdnClusterListener.Addr().String(), DataDir: "_data4", HeartbeatInterval: 1 * time.Second, }) time.Sleep(5 * time.Second) for _, _ = range make([]bool, 18) { doneBalancing.Done() } wg2.Wait() }