func (zkts *Server) CreateTablet(tablet *topo.Tablet) error { zkTabletPath := TabletPathForAlias(tablet.Alias()) // Create /zk/<cell>/vt/tablets/<uid> _, err := zk.CreateRecursive(zkts.zconn, zkTabletPath, tablet.Json(), 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { err = topo.ErrNodeExists } return err } // Create /zk/<cell>/vt/tablets/<uid>/action tap := path.Join(zkTabletPath, "action") _, err = zkts.zconn.Create(tap, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { return err } // Create /zk/<cell>/vt/tablets/<uid>/actionlog talp := path.Join(zkTabletPath, "actionlog") _, err = zkts.zconn.Create(talp, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { return err } return nil }
func (s *S) TestRetryChangeSetting(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "old", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) err = conn.RetryChange("/test", zk.EPHEMERAL, []zk.ACL{}, func(data string, stat *zk.Stat) (string, error) { c.Assert(data, Equals, "old") c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) return "brand new", nil }) c.Assert(err, IsNil) data, stat, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 1) c.Assert(data, Equals, "brand new") // ACL was unchanged by RetryChange(). acl, _, err := conn.ACL("/test") c.Assert(err, IsNil) c.Assert(acl, DeepEquals, zk.WorldACL(zk.PERM_ALL)) }
// TestPruneActionLogs is a ZK specific unit test func TestPruneActionLogs(t *testing.T) { ctx := context.Background() ts := NewTestServer(t, []string{"test"}) defer ts.Close() if err := ts.CreateKeyspace(ctx, "test_keyspace", &topo.Keyspace{}); err != nil { t.Fatalf("CreateKeyspace: %v", err) } actionLogPath := path.Join(globalKeyspacesPath, "test_keyspace", "actionlog") zkts := ts.Server.(*Server) if _, err := zk.CreateRecursive(zkts.zconn, actionLogPath+"/0", "first", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil { t.Fatalf("CreateRecursive(stale): %v", err) } if _, err := zk.CreateRecursive(zkts.zconn, actionLogPath+"/1", "second", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil { t.Fatalf("CreateRecursive(fresh): %v", err) } if count, err := zkts.PruneActionLogs(actionLogPath, 1); err != nil || count != 1 { t.Fatalf("PruneActionLogs: %v %v", err, count) } actionLogs, _, err := zkts.zconn.Children(actionLogPath) if err != nil || len(actionLogs) != 1 || actionLogs[0] != "1" { t.Errorf("PruneActionLogs kept the wrong things: %v %v", err, actionLogs) } }
// Create the persistence node in zookeeper func (zk *ZK) create() error { // create zk root path tpath := "" for _, str := range strings.Split(Conf.ZookeeperPath, "/")[1:] { tpath += "/" + str Log.Debug("create zookeeper path:%s", tpath) _, err := zk.conn.Create(tpath, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { Log.Warn("zk.create(\"%s\") exists", tpath) } else { Log.Error("zk.create(\"%s\") error(%v)", tpath, err) return err } } } // create node path fpath := fmt.Sprintf("%s/%s", Conf.ZookeeperPath, Conf.ZookeeperNode) Log.Debug("create zookeeper path:%s", fpath) _, err := zk.conn.Create(fpath, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { Log.Warn("zk.Create(\"%s\") exists", fpath) } else { Log.Error("zk.Create(\"%s\") error(%v)", fpath, err) return err } } return nil }
// TestPurgeActions is a ZK specific unit test func TestPurgeActions(t *testing.T) { ctx := context.Background() ts := NewTestServer(t, []string{"test"}) defer ts.Close() if err := ts.CreateKeyspace(ctx, "test_keyspace", &topo.Keyspace{}); err != nil { t.Fatalf("CreateKeyspace: %v", err) } actionPath := path.Join(globalKeyspacesPath, "test_keyspace", "action") zkts := ts.Server.(*Server) if _, err := zk.CreateRecursive(zkts.zconn, actionPath+"/topurge", "purgeme", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil { t.Fatalf("CreateRecursive(topurge): %v", err) } if _, err := zk.CreateRecursive(zkts.zconn, actionPath+"/tokeep", "keepme", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil { t.Fatalf("CreateRecursive(tokeep): %v", err) } if err := zkts.PurgeActions(actionPath, func(data string) bool { return data == "purgeme" }); err != nil { t.Fatalf("PurgeActions(tokeep): %v", err) } actions, _, err := zkts.zconn.Children(actionPath) if err != nil || len(actions) != 1 || actions[0] != "tokeep" { t.Errorf("PurgeActions kept the wrong things: %v %v", err, actions) } }
// UpdateShardReplicationFields is part of the topo.Server interface func (zkts *Server) UpdateShardReplicationFields(ctx context.Context, cell, keyspace, shard string, update func(*topodatapb.ShardReplication) error) error { // create the parent directory to be sure it's here zkDir := path.Join("/zk", cell, "vt", "replication", keyspace) if _, err := zk.CreateRecursive(zkts.zconn, zkDir, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil && !zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { return convertError(err) } // now update the data zkPath := shardReplicationPath(cell, keyspace, shard) f := func(oldValue string, oldStat zk.Stat) (string, error) { sr := &topodatapb.ShardReplication{} if oldValue != "" { if err := json.Unmarshal([]byte(oldValue), sr); err != nil { return "", err } } if err := update(sr); err != nil { return "", err } data, err := json.MarshalIndent(sr, "", " ") if err != nil { return "", err } return string(data), nil } err := zkts.zconn.RetryChange(zkPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { return convertError(err) } return nil }
// Create the persistence node in zookeeper func (zk *ZK) Create(path string, node string) error { // create zk root path tpath := "" for _, str := range strings.Split(path, "/")[1:] { tpath += "/" + str Log.Debug("create zookeeper path:%s", tpath) _, err := zk.conn.Create(tpath, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { Log.Warn("zk.Create(\"%s\") exists", tpath) } else { Log.Error("zk.Create(\"%s\") failed (%s)", tpath, err.Error()) return err } } } // create node path fpath := path + "/" + node Log.Debug("create zookeeper path:%s", fpath) _, err := zk.conn.Create(fpath, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { Log.Warn("zk.Create(\"%s\") exists", fpath) } else { Log.Error("zk.Create(\"%s\") failed (%s)", fpath, err.Error()) return err } } return nil }
func (s *S) TestRetryChangeConflictOnCreate(c *C) { conn, _ := s.init(c) changeFunc := func(data string, stat *zk.Stat) (string, error) { switch data { case "": c.Assert(stat, IsNil) _, err := conn.Create("/test", "conflict", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) return "<none> => conflict", nil case "conflict": c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) return "conflict => new", nil default: c.Fatal("Unexpected node data: " + data) } return "can't happen", nil } err := conn.RetryChange("/test", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL), changeFunc) c.Assert(err, IsNil) data, stat, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "conflict => new") c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 1) }
// UpdateEndPoints is part of the topo.Server interface func (zkts *Server) UpdateEndPoints(ctx context.Context, cell, keyspace, shard string, tabletType topodatapb.TabletType, addrs *topodatapb.EndPoints, existingVersion int64) error { path := zkPathForVtName(cell, keyspace, shard, tabletType) data, err := json.MarshalIndent(addrs, "", " ") if err != nil { return err } if existingVersion == -1 { // Update or create unconditionally. _, err := zk.CreateRecursive(zkts.zconn, path, string(data), 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { // Node already exists - just stomp away. Multiple writers shouldn't be here. // We use RetryChange here because it won't update the node unnecessarily. f := func(oldValue string, oldStat zk.Stat) (string, error) { return string(data), nil } err = zkts.zconn.RetryChange(path, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) } } return err } // Compare And Set if _, err = zkts.zconn.Set(path, string(data), int(existingVersion)); err != nil { if zookeeper.IsError(err, zookeeper.ZBADVERSION) { err = topo.ErrBadVersion } else if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } } return err }
func setUpFakeZk(t *testing.T) { conn = fakezk.NewConn() conn.Create("/zk", "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) conn.Create("/zk/fake", "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) conn.Create("/zk/fake/customrules", "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) conn.Create("/zk/fake/customrules/testrules", "customrule1", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) conn.Set("/zk/fake/customrules/testrules", customRule1, -1) }
func (zkd *Zkd) init(preserveData bool) error { log.Infof("zkd.Init") for _, path := range zkd.config.DirectoryList() { if err := os.MkdirAll(path, 0775); err != nil { log.Errorf(err.Error()) return err } // FIXME(msolomon) validate permissions? } configData, err := zkd.makeCfg() if err == nil { err = ioutil.WriteFile(zkd.config.ConfigFile(), []byte(configData), 0664) } if err != nil { log.Errorf("failed creating %v: %v", zkd.config.ConfigFile(), err) return err } err = zkd.config.WriteMyid() if err != nil { log.Errorf("failed creating %v: %v", zkd.config.MyidFile(), err) return err } if err = zkd.Start(); err != nil { log.Errorf("failed starting, check %v", zkd.config.LogDir()) return err } zkAddr := fmt.Sprintf("localhost:%v", zkd.config.ClientPort) zk, session, err := zookeeper.Dial(zkAddr, StartWaitTime*time.Second) if err != nil { return err } event := <-session if event.State != zookeeper.STATE_CONNECTED { return err } defer zk.Close() if !preserveData { _, err = zk.Create("/zk", "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil && !zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { return err } if zkd.config.Global { _, err = zk.Create("/zk/global", "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil && !zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { return err } } } return nil }
func (c *Coordinator) createPaths() { c.basePath = path.Join("/", c.config.JobId) c.lockPath = path.Join(c.basePath, LockPath) c.workersPath = path.Join(c.basePath, WorkersPath) c.barriersPath = path.Join(c.basePath, BarriersPath) c.zk.Create(c.basePath, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) c.zk.Create(c.workersPath, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) c.zk.Create(c.barriersPath, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) }
func CreateOrUpdate(zconn Conn, zkPath, value string, flags int, aclv []zookeeper.ACL, recursive bool) (pathCreated string, err error) { if recursive { pathCreated, err = CreateRecursive(zconn, zkPath, value, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) } else { pathCreated, err = zconn.Create(zkPath, value, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) } if err != nil && zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { pathCreated = "" _, err = zconn.Set(zkPath, value, -1) } return }
func (s *S) TestChildrenAndWatch(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) children, stat, watch, err := conn.ChildrenW("/") c.Assert(err, IsNil) c.Assert(children, DeepEquals, []string{"zookeeper"}) c.Assert(stat.NumChildren(), Equals, 1) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(zk.CountPendingWatches(), Equals, 2) _, err = conn.Create("/test1", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, zk.EVENT_CHILD) c.Assert(event.Path, Equals, "/") c.Check(zk.CountPendingWatches(), Equals, 1) children, stat, watch, err = conn.ChildrenW("/") c.Assert(err, IsNil) c.Assert(stat.NumChildren(), Equals, 2) // The ordering is most likely unstable, so this test must be fixed. c.Assert(children, DeepEquals, []string{"test1", "zookeeper"}) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(zk.CountPendingWatches(), Equals, 2) _, err = conn.Create("/test2", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) event = <-watch c.Assert(event.Type, Equals, zk.EVENT_CHILD) c.Check(zk.CountPendingWatches(), Equals, 1) }
func NewTestServer(t *testing.T, cells []string) *TestServer { zconn := fakezk.NewConn() // create the toplevel zk paths if _, err := zk.CreateRecursive(zconn, "/zk/global/vt", "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil { t.Fatalf("cannot init ZooKeeper: %v", err) } for _, cell := range cells { if _, err := zk.CreateRecursive(zconn, fmt.Sprintf("/zk/%v/vt", cell), "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil { t.Fatalf("cannot init ZooKeeper: %v", err) } } return &TestServer{Server: NewServer(zconn), localCells: cells} }
func (s *S) TestCreateAndGet(c *C) { conn, _ := s.init(c) path, err := conn.Create("/test-", "bababum", zk.SEQUENCE|zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) c.Assert(path, Matches, "/test-[0-9]+") // Check the error condition from Create(). _, err = conn.Create(path, "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Check(zk.IsError(err, zk.ZNODEEXISTS), Equals, true, Commentf("%v", err)) data, _, err := conn.Get(path) c.Assert(err, IsNil) c.Assert(data, Equals, "bababum") }
// UpdateTabletFields is part of the topo.Server interface func (zkts *Server) UpdateTabletFields(ctx context.Context, tabletAlias *topodatapb.TabletAlias, update func(*topodatapb.Tablet) error) (*topodatapb.Tablet, error) { // Store the last tablet value so we can log it if the change succeeds. var lastTablet *topodatapb.Tablet zkTabletPath := TabletPathForAlias(tabletAlias) f := func(oldValue string, oldStat zk.Stat) (string, error) { if oldValue == "" { return "", fmt.Errorf("no data for tablet addr update: %v", tabletAlias) } tablet := &topodatapb.Tablet{} if err := json.Unmarshal([]byte(oldValue), tablet); err != nil { return "", err } if err := update(tablet); err != nil { return "", err } lastTablet = tablet data, err := json.MarshalIndent(tablet, "", " ") if err != nil { return "", err } return string(data), nil } err := zkts.zconn.RetryChange(zkTabletPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return nil, err } return lastTablet, nil }
func Initzk() { ipport := utils.Cfg.GetString("zkServer") zk1, session, err := zookeeper.Dial(ipport, 5e9) zk = zk1 if err != nil { // log.Fatalf("Can't connect: %v", err) fmt.Println(err) } // defer zk.Close() // Wait for connection. event := <-session if event.State != zookeeper.STATE_CONNECTED { // log.Fatalf("Can't connect: %v", event) fmt.Println(event.String()) } fmt.Println(event) _, err = zk.Create(utils.Cfg.GetString("sendslavers"), "0", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) //zookeeper.EPHEMERAL|zookeeper.SEQUENCE if err != nil { // log.Fatalf("Can't create counter: %v", err) fmt.Println("Can't create counter: %v", err) } else { fmt.Println("Counter created!") } watchslavers() }
func TestChildren(t *testing.T) { conn := NewConn() defer conn.Close() nodes := []string{"/zk", "/zk/foo", "/zk/bar"} wantChildren := []string{"bar", "foo"} for _, path := range nodes { if _, err := conn.Create(path, "", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)); err != nil { t.Fatalf("conn.Create: %v", err) } } children, _, err := conn.Children("/zk") if err != nil { t.Fatalf(`conn.Children("/zk"): %v`, err) } sort.Strings(children) if length := len(children); length != 2 { t.Errorf("children: got %v, wanted %v", children, wantChildren) } for i, path := range children { if wantChildren[i] != path { t.Errorf("children: got %v, wanted %v", children, wantChildren) break } } }
// CreateShard is part of the topo.Server interface func (zkts *Server) CreateShard(ctx context.Context, keyspace, shard string, value *topodatapb.Shard) error { shardPath := path.Join(globalKeyspacesPath, keyspace, "shards", shard) pathList := []string{ shardPath, path.Join(shardPath, "action"), path.Join(shardPath, "actionlog"), } data, err := json.MarshalIndent(value, "", " ") if err != nil { return err } alreadyExists := false for i, zkPath := range pathList { c := "" if i == 0 { c = string(data) } _, err := zk.CreateRecursive(zkts.zconn, zkPath, c, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { alreadyExists = true } else { return fmt.Errorf("error creating shard: %v %v", zkPath, err) } } } if alreadyExists { return topo.ErrNodeExists } return nil }
func DeleteRecursive(zconn Conn, zkPath string, version int) error { // version: -1 delete any version of the node at path - only applies to the top node err := zconn.Delete(zkPath, version) if err == nil { return nil } if !zookeeper.IsError(err, zookeeper.ZNOTEMPTY) { return err } // Remove the ability for other nodes to get created while we are trying to delete. // Otherwise, you can enter a race condition, or get starved out from deleting. err = zconn.SetACL(zkPath, zookeeper.WorldACL(zookeeper.PERM_ADMIN|zookeeper.PERM_DELETE|zookeeper.PERM_READ), version) if err != nil { return err } children, _, err := zconn.Children(zkPath) if err != nil { return err } for _, child := range children { err := DeleteRecursive(zconn, path.Join(zkPath, child), -1) if err != nil && !zookeeper.IsError(err, zookeeper.ZNONODE) { return fmt.Errorf("zkutil: recursive delete failed: %v", err) } } err = zconn.Delete(zkPath, version) if err != nil && !zookeeper.IsError(err, zookeeper.ZNOTEMPTY) { err = fmt.Errorf("zkutil: nodes getting recreated underneath delete (app race condition): %v", zkPath) } return err }
// PubMIDLock public message mid lock, make sure that get the unique mid func PubMIDLock() (bool, string, error) { prefix := "p" splitSign := "@" pathCreated, err := zk.Create(fmt.Sprintf("%s/%s%s", Conf.ZKPIDPath, prefix, splitSign), "0", zookeeper.EPHEMERAL|zookeeper.SEQUENCE, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { return false, pathCreated, fmt.Errorf("zk.Create(%s/%s%s) error(%v)", Conf.ZKPIDPath, prefix, splitSign, err) } for { childrens, stat, err := zk.Children(Conf.ZKPIDPath) if err != nil { return false, pathCreated, fmt.Errorf("zk.Children(%s) error(%v)", Conf.ZKPIDPath, err) } // If node isn`t exist if childrens == nil || stat == nil { return false, pathCreated, fmt.Errorf("node(%s) is not existent", Conf.ZKPIDPath) } var realQueue []string for _, children := range childrens { tmp := strings.Split(children, splitSign) if prefix == tmp[0] { realQueue = append(realQueue, children) } } // Sort sequence nodes sort.Strings(realQueue) tmp := strings.Split(pathCreated, "/") posReal := sort.StringSlice(realQueue).Search(tmp[len(tmp)-1]) // If does not get lock if posReal > 0 { // Watch the last one watchPath := fmt.Sprintf("%s/%s", Conf.ZKPIDPath, realQueue[posReal-1]) _, watch, err := zk.ExistsW(watchPath) if err != nil || zookeeper.IsError(err, zookeeper.ZNONODE) { return false, pathCreated, fmt.Errorf("zk.ExistsW(%s) error(%v) or no node", watchPath, err) } // Watch the lower node watchNode := <-watch switch watchNode.Type { case zookeeper.EVENT_DELETED: default: return false, pathCreated, fmt.Errorf("zookeeper watch errCode:%d", watchNode.Type) } return false, pathCreated, nil } else { return true, pathCreated, nil } } // Never get here return false, pathCreated, fmt.Errorf("never get here") }
// Create an ephemeral node an just wait. func cmdElock(subFlags *flag.FlagSet, args []string) error { subFlags.Parse(args) zkPath := fixZkPath(subFlags.Arg(0)) // Speed up case where we die nicely, otherwise you have to wait for // the server to notice the client's demise. sigRecv := make(chan os.Signal, 1) signal.Notify(sigRecv, os.Interrupt) for { _, err := zconn.Create(zkPath, "", zookeeper.EPHEMERAL, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { return fmt.Errorf("elock: error %v: %v", zkPath, err) } watchLoop: for { _, _, watch, err := zconn.GetW(zkPath) if err != nil { return fmt.Errorf("elock: error %v: %v", zkPath, err) } select { case <-sigRecv: zconn.Delete(zkPath, -1) return nil case event := <-watch: log.Infof("elock: event %v: %v", zkPath, event) if !event.Ok() { //return fmt.Errorf("elock: error %v: %v", zkPath, event) break watchLoop } } } } }
func (zkts *Server) CreateKeyspace(keyspace string, value *topo.Keyspace) error { keyspacePath := path.Join(globalKeyspacesPath, keyspace) pathList := []string{ keyspacePath, path.Join(keyspacePath, "action"), path.Join(keyspacePath, "actionlog"), path.Join(keyspacePath, "shards"), } alreadyExists := false for i, zkPath := range pathList { c := "" if i == 0 { c = jscfg.ToJson(value) } _, err := zk.CreateRecursive(zkts.zconn, zkPath, c, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { alreadyExists = true } else { return fmt.Errorf("error creating keyspace: %v %v", zkPath, err) } } } if alreadyExists { return topo.ErrNodeExists } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *topo.NewKeyspaceInfo(keyspace, value), Status: "created", }) return nil }
func (zkts *Server) UpdateTabletFields(tabletAlias topo.TabletAlias, update func(*topo.Tablet) error) error { zkTabletPath := TabletPathForAlias(tabletAlias) f := func(oldValue string, oldStat zk.Stat) (string, error) { if oldValue == "" { return "", fmt.Errorf("no data for tablet addr update: %v", tabletAlias) } tablet, err := topo.TabletFromJson(oldValue) if err != nil { return "", err } if err := update(tablet); err != nil { return "", err } return jscfg.ToJson(tablet), nil } err := zkts.zconn.RetryChange(zkTabletPath, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { err = topo.ErrNoNode } return err } return nil }
func (zkts *Server) UpdateKeyspace(ki *topo.KeyspaceInfo) error { keyspacePath := path.Join(globalKeyspacesPath, ki.KeyspaceName()) data := jscfg.ToJson(ki.Keyspace) _, err := zkts.zconn.Set(keyspacePath, data, -1) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { // The code should be: // err = topo.ErrNoNode // Temporary code until we have Keyspace object // everywhere: _, err = zkts.zconn.Create(keyspacePath, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNONODE) { // the directory doesn't even exist err = topo.ErrNoNode } return err } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *ki, Status: "updated (had to create Keyspace object)", }) return nil } return err } event.Dispatch(&events.KeyspaceChange{ KeyspaceInfo: *ki, Status: "updated", }) return nil }
func (zkts *Server) UpdateSrvTabletType(cell, keyspace, shard string, tabletType topo.TabletType, addrs *topo.VtnsAddrs) error { path := zkPathForVtName(cell, keyspace, shard, tabletType) data := jscfg.ToJson(addrs) _, err := zk.CreateRecursive(zkts.zconn, path, data, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { // Node already exists - just stomp away. Multiple writers shouldn't be here. // We use RetryChange here because it won't update the node unnecessarily. f := func(oldValue string, oldStat zk.Stat) (string, error) { return data, nil } err = zkts.zconn.RetryChange(path, 0, zookeeper.WorldACL(zookeeper.PERM_ALL), f) } } return err }
func (s *S) TestCloseReleasesWatches(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) _, err := conn.Create("/test", "one", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) _, _, watch, err := conn.GetW("/test") c.Assert(err, IsNil) c.Assert(zk.CountPendingWatches(), Equals, 2) conn.Close() c.Assert(zk.CountPendingWatches(), Equals, 0) select { case _, ok := <-watch: c.Assert(ok, Equals, false) case <-time.After(3e9): c.Fatal("Watch didn't fire") } }
// CreateShard is part of the topo.Server interface func (zkts *Server) CreateShard(ctx context.Context, keyspace, shard string, value *pb.Shard) error { shardPath := path.Join(globalKeyspacesPath, keyspace, "shards", shard) pathList := []string{ shardPath, path.Join(shardPath, "action"), path.Join(shardPath, "actionlog"), } alreadyExists := false for i, zkPath := range pathList { c := "" if i == 0 { c = jscfg.ToJSON(value) } _, err := zk.CreateRecursive(zkts.zconn, zkPath, c, 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { if zookeeper.IsError(err, zookeeper.ZNODEEXISTS) { alreadyExists = true } else { return fmt.Errorf("error creating shard: %v %v", zkPath, err) } } } if alreadyExists { return topo.ErrNodeExists } event.Dispatch(&events.ShardChange{ ShardInfo: *topo.NewShardInfo(keyspace, shard, value, -1), Status: "created", }) return nil }
func (s *S) TestExistsAndWatch(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) stat, watch, err := conn.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Check(zk.CountPendingWatches(), Equals, 2) select { case <-watch: c.Fatal("Watch fired") default: } _, err = conn.Create("/test", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, zk.EVENT_CREATED) c.Assert(event.Path, Equals, "/test") c.Check(zk.CountPendingWatches(), Equals, 1) stat, watch, err = conn.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, NotNil) c.Assert(stat.NumChildren(), Equals, 0) c.Check(zk.CountPendingWatches(), Equals, 2) }