-
Notifications
You must be signed in to change notification settings - Fork 9
/
balancer.go
70 lines (58 loc) · 1.46 KB
/
balancer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package slb
import (
"log"
"net/http"
"net/http/httputil"
"github.com/pkg/errors"
)
// Available strategies for the pool.
const (
LeastBusy = "least_busy"
RoundRobin = "round_robin"
)
// Pool is an interface for pools with different
// strategies of distributing work.
type Pool interface {
Dispatch() node
Complete(res *http.Response)
}
// NewPool provides a pool with specified strategy.
func NewPool(strategy string, hosts []string) Pool {
switch strategy {
case LeastBusy:
return newLeastBusy(hosts)
case RoundRobin:
return newRoundRobin(hosts)
default:
panic(errors.Errorf("%v is not a valid strategy", strategy))
}
}
// Balancer is the reverse proxy server that balances requests.
type Balancer struct {
*httputil.ReverseProxy
pool Pool
}
// NewBalancer creates a new balancer to balance requests between hosts
// and uses specified strategy.
func NewBalancer(strategy string, hosts []string) *Balancer {
b := &Balancer{
pool: NewPool(strategy, hosts),
}
b.ReverseProxy = &httputil.ReverseProxy{
Director: b.Director,
ModifyResponse: b.ModifyResponse,
}
return b
}
// Director directs the request to the node that was dispatched by pool.
func (b *Balancer) Director(r *http.Request) {
node := b.pool.Dispatch()
log.Println(b.pool)
r.URL.Scheme = "http"
r.URL.Host = node.host
}
// ModifyResponse tells the pool that the request was handled.
func (b *Balancer) ModifyResponse(res *http.Response) error {
b.pool.Complete(res)
return nil
}