Use defer to close the channel in case of error

This commit is contained in:
Tuomas Silen 2015-09-11 16:17:23 +03:00
parent f8ec771cec
commit 2652db825a

View file

@ -355,9 +355,10 @@ func (c *EtcdLock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) {
// Get the local lock before interacting with etcd.
c.lock.Lock()
defer c.lock.Unlock()
var err error
// Check if the lock is already held.
if err := c.assertNotHeld(); err != nil {
if err = c.assertNotHeld(); err != nil {
return nil, err
}
@ -384,14 +385,20 @@ func (c *EtcdLock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) {
// Create a channel to signal when we lose the semaphore key.
done := make(chan struct{})
defer func(err *error) {
if *err != nil {
close(done)
}
}(&err)
go c.periodicallyRenewSemaphoreKey(done)
// Loop until the we current semaphore key matches ours.
for semaphoreKey != currentSemaphoreKey {
var err error
var response *etcd.Response
// Start a watch of the entire lock directory, providing the stop channel.
response, err := c.client.Watch(c.semaphoreDirKey, currentEtcdIndex+1, true, nil, boolStopCh)
response, err = c.client.Watch(c.semaphoreDirKey, currentEtcdIndex+1, true, nil, boolStopCh)
if err != nil {
// If the error is not an etcd error, we can assume it's a notification
@ -401,7 +408,6 @@ func (c *EtcdLock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) {
if _, ok := err.(*etcd.EtcdError); !ok {
_, err = c.client.Delete(c.semaphoreKey, false)
}
close(done)
return nil, err
}
@ -409,14 +415,13 @@ func (c *EtcdLock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) {
// this is an error and nothing else needs to be done.
if response.Node.Key == semaphoreKey &&
(response.Action == "delete" || response.Action == "expire") {
close(done)
return nil, EtcdSemaphoreKeyRemovedError
err = EtcdSemaphoreKeyRemovedError
return nil, err
}
// Get the current semaphore key and etcd index.
currentSemaphoreKey, _, currentEtcdIndex, err = c.getSemaphoreKey()
if err != nil {
close(done)
return nil, err
}
}