VOL-1775 VOL-1779 VOL-1780 : Fix several issues with overall stability
- Apply changes as reported by golang race utility
- Added version attribute in KV object
- Added context object to db/model api
- Carrying timestamp info through context to help in the
decision making when applying a revision change
- Replaced proxy access control mechanism with etcd reservation mechanism
Change-Id: If3d142a73b1da0d64fa6a819530f297dbfada2d3
diff --git a/db/model/non_persisted_revision.go b/db/model/non_persisted_revision.go
index 297a740..6900c5d 100644
--- a/db/model/non_persisted_revision.go
+++ b/db/model/non_persisted_revision.go
@@ -17,6 +17,7 @@
import (
"bytes"
+ "context"
"crypto/md5"
"fmt"
"github.com/golang/protobuf/proto"
@@ -35,6 +36,16 @@
Cache sync.Map
}
+func (s *revCacheSingleton) Get(path string) (interface{}, bool) {
+ return s.Cache.Load(path)
+}
+func (s *revCacheSingleton) Set(path string, value interface{}) {
+ s.Cache.Store(path, value)
+}
+func (s *revCacheSingleton) Delete(path string) {
+ s.Cache.Delete(path)
+}
+
var revCacheInstance *revCacheSingleton
var revCacheOnce sync.Once
@@ -269,10 +280,17 @@
}
// UpdateData will refresh the data content of the revision
-func (npr *NonPersistedRevision) UpdateData(data interface{}, branch *Branch) Revision {
+func (npr *NonPersistedRevision) UpdateData(ctx context.Context, data interface{}, branch *Branch) Revision {
npr.mutex.Lock()
defer npr.mutex.Unlock()
+ if ctx != nil {
+ if ctxTS, ok := ctx.Value(RequestTimestamp).(int64); ok && npr.lastUpdate.UnixNano() > ctxTS {
+ log.Warnw("data-is-older-than-current", log.Fields{"ctx-ts": ctxTS, "rev-ts": npr.lastUpdate.UnixNano()})
+ return npr
+ }
+ }
+
// Do not update the revision if data is the same
if npr.Config.Data != nil && npr.Config.hashData(npr.Root, data) == npr.Config.Hash {
log.Debugw("stored-data-matches-latest", log.Fields{"stored": npr.Config.Data, "provided": data})
@@ -300,7 +318,7 @@
// UpdateChildren will refresh the list of children with the provided ones
// It will carefully go through the list and ensure that no child is lost
-func (npr *NonPersistedRevision) UpdateChildren(name string, children []Revision, branch *Branch) Revision {
+func (npr *NonPersistedRevision) UpdateChildren(ctx context.Context, name string, children []Revision, branch *Branch) Revision {
npr.mutex.Lock()
defer npr.mutex.Unlock()
@@ -358,7 +376,7 @@
})
// replace entry
- newChild.GetNode().Root = existingChildren[nameIndex].GetNode().Root
+ newChild.GetNode().SetRoot(existingChildren[nameIndex].GetNode().GetRoot())
updatedChildren = append(updatedChildren, newChild)
} else {
log.Debugw("keeping-existing-child", log.Fields{
@@ -461,7 +479,7 @@
return npr.lastUpdate
}
-func (npr *NonPersistedRevision) LoadFromPersistence(path string, txid string, blobs map[string]*kvstore.KVPair) []Revision {
+func (npr *NonPersistedRevision) LoadFromPersistence(ctx context.Context, path string, txid string, blobs map[string]*kvstore.KVPair) []Revision {
// stub... required by interface
return nil
}
@@ -473,3 +491,7 @@
func (npr *NonPersistedRevision) StorageDrop(txid string, includeConfig bool) {
// stub ... required by interface
}
+
+func (npr *NonPersistedRevision) getVersion() int64 {
+ return -1
+}