From 042387da8acdf57ad8dba28565e2a5029c8964af Mon Sep 17 00:00:00 2001
From: Ian Luo <ian.luo@gmail.com>
Date: Thu, 22 Oct 2020 17:18:07 +0800
Subject: [PATCH] enhance client's connectivity

---
 cluster/router/healthcheck/default_health_check.go | 4 ++++
 protocol/dubbo/dubbo_invoker.go                    | 4 ++++
 remoting/exchange_client.go                        | 7 +++++++
 remoting/getty/getty_client.go                     | 8 ++++++++
 4 files changed, 23 insertions(+)

diff --git a/cluster/router/healthcheck/default_health_check.go b/cluster/router/healthcheck/default_health_check.go
index c522bdf0f..409408bb9 100644
--- a/cluster/router/healthcheck/default_health_check.go
+++ b/cluster/router/healthcheck/default_health_check.go
@@ -48,6 +48,10 @@ type DefaultHealthChecker struct {
 // IsHealthy evaluates the healthy state on the given Invoker based on the number of successive bad request
 // and the current active request
 func (c *DefaultHealthChecker) IsHealthy(invoker protocol.Invoker) bool {
+	if !invoker.IsAvailable() {
+		return false
+	}
+
 	urlStatus := protocol.GetURLStatus(invoker.GetUrl())
 	if c.isCircuitBreakerTripped(urlStatus) || urlStatus.GetActive() > c.GetOutStandingRequestCountLimit() {
 		logger.Debugf("Invoker [%s] is currently in circuitbreaker tripped state", invoker.GetUrl().Key())
diff --git a/protocol/dubbo/dubbo_invoker.go b/protocol/dubbo/dubbo_invoker.go
index bce33508b..e72ca2829 100644
--- a/protocol/dubbo/dubbo_invoker.go
+++ b/protocol/dubbo/dubbo_invoker.go
@@ -161,6 +161,10 @@ func (di *DubboInvoker) getTimeout(invocation *invocation_impl.RPCInvocation) ti
 	return di.timeout
 }
 
+func (di *DubboInvoker) IsAvailable() bool {
+	return di.client.IsAvailable()
+}
+
 // Destroy destroy dubbo client invoker.
 func (di *DubboInvoker) Destroy() {
 	di.quitOnce.Do(func() {
diff --git a/remoting/exchange_client.go b/remoting/exchange_client.go
index efcfca558..e5f6d7feb 100644
--- a/remoting/exchange_client.go
+++ b/remoting/exchange_client.go
@@ -47,6 +47,8 @@ type Client interface {
 	Close()
 	// send request to server.
 	Request(request *Request, timeout time.Duration, response *PendingResponse) error
+	// check if the client is still available
+	IsAvailable() bool
 }
 
 // This is abstraction level. it is like facade.
@@ -182,6 +184,11 @@ func (client *ExchangeClient) Close() {
 	client.client.Close()
 }
 
+// IsAvailable to check if the underlying network client is available yet.
+func (client *ExchangeClient) IsAvailable() bool {
+	return client.client.IsAvailable()
+}
+
 // handle the response from server
 func (client *ExchangeClient) Handler(response *Response) {
 
diff --git a/remoting/getty/getty_client.go b/remoting/getty/getty_client.go
index 6af3971f5..aa69429fc 100644
--- a/remoting/getty/getty_client.go
+++ b/remoting/getty/getty_client.go
@@ -204,6 +204,14 @@ func (c *Client) Request(request *remoting.Request, timeout time.Duration, respo
 	return perrors.WithStack(err)
 }
 
+func (c *Client) IsAvailable() bool {
+	client, err := c.pool.get()
+	if client == nil || !client.isAvailable() || err != nil {
+		return false
+	}
+	return true
+}
+
 func (c *Client) selectSession(addr string) (*gettyRPCClient, getty.Session, error) {
 	rpcClient, err := c.pool.getGettyRpcClient(addr)
 	if err != nil {
-- 
GitLab