From 0e7d51e821c136a50421a6b649e1a86c244ebe35 Mon Sep 17 00:00:00 2001
From: zonghaishang <yiji@apache.org>
Date: Wed, 12 Jun 2019 16:35:14 +0800
Subject: [PATCH] fix bug & unit test.

---
 cluster/loadbalance/round_robin.go      | 21 +++++++--------
 cluster/loadbalance/round_robin_test.go | 34 +++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/cluster/loadbalance/round_robin.go b/cluster/loadbalance/round_robin.go
index ec586c40e..a17f7c6c7 100644
--- a/cluster/loadbalance/round_robin.go
+++ b/cluster/loadbalance/round_robin.go
@@ -59,8 +59,8 @@ func (lb *roundRobinLoadBalance) Select(invokers []protocol.Invoker, invocation
 	}
 
 	key := invokers[0].GetUrl().Path + "." + invocation.MethodName()
-	cache, _ := methodWeightMap.LoadOrStore(key, cachedInvokers{})
-	cachedInvokers := cache.(cachedInvokers)
+	cache, _ := methodWeightMap.LoadOrStore(key, &cachedInvokers{})
+	cachedInvokers := cache.(*cachedInvokers)
 
 	clean := false
 	totalWeight := int64(0)
@@ -75,9 +75,9 @@ func (lb *roundRobinLoadBalance) Select(invokers []protocol.Invoker, invocation
 			weight = 0
 		}
 
-		identify := invoker.GetUrl().Key()
-		loaded, found := cachedInvokers.LoadOrStore(identify, weightedRoundRobin{weight: weight})
-		weightRobin := loaded.(weightedRoundRobin)
+		identifier := invoker.GetUrl().Key()
+		loaded, found := cachedInvokers.LoadOrStore(identifier, &weightedRoundRobin{weight: weight})
+		weightRobin := loaded.(*weightedRoundRobin)
 		if !found {
 			clean = true
 		}
@@ -92,7 +92,7 @@ func (lb *roundRobinLoadBalance) Select(invokers []protocol.Invoker, invocation
 		if currentWeight > maxCurrentWeight {
 			maxCurrentWeight = currentWeight
 			selectedInvoker = invoker
-			selectedWeightRobin = weightRobin
+			selectedWeightRobin = *weightRobin
 		}
 		totalWeight += weight
 	}
@@ -107,12 +107,13 @@ func (lb *roundRobinLoadBalance) Select(invokers []protocol.Invoker, invocation
 	return invokers[0]
 }
 
-func cleanIfRequired(clean bool, invokers cachedInvokers, now *time.Time) {
-	if atomic.LoadInt32(&state) < UPDATING && clean && atomic.CompareAndSwapInt32(&state, COMPLETE, UPDATING) {
+func cleanIfRequired(clean bool, invokers *cachedInvokers, now *time.Time) {
+	if clean && atomic.CompareAndSwapInt32(&state, COMPLETE, UPDATING) {
 		defer atomic.CompareAndSwapInt32(&state, UPDATING, COMPLETE)
 		invokers.Range(func(identify, robin interface{}) bool {
-			weightedRoundRobin := robin.(weightedRoundRobin)
-			if now.Sub(*weightedRoundRobin.lastUpdate).Nanoseconds() > recyclePeriod {
+			weightedRoundRobin := robin.(*weightedRoundRobin)
+			elapsed := now.Sub(*weightedRoundRobin.lastUpdate).Nanoseconds()
+			if elapsed > recyclePeriod {
 				invokers.Delete(identify)
 			}
 			return true
diff --git a/cluster/loadbalance/round_robin_test.go b/cluster/loadbalance/round_robin_test.go
index d5fb84e3d..fc07a61bd 100644
--- a/cluster/loadbalance/round_robin_test.go
+++ b/cluster/loadbalance/round_robin_test.go
@@ -1 +1,35 @@
 package loadbalance
+
+import (
+	"context"
+	"fmt"
+	"testing"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+import (
+	"github.com/dubbo/go-for-apache-dubbo/common"
+	"github.com/dubbo/go-for-apache-dubbo/protocol"
+	"github.com/dubbo/go-for-apache-dubbo/protocol/invocation"
+)
+
+func TestRoundRobinSelect(t *testing.T) {
+	loadBalance := NewRoundRobinLoadBalance()
+
+	var invokers []protocol.Invoker
+
+	url, _ := common.NewURL(context.TODO(), "dubbo://192.168.1.0:20000/org.apache.demo.HelloService")
+	invokers = append(invokers, protocol.NewBaseInvoker(url))
+	i := loadBalance.Select(invokers, &invocation.RPCInvocation{})
+	assert.True(t, i.GetUrl().URLEqual(url))
+
+	for i := 1; i < 10; i++ {
+		url, _ := common.NewURL(context.TODO(), fmt.Sprintf("dubbo://192.168.1.%v:20000/org.apache.demo.HelloService", i))
+		invokers = append(invokers, protocol.NewBaseInvoker(url))
+	}
+	loadBalance.Select(invokers, &invocation.RPCInvocation{})
+
+}
-- 
GitLab