github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/network.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apiserver
     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(); ; {
    45  			a.Next()
    46  			err := networkOp()
    47  			if !a.HasNext() || err == nil {
    48  				return errors.Trace(err)
    49  			}
    50  			if networkErr, ok := errors.Cause(err).(net.Error); !ok || !networkErr.Temporary() {
    51  				return errors.Trace(err)
    52  			}
    53  			logger.Debugf("%q error, will retry: %v", description, err)
    54  		}
    55  	}
    56  }