Browse Source

came up with nifty new rr strategy, but breaks test...

Dan Frank 13 years ago
parent
commit
173584a27a
1 changed files with 28 additions and 25 deletions
  1. 28 25
      hostpool.go

+ 28 - 25
hostpool.go

@@ -48,7 +48,7 @@ type standardHostPool struct {
 	hosts             map[string]HostEntry
 	initialRetryDelay time.Duration
 	maxRetryInterval  time.Duration
-	nextHostIndex     int
+	rrResults         chan string
 }
 
 // --- Value Calculators -----------------
@@ -75,6 +75,8 @@ func New(hosts []string) HostPool {
 		e := newHostEntry(h, p.initialRetryDelay, p.maxRetryInterval)
 		p.hosts[h] = e
 	}
+	p.rrResults = make(chan string)
+	go p.serveRoundRobin()
 	return p
 }
 
@@ -130,32 +132,34 @@ func (p *epsilonGreedyHostPool) Get() HostPoolResponse {
 }
 
 func (p *standardHostPool) getRoundRobin() string {
-	// TODO - will want to replace this with something that runs in a 
-	// goroutine and receives requests on a channel.
-	// The state being protected in that case is really just the currentIdx
-
-	// Question - should I just skip the goroutine shit and select randomly?
-	// Maybe
-	now := time.Now()
-	hostCount := len(p.hosts)
-	for i := range p.hostList() {
-		// iterate via sequenece from where we last iterated
-		currentIndex := (i + p.nextHostIndex) % hostCount
-
-		h := p.hostList()[currentIndex]
-		if h.canTryHost(now) {
-			if h.IsDead() {
-				h.willRetryHost()
+	return <-p.rrResults
+}
+
+func (p *standardHostPool) serveRoundRobin() {
+	nextHostIndex := 0
+	getHostToServe := func() string {
+		hostCount := len(p.hosts)
+		for i := range p.hostList() {
+			// iterate via sequenece from where we last iterated
+			currentIndex := (i + nextHostIndex) % hostCount
+
+			h := p.hostList()[currentIndex]
+			if h.canTryHost(time.Now()) {
+				if h.IsDead() {
+					h.willRetryHost()
+				}
+				nextHostIndex = currentIndex + 1
+				return h.Host()
 			}
-			p.nextHostIndex = currentIndex + 1
-			return h.Host()
 		}
+		// all hosts are down. re-add them
+		p.ResetAll()
+		nextHostIndex = 0
+		return p.hostList()[0].Host()
+	}
+	for {
+		p.rrResults <- getHostToServe()
 	}
-
-	// all hosts are down. re-add them
-	p.ResetAll()
-	p.nextHostIndex = 0
-	return p.hostList()[0].Host()
 }
 
 func (p *standardHostPool) ResetAll() {
@@ -205,7 +209,6 @@ func (p *standardHostPool) lookupHost(hostname string) HostEntry {
 func (p *standardHostPool) hostList() []HostEntry {
 	// This returns a sorted list of HostEntry's. We ought
 	// to do some optimization so that this isn't computed every time
-	// TODO can totally use Hosts above to accomplish this
 	keys := make([]string, 0, len(p.hosts))
 	vals := make([]HostEntry, 0, len(p.hosts))
 	for hostName := range p.hosts {