From 553ea9e423e87ca82740c7989a63c782ba19265c Mon Sep 17 00:00:00 2001
From: cvictory <shenglicao2@gmail.com>
Date: Fri, 6 Nov 2020 11:36:18 +0800
Subject: [PATCH] Fix : when there is no invoker is available for network
 reason, it is the same as "No Provider Available."

---
 cluster/cluster_impl/base_cluster_invoker.go     |  8 ++++++++
 cluster/cluster_impl/failover_cluster_invoker.go | 12 ++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/cluster/cluster_impl/base_cluster_invoker.go b/cluster/cluster_impl/base_cluster_invoker.go
index d3552c947..0ac851f72 100644
--- a/cluster/cluster_impl/base_cluster_invoker.go
+++ b/cluster/cluster_impl/base_cluster_invoker.go
@@ -31,6 +31,7 @@ import (
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/common/extension"
+	"github.com/apache/dubbo-go/common/logger"
 	"github.com/apache/dubbo-go/protocol"
 )
 
@@ -119,6 +120,10 @@ func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation p
 }
 
 func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker {
+	if len(invokers) == 0 {
+		logger.Errorf("the invokers of %s is nil. ", invocation.Invoker().GetUrl().ServiceKey())
+		return nil
+	}
 	if len(invokers) == 1 {
 		return invokers[0]
 	}
@@ -133,6 +138,8 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc
 
 		for _, invoker := range invokers {
 			if !invoker.IsAvailable() {
+				logger.Infof("the invoker of %s is not available, maybe some network error happened or the server is shutdown.",
+					invoker.GetUrl().Ip)
 				continue
 			}
 
@@ -144,6 +151,7 @@ func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invoc
 		if len(reslectInvokers) > 0 {
 			selectedInvoker = lb.Select(reslectInvokers, invocation)
 		} else {
+			logger.Errorf("all %d invokers is unavailable for %s.", len(invokers), selectedInvoker.GetUrl().String())
 			return nil
 		}
 	}
diff --git a/cluster/cluster_impl/failover_cluster_invoker.go b/cluster/cluster_impl/failover_cluster_invoker.go
index 9d19152c1..ca490e7f8 100644
--- a/cluster/cluster_impl/failover_cluster_invoker.go
+++ b/cluster/cluster_impl/failover_cluster_invoker.go
@@ -51,6 +51,7 @@ func (invoker *failoverClusterInvoker) Invoke(ctx context.Context, invocation pr
 		result    protocol.Result
 		invoked   []protocol.Invoker
 		providers []string
+		ivk       protocol.Invoker
 	)
 
 	invokers := invoker.directory.List(invocation)
@@ -75,7 +76,7 @@ func (invoker *failoverClusterInvoker) Invoke(ctx context.Context, invocation pr
 				return &protocol.RPCResult{Err: err}
 			}
 		}
-		ivk := invoker.doSelect(loadBalance, invocation, invokers, invoked)
+		ivk = invoker.doSelect(loadBalance, invocation, invokers, invoked)
 		if ivk == nil {
 			continue
 		}
@@ -88,10 +89,17 @@ func (invoker *failoverClusterInvoker) Invoke(ctx context.Context, invocation pr
 		}
 		return result
 	}
-
 	ip := common.GetLocalIp()
 	invokerSvc := invoker.GetUrl().Service()
 	invokerUrl := invoker.directory.GetUrl()
+	if ivk == nil {
+		logger.Errorf("Failed to invoke the method %s of the service %s .No provider is available.", methodName, invokerSvc)
+		return &protocol.RPCResult{
+			Err: perrors.Errorf("Failed to invoke the method %s of the service %s .No provider is available because can't connect server.",
+				methodName, invokerSvc),
+		}
+	}
+
 	return &protocol.RPCResult{
 		Err: perrors.Wrap(result.Error(), fmt.Sprintf("Failed to invoke the method %v in the service %v. "+
 			"Tried %v times of the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. "+
-- 
GitLab