VOL-1387 : Fixed issue introduced with watch mechanism submission
- Added flag to determine when a revision is watched
- Added flag to determine when a revision is stored
- Refactored confusing method names for Set/GetChildren
- Fixed issue with deletion of devices due to previous submission
Change-Id: I68c46951f9d40d47e4e74854bba449c9fec4a427
diff --git a/db/model/merge.go b/db/model/merge.go
index e40f98b..b230076 100644
--- a/db/model/merge.go
+++ b/db/model/merge.go
@@ -102,9 +102,9 @@
configChanged = true
}
- //newChildren := reflect.ValueOf(dstRev.GetChildren()).Interface().(map[string][]Revision)
+ //newChildren := reflect.ValueOf(dstRev.GetAllChildren()).Interface().(map[string][]Revision)
newChildren := make(map[string][]Revision)
- for entryName, childrenEntry := range dstRev.GetChildren() {
+ for entryName, childrenEntry := range dstRev.GetAllChildren() {
//newRev.Children[entryName] = append(newRev.Children[entryName], childrenEntry...)
newChildren[entryName] = make([]Revision, len(childrenEntry))
copy(newChildren[entryName], childrenEntry)
@@ -113,9 +113,9 @@
childrenFields := ChildrenFields(forkRev.GetData())
for fieldName, field := range childrenFields {
- forkList := forkRev.GetChildren()[fieldName]
- srcList := srcRev.GetChildren()[fieldName]
- dstList := dstRev.GetChildren()[fieldName]
+ forkList := forkRev.GetChildren(fieldName)
+ srcList := srcRev.GetChildren(fieldName)
+ dstList := dstRev.GetChildren(fieldName)
if revisionsAreEqual(dstList, srcList) {
for _, rev := range srcList {
diff --git a/db/model/node.go b/db/model/node.go
index b8daadd..55b0eb7 100644
--- a/db/model/node.go
+++ b/db/model/node.go
@@ -302,8 +302,8 @@
field := names[name]
if field != nil && field.IsContainer {
- children := make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children := make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
if field.Key != "" {
if path != "" {
@@ -341,7 +341,7 @@
}
}
- childRev := rev.GetChildren()[name][0]
+ childRev := rev.GetChildren(name)[0]
childNode := childRev.GetNode()
return childNode.getPath(childRev, path, depth)
}
@@ -409,8 +409,8 @@
}
keyValue := field.KeyFromStr(key)
- children = make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children = make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
idx, childRev := n.findRevByKey(children, field.Key, keyValue)
childNode := childRev.GetNode()
@@ -448,7 +448,7 @@
log.Errorf("cannot index into container with no keys")
}
} else {
- childRev := rev.GetChildren()[name][0]
+ childRev := rev.GetChildren(name)[0]
childNode := childRev.GetNode()
newChildRev := childNode.Update(path, data, strict, txid, makeBranch)
updatedRev := rev.UpdateChildren(name, []Revision{newChildRev}, branch)
@@ -543,8 +543,8 @@
n.GetProxy().InvokeCallbacks(PRE_ADD, false, data)
}
- children = make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children = make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
_, key := GetAttributeValue(data, field.Key, 0)
@@ -582,8 +582,8 @@
}
keyValue := field.KeyFromStr(key)
- children = make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children = make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
idx, childRev := n.findRevByKey(children, field.Key, keyValue)
@@ -592,7 +592,7 @@
children[idx] = newChildRev
- rev = rev.UpdateChildren(name, branch.GetLatest().GetChildren()[name], branch)
+ rev = rev.UpdateChildren(name, branch.GetLatest().GetChildren(name), branch)
rev.Drop(txid, false)
n.makeLatest(branch, rev.GetBranch().GetLatest(), nil)
@@ -649,14 +649,14 @@
path = partition[1]
}
keyValue := field.KeyFromStr(key)
- children = make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children = make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
if path != "" {
idx, childRev := n.findRevByKey(children, field.Key, keyValue)
childNode := childRev.GetNode()
newChildRev := childNode.Remove(path, txid, makeBranch)
children[idx] = newChildRev
- rev := rev.UpdateChildren(name, children, branch)
+ rev.SetChildren(name, children)
branch.GetLatest().Drop(txid, false)
n.makeLatest(branch, rev, nil)
return rev
@@ -671,7 +671,7 @@
}
childRev.Drop(txid, true)
children = append(children[:idx], children[idx+1:]...)
- rev := rev.UpdateChildren(name, children, branch)
+ rev.SetChildren(name, children)
branch.GetLatest().Drop(txid, false)
n.makeLatest(branch, rev, postAnnouncement)
return rev
@@ -812,8 +812,8 @@
}
keyValue := field.KeyFromStr(key)
var children []Revision
- children = make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children = make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
if _, childRev := n.findRevByKey(children, field.Key, keyValue); childRev != nil {
childNode := childRev.GetNode()
return childNode.createProxy(path, fullPath, n, exclusive)
@@ -822,7 +822,7 @@
log.Error("cannot index into container with no keys")
}
} else {
- childRev := rev.GetChildren()[name][0]
+ childRev := rev.GetChildren(name)[0]
childNode := childRev.GetNode()
return childNode.createProxy(path, fullPath, n, exclusive)
}
diff --git a/db/model/non_persisted_revision.go b/db/model/non_persisted_revision.go
index 66e6f74..765bbaf 100644
--- a/db/model/non_persisted_revision.go
+++ b/db/model/non_persisted_revision.go
@@ -72,18 +72,35 @@
return npr.Config
}
-func (npr *NonPersistedRevision) SetChildren(children map[string][]Revision) {
+func (npr *NonPersistedRevision) SetAllChildren(children map[string][]Revision) {
npr.mutex.Lock()
defer npr.mutex.Unlock()
npr.Children = children
}
-func (npr *NonPersistedRevision) GetChildren() map[string][]Revision {
+func (npr *NonPersistedRevision) SetChildren(name string, children []Revision) {
+ npr.mutex.Lock()
+ defer npr.mutex.Unlock()
+ if _, exists := npr.Children[name]; exists {
+ npr.Children[name] = children
+ }
+}
+
+func (npr *NonPersistedRevision) GetAllChildren() map[string][]Revision {
npr.mutex.Lock()
defer npr.mutex.Unlock()
return npr.Children
}
+func (npr *NonPersistedRevision) GetChildren(name string) []Revision {
+ npr.mutex.Lock()
+ defer npr.mutex.Unlock()
+ if _, exists := npr.Children[name]; exists {
+ return npr.Children[name]
+ }
+ return nil
+}
+
func (npr *NonPersistedRevision) SetHash(hash string) {
npr.mutex.Lock()
defer npr.mutex.Unlock()
@@ -188,7 +205,7 @@
for fieldName, field := range ChildrenFields(latestRev.GetData()) {
childDataName, childDataHolder := GetAttributeValue(data, fieldName, 0)
if field.IsContainer {
- for _, rev := range latestRev.GetChildren()[fieldName] {
+ for _, rev := range latestRev.GetChildren(fieldName) {
childData := rev.Get(depth - 1)
foundEntry := false
for i := 0; i < childDataHolder.Len(); i++ {
@@ -204,8 +221,8 @@
}
}
} else {
- if revs := latestRev.GetChildren()[fieldName]; revs != nil && len(revs) > 0 {
- rev := latestRev.GetChildren()[fieldName][0]
+ if revs := latestRev.GetChildren(fieldName); revs != nil && len(revs) > 0 {
+ rev := latestRev.GetChildren(fieldName)[0]
if rev != nil {
childData := rev.Get(depth - 1)
if reflect.TypeOf(childData) == reflect.TypeOf(childDataHolder.Interface()) {
diff --git a/db/model/persisted_revision.go b/db/model/persisted_revision.go
index dd24e7e..84b9569 100644
--- a/db/model/persisted_revision.go
+++ b/db/model/persisted_revision.go
@@ -33,9 +33,11 @@
Revision
Compress bool
- events chan *kvstore.Event `json:"-"`
- kvStore *Backend `json:"-"`
- mutex sync.RWMutex `json:"-"`
+ events chan *kvstore.Event `json:"-"`
+ kvStore *Backend `json:"-"`
+ mutex sync.RWMutex `json:"-"`
+ isStored bool
+ isWatched bool
}
// NewPersistedRevision creates a new instance of a PersistentRevision structure
@@ -83,6 +85,7 @@
} else {
log.Debugw("storing-revision-config",
log.Fields{"hash": pr.GetHash(), "data": pr.GetConfig().Data})
+ pr.isStored = true
}
}
}
@@ -95,6 +98,8 @@
pr.events = pr.kvStore.CreateWatch(key)
+ pr.isWatched = true
+
// Start watching
go pr.startWatching()
}
@@ -176,8 +181,8 @@
if field.Key != "" {
// e.g. /logical_devices/abcde --> path="" name=logical_devices key=abcde
if field.Key != "" {
- children = make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children = make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
_, key := GetAttributeValue(data.Interface(), field.Key, 0)
@@ -208,8 +213,8 @@
}
keyValue := field.KeyFromStr(key)
- children = make([]Revision, len(rev.GetChildren()[name]))
- copy(children, rev.GetChildren()[name])
+ children = make([]Revision, len(rev.GetChildren(name)))
+ copy(children, rev.GetChildren(name))
idx, childRev := rev.GetBranch().Node.findRevByKey(children, field.Key, keyValue)
@@ -217,7 +222,7 @@
children[idx] = newChildRev[0]
- rev := rev.UpdateChildren(name, rev.GetChildren()[name], rev.GetBranch())
+ rev := rev.UpdateChildren(name, rev.GetChildren(name), rev.GetBranch())
rev.GetBranch().Node.makeLatest(rev.GetBranch(), rev, nil)
response = append(response, newChildRev[0])
@@ -284,18 +289,25 @@
pr.mutex.Lock()
defer pr.mutex.Unlock()
if pr.kvStore != nil && txid == "" {
- if includeConfig {
- if err := pr.kvStore.Delete(pr.GetConfig().Hash); err != nil {
- log.Errorw("failed-to-remove-revision-config", log.Fields{"hash": pr.GetConfig().Hash, "error": err.Error()})
+ if pr.isStored {
+ if includeConfig {
+ if err := pr.kvStore.Delete(pr.GetConfig().Hash); err != nil {
+ log.Errorw("failed-to-remove-revision-config", log.Fields{"hash": pr.GetConfig().Hash, "error": err.Error()})
+ }
+ }
+
+ if err := pr.kvStore.Delete(pr.GetHash()); err != nil {
+ log.Errorw("failed-to-remove-revision", log.Fields{"hash": pr.GetHash(), "error": err.Error()})
+ } else {
+ pr.isStored = false
+ }
+
+ if pr.isWatched {
+ pr.kvStore.DeleteWatch(pr.GetHash(), pr.events)
+ pr.isWatched = false
}
}
- if err := pr.kvStore.Delete(pr.GetHash()); err != nil {
- log.Errorw("failed-to-remove-revision", log.Fields{"hash": pr.GetHash(), "error": err.Error()})
- }
-
- pr.kvStore.DeleteWatch(pr.GetConfig().Hash, pr.events)
-
} else {
if includeConfig {
log.Debugw("attempted-to-remove-transacted-revision-config", log.Fields{"hash": pr.GetConfig().Hash, "txid": txid})
diff --git a/db/model/proxy_load_test.go b/db/model/proxy_load_test.go
index b388d97..49443cd 100644
--- a/db/model/proxy_load_test.go
+++ b/db/model/proxy_load_test.go
@@ -227,7 +227,7 @@
// tlog.Debugf("%sbranchIndex: %s", prefix, brIdx)
// traverseBranches(brRev, depth+1)
//}
- for childrenI, children := range revision.GetChildren() {
+ for childrenI, children := range revision.GetAllChildren() {
tlog.Debugf("%schildrenIndex: %s, length: %d", prefix, childrenI, len(children))
for _, subrev := range children {
diff --git a/db/model/revision.go b/db/model/revision.go
index 0a58ccd..51f7a1a 100644
--- a/db/model/revision.go
+++ b/db/model/revision.go
@@ -20,8 +20,10 @@
SetConfig(revision *DataRevision)
GetConfig() *DataRevision
Drop(txid string, includeConfig bool)
- SetChildren(children map[string][]Revision)
- GetChildren() map[string][]Revision
+ SetChildren(name string, children []Revision)
+ GetChildren(name string) []Revision
+ SetAllChildren(children map[string][]Revision)
+ GetAllChildren() map[string][]Revision
SetHash(hash string)
GetHash() string
ClearHash()