func TestReplication(t *testing.T) { data_dir := "/tmp/test_replication" os.RemoveAll(data_dir) masterCfg := new(config.Config) masterCfg.DataDir = fmt.Sprintf("%s/master", data_dir) masterCfg.Addr = "127.0.0.1:11182" masterCfg.BinLog.MaxFileSize = 1 * 1024 * 1024 masterCfg.BinLog.MaxFileNum = 10 var master *App var slave *App var err error master, err = NewApp(masterCfg) if err != nil { t.Fatal(err) } defer master.Close() slaveCfg := new(config.Config) slaveCfg.DataDir = fmt.Sprintf("%s/slave", data_dir) slaveCfg.Addr = "127.0.0.1:11183" slaveCfg.SlaveOf = masterCfg.Addr slave, err = NewApp(slaveCfg) if err != nil { t.Fatal(err) } defer slave.Close() go master.Run() db, _ := master.ldb.Select(0) value := make([]byte, 10) db.Set([]byte("a"), value) db.Set([]byte("b"), value) db.HSet([]byte("a"), []byte("1"), value) db.HSet([]byte("b"), []byte("2"), value) go slave.Run() time.Sleep(1 * time.Second) if err = checkDataEqual(master, slave); err != nil { t.Fatal(err) } db.Set([]byte("a1"), value) db.Set([]byte("b1"), value) db.HSet([]byte("a1"), []byte("1"), value) db.HSet([]byte("b1"), []byte("2"), value) time.Sleep(1 * time.Second) if err = checkDataEqual(master, slave); err != nil { t.Fatal(err) } slave.slaveof("") db.Set([]byte("a2"), value) db.Set([]byte("b2"), value) db.HSet([]byte("a2"), []byte("1"), value) db.HSet([]byte("b2"), []byte("2"), value) db.Set([]byte("a3"), value) db.Set([]byte("b3"), value) db.HSet([]byte("a3"), []byte("1"), value) db.HSet([]byte("b3"), []byte("2"), value) if err = checkDataEqual(master, slave); err == nil { t.Fatal("must error") } slave.slaveof(masterCfg.Addr) time.Sleep(1 * time.Second) if err = checkDataEqual(master, slave); err != nil { t.Fatal(err) } }
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) flag.Parse() var cfg *config.Config var err error if len(*configFile) == 0 { println("no config set, using default config") cfg = config.NewConfigDefault() } else { cfg, err = config.NewConfigWithFile(*configFile) } if err != nil { println(err.Error()) return } if len(*addr) > 0 { cfg.Addr = *addr } if len(*dataDir) > 0 { cfg.DataDir = *dataDir } if len(*dbName) > 0 { cfg.DBName = *dbName } if *databases > 0 { cfg.Databases = *databases } // check bool flag, use it. for _, arg := range os.Args { arg := strings.ToLower(arg) switch arg { case "-rpl", "-rpl=true", "-rpl=false": cfg.UseReplication = *rpl case "-readonly", "-readonly=true", "-readonly=false": cfg.Readonly = *readonly case "-rpl_sync", "-rpl_sync=true", "-rpl_sync=false": cfg.Replication.Sync = *rplSync } } if len(*slaveof) > 0 { cfg.SlaveOf = *slaveof cfg.Readonly = true cfg.UseReplication = true } if *ttlCheck > 0 { cfg.TTLCheckInterval = *ttlCheck } var app *server.App app, err = server.NewApp(cfg) if err != nil { println(err.Error()) return } sc := make(chan os.Signal, 1) signal.Notify(sc, os.Kill, os.Interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) if *usePprof { go func() { log.Println(http.ListenAndServe(fmt.Sprintf(":%d", *pprofPort), nil)) }() } go app.Run() <-sc println("ledis-server is closing") app.Close() println("ledis-server is closed") }