Skip to content

Commit

Permalink
Avoid concurrently status check + Go modules (#9)
Browse files Browse the repository at this point in the history
* Migrate to go modules

* initial check async + prevent multiple checks on database
  • Loading branch information
Victor authored Mar 27, 2019
1 parent 551d785 commit ae0121d
Show file tree
Hide file tree
Showing 458 changed files with 131 additions and 359,525 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coverage.txt
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ go:
- 1.11
go_import_path: github.com/StudioSol/balancer
install:
- make dependency
- make upgrade
script:
- make test
after_success:
Expand Down
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
dependency:
go get github.com/smartystreets/goconvey/convey
go get gopkg.in/DATA-DOG/go-sqlmock.v1
export GO111MODULE=on

all: deps build
install:
go install
build:
go build
clean:
go clean
deps:
go build -v ./...
upgrade:
go get -u
test:
echo "" > coverage.txt
for d in $(shell go list ./...); do \
Expand Down
22 changes: 8 additions & 14 deletions balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,9 @@ func (b *Balancer) serversUP() Servers {
return serversUP
}

func (b *Balancer) initChecks() {
for i := range b.servers {
b.servers[i].CheckHealth(b.traceOn, b.logger)
}
}

func (b *Balancer) startChecks() {
concurrence.Every(time.Duration(b.config.CheckInterval)*time.Second, func(time.Time) bool {
b.servers.eachASYNC(func(index int, server *Server) {
server.CheckHealth(b.traceOn, b.logger)
})
return true
func (b *Balancer) check() {
b.servers.eachASYNC(func(index int, server *Server) {
server.CheckHealth(b.traceOn, b.logger)
})
}

Expand Down Expand Up @@ -136,9 +127,12 @@ func New(config *Config) *Balancer {
traceOn: config.TraceOn,
}

balancer.initChecks()
balancer.check()
if config.StartCheck {
balancer.startChecks()
concurrence.Every(time.Duration(config.CheckInterval)*time.Second, func(time.Time) bool {
balancer.check()
return true
})
}

return balancer
Expand Down
22 changes: 22 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module github.com/StudioSol/balancer

require (
github.com/DATA-DOG/go-sqlmock v1.3.3
github.com/go-gorp/gorp v2.0.0+incompatible
github.com/go-sql-driver/mysql v1.4.1
github.com/golang/protobuf v1.3.1
github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9 // indirect
github.com/lib/pq v1.0.0
github.com/mattn/go-sqlite3 v1.10.0
github.com/onsi/ginkgo v1.8.0
github.com/onsi/gomega v1.5.0
github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac // indirect
github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff
github.com/ziutek/mymysql v0.0.0-20160623123511-8787d5581eb6
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c // indirect
golang.org/x/net v0.0.0-20190327091125-710a502c58a2 // indirect
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127
gopkg.in/yaml.v2 v2.2.2
)
52 changes: 52 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-gorp/gorp v0.0.0-20160222073440-6a3c8a87d045 h1:3GTkiN2MUTTkojMsGMOhq1epHEorIAPSFOcaFOGnLjo=
github.com/go-gorp/gorp v0.0.0-20160222073440-6a3c8a87d045/go.mod h1:7IfkAQnO7jfT/9IQ3R9wL1dFhukN6aQxzKTHnkxzA/E=
github.com/go-gorp/gorp v2.0.0+incompatible h1:dIQPsBtl6/H1MjVseWuWPXa7ET4p6Dve4j3Hg+UjqYw=
github.com/go-gorp/gorp v2.0.0+incompatible/go.mod h1:7IfkAQnO7jfT/9IQ3R9wL1dFhukN6aQxzKTHnkxzA/E=
github.com/go-sql-driver/mysql v0.0.0-20160602001021-3654d25ec346/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v0.0.0-20160712193813-874264fbbb43/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/lib/pq v0.0.0-20160623220637-4dd446efc176/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v0.0.0-20160514122348-38ee283dabf1/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/onsi/ginkgo v0.0.0-20160713133600-01a0bc330e32/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20160713044445-9574b2d94c03/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac h1:wbW+Bybf9pXxnCFAOWZTqkRjAc7rAIwo2e1ArUhiHxg=
github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff h1:86HlEv0yBCry9syNuylzqznKXDK11p6D0DT596yNMys=
github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs=
github.com/ziutek/mymysql v0.0.0-20160623123511-8787d5581eb6/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20160712235641-b518c298ac9d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20160301204022-a83829b6f129/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
52 changes: 34 additions & 18 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Server struct {
connection *gorp.DbMap
replicationConnection *gorp.DbMap
traceOn bool
isChecking bool
}

// GetName returns server's name
Expand Down Expand Up @@ -68,6 +69,16 @@ func (s *Server) connect(dsn string, traceOn bool, logger Logger) (*gorp.DbMap,
func (s *Server) CheckHealth(traceOn bool, logger Logger) {
var secondsBehindMaster, openConnections, runningConnections *int

// prevent concurrently checks on same server (slow queries/network)
if s.isChecking {
return
}

s.isChecking = true
defer func() {
s.isChecking = false
}()

if err := s.connectIfNecessary(traceOn, logger); err != nil {
s.health.setDown(
err, secondsBehindMaster, openConnections, runningConnections,
Expand All @@ -76,28 +87,33 @@ func (s *Server) CheckHealth(traceOn bool, logger Logger) {
}

slaveStatusResult, err := s.rawQuery("SHOW SLAVE STATUS", logger)
if err == nil {
rawSecondsBehindMaster := strings.TrimSpace(slaveStatusResult["Seconds_Behind_Master"])
if rawSecondsBehindMaster == "" || strings.ToLower(rawSecondsBehindMaster) == "null" {
s.health.setDown(
fmt.Errorf("empty or null value for Seconds_Behind_Master returned from MySQL: %s", err),
secondsBehindMaster, openConnections, runningConnections,
)
return
}
if err != nil {
s.health.setDown(
err, secondsBehindMaster, openConnections, runningConnections,
)
return
}

tmp, err := strconv.Atoi(rawSecondsBehindMaster)
if err != nil {
s.health.setDown(
fmt.Errorf("unexpected value for Seconds_Behind_Master returned from MySQL (conversion error): %s", err),
secondsBehindMaster, openConnections, runningConnections,
)
return
}
rawSecondsBehindMaster := strings.TrimSpace(slaveStatusResult["Seconds_Behind_Master"])
if rawSecondsBehindMaster == "" || strings.ToLower(rawSecondsBehindMaster) == "null" {
s.health.setDown(
fmt.Errorf("empty or null value for Seconds_Behind_Master returned from MySQL: %s", err),
secondsBehindMaster, openConnections, runningConnections,
)
return
}

secondsBehindMaster = &tmp
tmp, err := strconv.Atoi(rawSecondsBehindMaster)
if err != nil {
s.health.setDown(
fmt.Errorf("unexpected value for Seconds_Behind_Master returned from MySQL (conversion error): %s", err),
secondsBehindMaster, openConnections, runningConnections,
)
return
}

secondsBehindMaster = &tmp

threadsConnectedResult, err := s.rawQuery("SHOW STATUS LIKE 'Threads_connected'", logger)
if err != nil {
s.health.setDown(
Expand Down
2 changes: 1 addition & 1 deletion server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"regexp"
"testing"

sqlmock "github.com/DATA-DOG/go-sqlmock"
"github.com/go-gorp/gorp"
. "github.com/smartystreets/goconvey/convey"
"gopkg.in/DATA-DOG/go-sqlmock.v1"
)

type LoggerMock struct {
Expand Down
22 changes: 0 additions & 22 deletions vendor/github.com/go-gorp/gorp/LICENSE

This file was deleted.

83 changes: 0 additions & 83 deletions vendor/github.com/go-gorp/gorp/column.go

This file was deleted.

Loading

0 comments on commit ae0121d

Please sign in to comment.