-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
81 lines (67 loc) · 1.34 KB
/
main.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
71
72
73
74
75
76
77
78
79
80
81
package connection
import (
"errors"
"net/http/httputil"
"sync"
"github.com/CoderCookE/goaround/internal/stats"
)
type Message struct {
Health bool
Backend string
Proxy *httputil.ReverseProxy
Ack *sync.WaitGroup
Shutdown bool
}
type Connection struct {
healthy bool
Shut bool
Messages chan Message
Backend string
sync.RWMutex
proxy *httputil.ReverseProxy
}
func NewConnection(proxy *httputil.ReverseProxy, backend string, startup *sync.WaitGroup) *Connection {
conn := &Connection{
Backend: backend,
Messages: make(chan Message),
proxy: proxy,
}
go conn.healthCheck()
startup.Done()
return conn
}
func (c *Connection) Get() (*httputil.ReverseProxy, error) {
c.Lock()
defer c.Unlock()
health := c.healthy
if health && !c.Shut {
return c.proxy, nil
}
return nil, errors.New("Unhealthy Node")
}
func (c *Connection) healthCheck() {
for msg := range c.Messages {
c.Lock()
if msg.Shutdown {
c.Shutdown()
c.Unlock()
return
} else {
backend := msg.Backend
c.healthy = msg.Health
proxy := msg.Proxy
if proxy != nil && c.Backend != backend {
c.Backend = backend
c.proxy = proxy
}
}
msg.Ack.Done()
c.Unlock()
}
}
func (c *Connection) Shutdown() {
c.healthy = false
c.Shut = true
close(c.Messages)
stats.AvailableConnectionsGauge.WithLabelValues("available").Sub(1)
}