Skip to content
This repository has been archived by the owner on Oct 7, 2023. It is now read-only.

Commit

Permalink
Merge pull request #77 from heyitsanthony/fix-root-stat
Browse files Browse the repository at this point in the history
zetcd: fix stat data for root directory
  • Loading branch information
Anthony Romano authored Aug 8, 2017
2 parents de71a64 + 393dde8 commit e4352ce
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 20 deletions.
10 changes: 8 additions & 2 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,20 @@ func TestSync(t *testing.T) {

func TestExists(t *testing.T) {
runTest(t, func(t *testing.T, c *zk.Conn) {
if ok, _, err := c.Exists("/"); err != nil || !ok {
t.Errorf("expected /, got err=%v, ok=%v", err, ok)
}
if _, err := c.Create("/abc", []byte(""), 0, acl); err != nil {
t.Fatal(err)
}
if ok, _, err := c.Exists("/"); err != nil || !ok {
t.Errorf("expected /, got err=%v, ok=%v", err, ok)
}
if ok, _, err := c.Exists("/abc"); err != nil || !ok {
t.Fatalf("expected it to exist %v %v", err, ok)
t.Errorf("expected it to exist %v %v", err, ok)
}
if ok, _, err := c.Exists("/ab"); ok {
t.Fatalf("expected it to not exist %v %v", err, ok)
t.Errorf("expected it to not exist %v %v", err, ok)
}
})
}
Expand Down
20 changes: 18 additions & 2 deletions stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func statGetsRev(p string, rev int64) []etcd.Op {

func statGets(p string) []etcd.Op { return statGetsRev(p, 0) }

func statTxn(txnresp *etcd.TxnResponse) (s Stat) {
func statTxn(p string, txnresp *etcd.TxnResponse) (s Stat, err error) {
ctime := txnresp.Responses[0].GetResponseRange()
mtime := txnresp.Responses[1].GetResponseRange()
node := txnresp.Responses[2].GetResponseRange()
Expand Down Expand Up @@ -64,5 +64,21 @@ func statTxn(txnresp *etcd.TxnResponse) (s Stat) {
s.DataLength = int32(len(node.Kvs[0].Value))
}
s.NumChildren = int32(len(children.Kvs))
return s

if p != "/" {
if s.Ctime == 0 {
return s, ErrNoNode
}
return s, nil
}

// fix ups for special root node

// lie about having the quota dir so stat on "/" xchks OK
s.NumChildren++
// Cversion for root begins at -1, then 0 on first child
if len(cver.Kvs) == 0 {
s.Cversion = -1
}
return s, nil
}
29 changes: 13 additions & 16 deletions zketcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,8 @@ func (z *zkEtcd) GetChildren2(xid Xid, op *GetChildren2Request) ZKResponse {
return mkErr(err)
}

resp.Stat = statTxn(txnresp)
if op.Path != "/" && resp.Stat.Ctime == 0 {
return mkZKErr(xid, ZXid(txnresp.Header.Revision), errNoNode)
if resp.Stat, err = statTxn(op.Path, txnresp); err != nil {
return apiErrToZKErr(xid, ZXid(txnresp.Header.Revision), err)
}

children := txnresp.Responses[5].GetResponseRange()
Expand Down Expand Up @@ -258,7 +257,7 @@ func (z *zkEtcd) Exists(xid Xid, op *ExistsRequest) ZKResponse {
}

exResp := &ExistsResponse{}
exResp.Stat = statTxn(txnresp)
exResp.Stat, err = statTxn(op.Path, txnresp)
zxid := ZXid(txnresp.Header.Revision)
z.s.Wait(exResp.Stat.Czxid, p, EventNodeCreated)

Expand All @@ -279,8 +278,8 @@ func (z *zkEtcd) Exists(xid Xid, op *ExistsRequest) ZKResponse {
z.s.Watch(zxid, xid, p, ev, f)
}

if exResp.Stat.Mtime == 0 {
return mkZKErr(xid, zxid, errNoNode)
if err != nil {
return apiErrToZKErr(xid, zxid, err)
}

glog.V(7).Infof("Exists(%v) = (zxid=%v, resp=%+v)", xid, zxid, *exResp)
Expand All @@ -298,9 +297,8 @@ func (z *zkEtcd) GetData(xid Xid, op *GetDataRequest) ZKResponse {
zxid := ZXid(txnresp.Header.Revision)

datResp := &GetDataResponse{}
datResp.Stat = statTxn(txnresp)
if datResp.Stat.Mtime == 0 {
return mkZKErr(xid, zxid, errNoNode)
if datResp.Stat, err = statTxn(op.Path, txnresp); err != nil {
return apiErrToZKErr(xid, zxid, err)
}

z.s.Wait(datResp.Stat.Mzxid, p, EventNodeDataChanged)
Expand Down Expand Up @@ -362,7 +360,8 @@ func (z *zkEtcd) mkSetDataTxnOp(op *SetDataRequest) opBundle {
glog.Warningf("set data failed (%v)", err)
return mkZKErr(xid, zxid, errSystemError)
}
return mkZKResp(xid, zxid, &SetDataResponse{Stat: statTxn(statResp)})
st, _ := statTxn(op.Path, statResp)
return mkZKResp(xid, zxid, &SetDataResponse{Stat: st})
}

return opBundle{apply, reply}
Expand All @@ -382,9 +381,8 @@ func (z *zkEtcd) GetAcl(xid Xid, op *GetAclRequest) ZKResponse {
zxid := ZXid(txnresp.Header.Revision)
resps := txnresp.Responses
txnresp.Responses = resps[1:]
resp.Stat = statTxn(txnresp)
if resp.Stat.Ctime == 0 {
return mkZKErr(xid, zxid, errNoNode)
if resp.Stat, err = statTxn(op.Path, txnresp); err != nil {
return apiErrToZKErr(xid, zxid, err)
}
resp.Acl = decodeACLs(resps[0].GetResponseRange().Kvs[0].Value)

Expand All @@ -410,9 +408,8 @@ func (z *zkEtcd) GetChildren(xid Xid, op *GetChildrenRequest) ZKResponse {
return mkErr(err)
}

s := statTxn(txnresp)
if op.Path != "/" && s.Ctime == 0 {
return mkZKErr(xid, ZXid(txnresp.Header.Revision), errNoNode)
if _, err := statTxn(op.Path, txnresp); err != nil {
return apiErrToZKErr(xid, ZXid(txnresp.Header.Revision), err)
}

children := txnresp.Responses[5].GetResponseRange()
Expand Down

0 comments on commit e4352ce

Please sign in to comment.