github.com/Cloud-Foundations/Dominator@v0.3.4/lib/srpc/retryclient/impl.go (about)

     1  package retryclient
     2  
     3  import (
     4  	"net"
     5  	"time"
     6  
     7  	"github.com/Cloud-Foundations/Dominator/lib/retry"
     8  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
     9  )
    10  
    11  const checkDelay = time.Second
    12  
    13  func dialHTTP(params Params) (*RetryClient, error) {
    14  	if params.Dialer == nil {
    15  		params.Dialer = &net.Dialer{}
    16  	}
    17  	client := &RetryClient{params: params}
    18  	if err := client.dial(); err != nil {
    19  		return nil, err
    20  	}
    21  	return client, nil
    22  }
    23  
    24  func (client *RetryClient) call(serviceMethod string) (*srpc.Conn, error) {
    25  	if err := client.maybePing(); err != nil {
    26  		return nil, err
    27  	}
    28  	if conn, err := client.client.Call(serviceMethod); err != nil {
    29  		return nil, err
    30  	} else {
    31  		client.lastGoodTime = time.Now()
    32  		return conn, nil
    33  	}
    34  }
    35  
    36  func (client *RetryClient) close() error {
    37  	if err := client.client.Close(); err != nil {
    38  		return err
    39  	}
    40  	client.client = nil
    41  	return nil
    42  }
    43  
    44  func (client *RetryClient) dial() error {
    45  	return retry.Retry(func() bool {
    46  		if err := client.dialOnce(); err == nil {
    47  			return true
    48  		}
    49  		return false
    50  	}, client.params.Params)
    51  }
    52  
    53  func (client *RetryClient) dialOnce() error {
    54  	if client.client != nil {
    55  		client.client.Close()
    56  		client.client = nil
    57  	}
    58  	rawClient, err := srpc.DialTlsHTTPWithDialer(client.params.Network,
    59  		client.params.Address, client.params.TlsConfig, client.params.Dialer)
    60  	if err != nil {
    61  		return err
    62  	}
    63  	client.lastGoodTime = time.Now()
    64  	if client.params.KeepAlive {
    65  		if err := rawClient.SetKeepAlive(client.params.KeepAlive); err != nil {
    66  			rawClient.Close()
    67  			return err
    68  		}
    69  	}
    70  	if client.params.KeepAlivePeriod > 0 {
    71  		err := rawClient.SetKeepAlivePeriod(client.params.KeepAlivePeriod)
    72  		if err != nil {
    73  			rawClient.Close()
    74  			return err
    75  		}
    76  	}
    77  	client.client = rawClient
    78  	return nil
    79  }
    80  
    81  func (client *RetryClient) maybePing() error {
    82  	if time.Since(client.lastGoodTime) < checkDelay {
    83  		return nil
    84  	}
    85  	return client.Ping()
    86  }
    87  
    88  func (client *RetryClient) ping() error {
    89  	if client.client.Ping() == nil {
    90  		client.lastGoodTime = time.Now()
    91  		return nil
    92  	}
    93  	return client.dial()
    94  }
    95  
    96  func (client *RetryClient) requestReply(serviceMethod string,
    97  	request interface{}, reply interface{}) error {
    98  	if err := client.maybePing(); err != nil {
    99  		return err
   100  	}
   101  	err := client.client.RequestReply(serviceMethod, request, reply)
   102  	if err != nil {
   103  		return err
   104  	}
   105  	client.lastGoodTime = time.Now()
   106  	return nil
   107  }
   108  
   109  func (client *RetryClient) setKeepAlive(keepAlive bool) error {
   110  	client.params.KeepAlive = keepAlive
   111  	if client == nil {
   112  		return nil
   113  	}
   114  	return client.client.SetKeepAlive(keepAlive)
   115  }
   116  
   117  func (client *RetryClient) setKeepAlivePeriod(d time.Duration) error {
   118  	client.params.KeepAlivePeriod = d
   119  	if client == nil {
   120  		return nil
   121  	}
   122  	return client.client.SetKeepAlivePeriod(d)
   123  }