|
|
@ -42,7 +42,7 @@ const ( |
|
|
|
|
|
|
|
|
|
|
|
// To abstract a node over network.
|
|
|
|
// To abstract a node over network.
|
|
|
|
type lockRESTServer struct { |
|
|
|
type lockRESTServer struct { |
|
|
|
ll localLocker |
|
|
|
ll *localLocker |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (l *lockRESTServer) writeErrorResponse(w http.ResponseWriter, err error) { |
|
|
|
func (l *lockRESTServer) writeErrorResponse(w http.ResponseWriter, err error) { |
|
|
@ -62,6 +62,7 @@ func (l *lockRESTServer) IsValid(w http.ResponseWriter, r *http.Request) bool { |
|
|
|
func getLockArgs(r *http.Request) dsync.LockArgs { |
|
|
|
func getLockArgs(r *http.Request) dsync.LockArgs { |
|
|
|
return dsync.LockArgs{ |
|
|
|
return dsync.LockArgs{ |
|
|
|
UID: r.URL.Query().Get(lockRESTUID), |
|
|
|
UID: r.URL.Query().Get(lockRESTUID), |
|
|
|
|
|
|
|
Source: r.URL.Query().Get(lockRESTSource), |
|
|
|
Resource: r.URL.Query().Get(lockRESTResource), |
|
|
|
Resource: r.URL.Query().Get(lockRESTResource), |
|
|
|
ServerAddr: r.URL.Query().Get(lockRESTServerAddr), |
|
|
|
ServerAddr: r.URL.Query().Get(lockRESTServerAddr), |
|
|
|
ServiceEndpoint: r.URL.Query().Get(lockRESTServerEndpoint), |
|
|
|
ServiceEndpoint: r.URL.Query().Get(lockRESTServerEndpoint), |
|
|
@ -75,7 +76,11 @@ func (l *lockRESTServer) LockHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if _, err := l.ll.Lock(getLockArgs(r)); err != nil { |
|
|
|
success, err := l.ll.Lock(getLockArgs(r)) |
|
|
|
|
|
|
|
if err == nil && !success { |
|
|
|
|
|
|
|
err = errLockConflict |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -88,7 +93,10 @@ func (l *lockRESTServer) UnlockHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if _, err := l.ll.Unlock(getLockArgs(r)); err != nil { |
|
|
|
_, err := l.ll.Unlock(getLockArgs(r)) |
|
|
|
|
|
|
|
// Ignore the Unlock() "reply" return value because if err == nil, "reply" is always true
|
|
|
|
|
|
|
|
// Consequently, if err != nil, reply is always false
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -101,7 +109,11 @@ func (l *lockRESTServer) RLockHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if _, err := l.ll.RLock(getLockArgs(r)); err != nil { |
|
|
|
success, err := l.ll.RLock(getLockArgs(r)) |
|
|
|
|
|
|
|
if err == nil && !success { |
|
|
|
|
|
|
|
err = errLockConflict |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -114,7 +126,10 @@ func (l *lockRESTServer) RUnlockHandler(w http.ResponseWriter, r *http.Request) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if _, err := l.ll.RUnlock(getLockArgs(r)); err != nil { |
|
|
|
// Ignore the RUnlock() "reply" return value because if err == nil, "reply" is always true.
|
|
|
|
|
|
|
|
// Consequently, if err != nil, reply is always false
|
|
|
|
|
|
|
|
_, err := l.ll.RUnlock(getLockArgs(r)) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
@ -127,6 +142,8 @@ func (l *lockRESTServer) ForceUnlockHandler(w http.ResponseWriter, r *http.Reque |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ignore the ForceUnlock() "reply" return value because if err == nil, "reply" is always true
|
|
|
|
|
|
|
|
// Consequently, if err != nil, reply is always false
|
|
|
|
if _, err := l.ll.ForceUnlock(getLockArgs(r)); err != nil { |
|
|
|
if _, err := l.ll.ForceUnlock(getLockArgs(r)); err != nil { |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
l.writeErrorResponse(w, err) |
|
|
|
return |
|
|
|
return |
|
|
@ -142,7 +159,6 @@ func (l *lockRESTServer) ExpiredHandler(w http.ResponseWriter, r *http.Request) |
|
|
|
|
|
|
|
|
|
|
|
lockArgs := getLockArgs(r) |
|
|
|
lockArgs := getLockArgs(r) |
|
|
|
|
|
|
|
|
|
|
|
success := true |
|
|
|
|
|
|
|
l.ll.mutex.Lock() |
|
|
|
l.ll.mutex.Lock() |
|
|
|
defer l.ll.mutex.Unlock() |
|
|
|
defer l.ll.mutex.Unlock() |
|
|
|
// Lock found, proceed to verify if belongs to given uid.
|
|
|
|
// Lock found, proceed to verify if belongs to given uid.
|
|
|
@ -150,15 +166,11 @@ func (l *lockRESTServer) ExpiredHandler(w http.ResponseWriter, r *http.Request) |
|
|
|
// Check whether uid is still active
|
|
|
|
// Check whether uid is still active
|
|
|
|
for _, entry := range lri { |
|
|
|
for _, entry := range lri { |
|
|
|
if entry.UID == lockArgs.UID { |
|
|
|
if entry.UID == lockArgs.UID { |
|
|
|
success = false // When uid found, lock is still active so return not expired.
|
|
|
|
l.writeErrorResponse(w, errLockNotExpired) |
|
|
|
break |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if !success { |
|
|
|
|
|
|
|
l.writeErrorResponse(w, errors.New("lock already expired")) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// lockMaintenance loops over locks that have been active for some time and checks back
|
|
|
|
// lockMaintenance loops over locks that have been active for some time and checks back
|
|
|
@ -189,11 +201,15 @@ func (l *lockRESTServer) lockMaintenance(interval time.Duration) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Call back to original server verify whether the lock is still active (based on name & uid)
|
|
|
|
// Call back to original server verify whether the lock is still active (based on name & uid)
|
|
|
|
expired, _ := c.Expired(dsync.LockArgs{ |
|
|
|
expired, err := c.Expired(dsync.LockArgs{ |
|
|
|
UID: nlrip.lri.UID, |
|
|
|
UID: nlrip.lri.UID, |
|
|
|
Resource: nlrip.name, |
|
|
|
Resource: nlrip.name, |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// For successful response, verify if lock was indeed active or stale.
|
|
|
|
// For successful response, verify if lock was indeed active or stale.
|
|
|
|
if expired { |
|
|
|
if expired { |
|
|
|
// The lock is no longer active at server that originated
|
|
|
|
// The lock is no longer active at server that originated
|
|
|
|