Update vendorized version of dsync that relaxes read quorum to N/2 (#2874)

master
Frank 8 years ago committed by Harshavardhana
parent 97f4989945
commit e53a9f6cab
  1. 17
      vendor/github.com/minio/dsync/drwmutex.go
  2. 6
      vendor/github.com/minio/dsync/dsync.go
  3. 6
      vendor/vendor.json

@ -211,7 +211,8 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool {
(*locks)[grant.index] = grant.lockUid (*locks)[grant.index] = grant.lockUid
} else { } else {
locksFailed++ locksFailed++
if locksFailed > dnodeCount-dquorum { if !isReadLock && locksFailed > dnodeCount-dquorum ||
isReadLock && locksFailed > dnodeCount-dquorumReads {
// We know that we are not going to get the lock anymore, so exit out // We know that we are not going to get the lock anymore, so exit out
// and release any locks that did get acquired // and release any locks that did get acquired
done = true done = true
@ -223,7 +224,7 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool {
done = true done = true
// timeout happened, maybe one of the nodes is slow, count // timeout happened, maybe one of the nodes is slow, count
// number of locks to check whether we have quorum or not // number of locks to check whether we have quorum or not
if !quorumMet(locks) { if !quorumMet(locks, isReadLock) {
releaseAll(clnts, locks, lockName, isReadLock) releaseAll(clnts, locks, lockName, isReadLock)
} }
} }
@ -234,7 +235,7 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool {
} }
// Count locks in order to determine whterh we have quorum or not // Count locks in order to determine whterh we have quorum or not
quorum = quorumMet(locks) quorum = quorumMet(locks, isReadLock)
// Signal that we have the quorum // Signal that we have the quorum
wg.Done() wg.Done()
@ -263,8 +264,8 @@ func lock(clnts []RPC, locks *[]string, lockName string, isReadLock bool) bool {
return quorum return quorum
} }
// quorumMet determines whether we have acquired n/2+1 underlying locks or not // quorumMet determines whether we have acquired the required quorum of underlying locks or not
func quorumMet(locks *[]string) bool { func quorumMet(locks *[]string, isReadLock bool) bool {
count := 0 count := 0
for _, uid := range *locks { for _, uid := range *locks {
@ -273,7 +274,11 @@ func quorumMet(locks *[]string) bool {
} }
} }
return count >= dquorum if isReadLock {
return count >= dquorumReads
} else {
return count >= dquorum
}
} }
// releaseAll releases all locks that are marked as locked // releaseAll releases all locks that are marked as locked

@ -34,6 +34,8 @@ var ownNode int
// Simple majority based quorum, set to dNodeCount/2+1 // Simple majority based quorum, set to dNodeCount/2+1
var dquorum int var dquorum int
// Simple quorum for read operations, set to dNodeCount/2
var dquorumReads int
// SetNodesWithPath - initializes package-level global state variables such as clnts. // SetNodesWithPath - initializes package-level global state variables such as clnts.
// N B - This function should be called only once inside any program that uses // N B - This function should be called only once inside any program that uses
@ -47,15 +49,17 @@ func SetNodesWithClients(rpcClnts []RPC, rpcOwnNode int) (err error) {
return errors.New("Dsync not designed for less than 4 nodes") return errors.New("Dsync not designed for less than 4 nodes")
} else if len(rpcClnts) > 16 { } else if len(rpcClnts) > 16 {
return errors.New("Dsync not designed for more than 16 nodes") return errors.New("Dsync not designed for more than 16 nodes")
} else if len(rpcClnts)&1 == 1 {
return errors.New("Dsync not designed for an uneven number of nodes")
} }
if rpcOwnNode > len(rpcClnts) { if rpcOwnNode > len(rpcClnts) {
return errors.New("Index for own node is too large") return errors.New("Index for own node is too large")
} }
dnodeCount = len(rpcClnts) dnodeCount = len(rpcClnts)
dquorum = dnodeCount/2 + 1 dquorum = dnodeCount/2 + 1
dquorumReads = dnodeCount/2
// Initialize node name and rpc path for each RPCClient object. // Initialize node name and rpc path for each RPCClient object.
clnts = make([]RPC, dnodeCount) clnts = make([]RPC, dnodeCount)
copy(clnts, rpcClnts) copy(clnts, rpcClnts)

@ -111,10 +111,10 @@
"revisionTime": "2015-11-18T20:00:48-08:00" "revisionTime": "2015-11-18T20:00:48-08:00"
}, },
{ {
"checksumSHA1": "0wc4gxRamjyjVSiZF73KIaCRC6k=", "checksumSHA1": "5DKBTLXf5GY5RkVC9DGP2XFMabc=",
"path": "github.com/minio/dsync", "path": "github.com/minio/dsync",
"revision": "531818cd6458e24e30eec2c67136a8bcb24520af", "revision": "66c2a42bf14fcaad0322e9f06d9ab85dd6dba9b7",
"revisionTime": "2016-09-15T18:37:01Z" "revisionTime": "2016-10-07T07:30:36Z"
}, },
{ {
"path": "github.com/minio/go-homedir", "path": "github.com/minio/go-homedir",

Loading…
Cancel
Save