github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/utils/network.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package utils
     5  
     6  import (
     7  	"net"
     8  	"time"
     9  
    10  	"github.com/juju/errors"
    11  	"github.com/juju/utils"
    12  )
    13  
    14  var (
    15  	// The defaults below are best suited to retries associated
    16  	// with disk I/O timeouts, eg database operations.
    17  	// Use the NetworkOperationWithRetries() variant to explicitly
    18  	// use retry values better suited to different scenarios.
    19  
    20  	// DefaultNetworkOperationRetryDelay is the default time
    21  	// to wait between operation retries.
    22  	DefaultNetworkOperationRetryDelay = 30 * time.Second
    23  
    24  	// DefaultNetworkOperationAttempts is the default number
    25  	// of attempts before giving up.
    26  	DefaultNetworkOperationAttempts = 10
    27  )
    28  
    29  // NetworkOperationWithDefaultRetries calls the supplied function and if it returns a
    30  // network error which is temporary, will retry a number of times before giving up.
    31  // A default attempt strategy is used.
    32  func NetworkOperationWitDefaultRetries(networkOp func() error, description string) func() error {
    33  	attempt := utils.AttemptStrategy{
    34  		Delay: DefaultNetworkOperationRetryDelay,
    35  		Min:   DefaultNetworkOperationAttempts,
    36  	}
    37  	return NetworkOperationWithRetries(attempt, networkOp, description)
    38  }
    39  
    40  // NetworkOperationWithRetries calls the supplied function and if it returns a
    41  // network error which is temporary, will retry a number of times before giving up.
    42  func NetworkOperationWithRetries(strategy utils.AttemptStrategy, networkOp func() error, description string) func() error {
    43  	return func() error {
    44  		for a := strategy.Start(); a.Next(); {
    45  			err := networkOp()
    46  			if !a.HasNext() || err == nil {
    47  				return errors.Trace(err)
    48  			}
    49  			if networkErr, ok := errors.Cause(err).(net.Error); !ok || !networkErr.Temporary() {
    50  				return errors.Trace(err)
    51  			}
    52  			logger.Debugf("%q error, will retry: %v", description, err)
    53  		}
    54  		panic("unreachable")
    55  	}
    56  }