github.com/lazyledger/lazyledger-core@v0.35.0-dev.0.20210613111200-4c651f053571/privval/signer_dialer_endpoint.go (about)

     1  package privval
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/lazyledger/lazyledger-core/libs/log"
     7  	"github.com/lazyledger/lazyledger-core/libs/service"
     8  )
     9  
    10  const (
    11  	defaultMaxDialRetries        = 10
    12  	defaultRetryWaitMilliseconds = 100
    13  )
    14  
    15  // SignerServiceEndpointOption sets an optional parameter on the SignerDialerEndpoint.
    16  type SignerServiceEndpointOption func(*SignerDialerEndpoint)
    17  
    18  // SignerDialerEndpointTimeoutReadWrite sets the read and write timeout for
    19  // connections from client processes.
    20  func SignerDialerEndpointTimeoutReadWrite(timeout time.Duration) SignerServiceEndpointOption {
    21  	return func(ss *SignerDialerEndpoint) { ss.timeoutReadWrite = timeout }
    22  }
    23  
    24  // SignerDialerEndpointConnRetries sets the amount of attempted retries to
    25  // acceptNewConnection.
    26  func SignerDialerEndpointConnRetries(retries int) SignerServiceEndpointOption {
    27  	return func(ss *SignerDialerEndpoint) { ss.maxConnRetries = retries }
    28  }
    29  
    30  // SignerDialerEndpointRetryWaitInterval sets the retry wait interval to a
    31  // custom value.
    32  func SignerDialerEndpointRetryWaitInterval(interval time.Duration) SignerServiceEndpointOption {
    33  	return func(ss *SignerDialerEndpoint) { ss.retryWait = interval }
    34  }
    35  
    36  // SignerDialerEndpoint dials using its dialer and responds to any signature
    37  // requests using its privVal.
    38  type SignerDialerEndpoint struct {
    39  	signerEndpoint
    40  
    41  	dialer SocketDialer
    42  
    43  	retryWait      time.Duration
    44  	maxConnRetries int
    45  }
    46  
    47  // NewSignerDialerEndpoint returns a SignerDialerEndpoint that will dial using the given
    48  // dialer and respond to any signature requests over the connection
    49  // using the given privVal.
    50  func NewSignerDialerEndpoint(
    51  	logger log.Logger,
    52  	dialer SocketDialer,
    53  	options ...SignerServiceEndpointOption,
    54  ) *SignerDialerEndpoint {
    55  
    56  	sd := &SignerDialerEndpoint{
    57  		dialer:         dialer,
    58  		retryWait:      defaultRetryWaitMilliseconds * time.Millisecond,
    59  		maxConnRetries: defaultMaxDialRetries,
    60  	}
    61  
    62  	sd.BaseService = *service.NewBaseService(logger, "SignerDialerEndpoint", sd)
    63  	sd.signerEndpoint.timeoutReadWrite = defaultTimeoutReadWriteSeconds * time.Second
    64  
    65  	for _, optionFunc := range options {
    66  		optionFunc(sd)
    67  	}
    68  
    69  	return sd
    70  }
    71  
    72  func (sd *SignerDialerEndpoint) ensureConnection() error {
    73  	if sd.IsConnected() {
    74  		return nil
    75  	}
    76  
    77  	retries := 0
    78  	for retries < sd.maxConnRetries {
    79  		conn, err := sd.dialer()
    80  
    81  		if err != nil {
    82  			retries++
    83  			sd.Logger.Debug("SignerDialer: Reconnection failed", "retries", retries, "max", sd.maxConnRetries, "err", err)
    84  			// Wait between retries
    85  			time.Sleep(sd.retryWait)
    86  		} else {
    87  			sd.SetConnection(conn)
    88  			sd.Logger.Debug("SignerDialer: Connection Ready")
    89  			return nil
    90  		}
    91  	}
    92  
    93  	sd.Logger.Debug("SignerDialer: Max retries exceeded", "retries", retries, "max", sd.maxConnRetries)
    94  
    95  	return ErrNoConnection
    96  }