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 }