-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Balancing #107
Balancing #107
Changes from 1 commit
646852c
7ca93a6
67e3852
5631bc0
bc6098e
ca8f512
c0a686d
2f13508
452efe9
ded1321
3847aea
64b4e9a
5d65ae6
58d540c
470741f
7e5e6ec
723a025
73be064
7ce573a
5f53768
f54769a
d76597c
1b94974
8478a75
22537e1
a27c1b0
b7c8c25
458d581
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,6 +231,7 @@ func (h *histogram) unshiftData(now time.Time) { | |
h.growSeries() | ||
} | ||
|
||
// Breaker is interface od citcuit breaker | ||
type Breaker interface { | ||
Record(duration time.Duration, success bool) bool | ||
ShouldOpen() bool | ||
|
@@ -252,6 +253,7 @@ func newBreaker(retention int, timeLimit time.Duration, | |
} | ||
} | ||
|
||
// NodeBreaker is implementation of Breaker interface | ||
type NodeBreaker struct { | ||
rate float64 | ||
limit time.Duration | ||
|
@@ -265,6 +267,7 @@ type NodeBreaker struct { | |
state *openStateTracker | ||
} | ||
|
||
// Record collects call data and returns bool if breaker should be open | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
func (breaker *NodeBreaker) Record(duration time.Duration, success bool) bool { | ||
breaker.timeData.Add(float64(duration)) | ||
successValue := float64(1) | ||
|
@@ -275,6 +278,7 @@ func (breaker *NodeBreaker) Record(duration time.Duration, success bool) bool { | |
return breaker.ShouldOpen() | ||
} | ||
|
||
// ShouldOpen checks if breaker should be open | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as above |
||
func (breaker *NodeBreaker) ShouldOpen() bool { | ||
exceeded := breaker.limitsExceeded() | ||
if breaker.state != nil { | ||
|
@@ -348,12 +352,14 @@ type lenLimitCounter struct { | |
mx sync.Mutex | ||
mjarco marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// Add acumates new values | ||
func (counter *lenLimitCounter) Add(value float64) { | ||
index := counter.nextIdx | ||
counter.values[index] = value | ||
counter.nextIdx = (counter.nextIdx + 1) % cap(counter.values) | ||
} | ||
|
||
// Sum returns sum of valuesś | ||
mjarco marked this conversation as resolved.
Show resolved
Hide resolved
|
||
func (counter *lenLimitCounter) Sum() float64 { | ||
sum := float64(0) | ||
for _, v := range counter.values { | ||
|
@@ -362,6 +368,7 @@ func (counter *lenLimitCounter) Sum() float64 { | |
return sum | ||
} | ||
|
||
// Percentile return value for given percentile | ||
func (counter *lenLimitCounter) Percentile(percentile float64) float64 { | ||
snapshot := make([]float64, len(counter.values)) | ||
copy(snapshot, counter.values) | ||
|
@@ -442,26 +449,28 @@ func (tracker *openStateTracker) currentState(now time.Time, limitsExceeded bool | |
return tracker.state, changed | ||
} | ||
|
||
// MeasuredStorage coordinates metrics collection | ||
type MeasuredStorage struct { | ||
Node | ||
Breaker | ||
http.RoundTripper | ||
Name string | ||
} | ||
|
||
// RoundTrip implements http.RoundTripper | ||
func (ms *MeasuredStorage) RoundTrip(req *http.Request) (*http.Response, error) { | ||
start := time.Now() | ||
resp, err := ms.RoundTripper.RoundTrip(req) | ||
duration := time.Since(start) | ||
success := backend.IsSuccessful(resp, err) | ||
open := ms.Breaker.Record(duration, success) | ||
fmt.Printf("Updated %s with success %t, and it's open %t\n", ms.Name, success, open) | ||
ms.Node.Update(duration) | ||
ms.Node.SetActive(!open) | ||
return resp, err | ||
} | ||
|
||
func NewBalancerPrioritySet(storagesConfig config.Storages, backends map[string]http.RoundTripper) BalancerPrioritySet { | ||
// NewBalancerPrioritySet configures prioritized balancers stack | ||
func NewBalancerPrioritySet(storagesConfig config.Storages, backends map[string]http.RoundTripper) *BalancerPrioritySet { | ||
priorities := make([]int, 0) | ||
priotitiesFilter := make(map[int]struct{}) | ||
priorityStorage := make(map[int][]*MeasuredStorage) | ||
|
@@ -492,7 +501,7 @@ func NewBalancerPrioritySet(storagesConfig config.Storages, backends map[string] | |
priorityStorage[storageConfig.Priority], mstorage) | ||
} | ||
sort.Ints(priorities) | ||
bps := BalancerPrioritySet{balancers: []*ResponseTimeBalancer{}} | ||
bps := &BalancerPrioritySet{balancers: []*ResponseTimeBalancer{}} | ||
for _, key := range priorities { | ||
nodes := make([]Node, 0) | ||
for _, node := range priorityStorage[key] { | ||
|
@@ -504,10 +513,12 @@ func NewBalancerPrioritySet(storagesConfig config.Storages, backends map[string] | |
return bps | ||
} | ||
|
||
// BalancerPrioritySet selects storage by priority and availability | ||
type BalancerPrioritySet struct { | ||
balancers []*ResponseTimeBalancer | ||
} | ||
|
||
// GetMostAvailable returns balancer member | ||
func (bps *BalancerPrioritySet) GetMostAvailable() *MeasuredStorage { | ||
for _, balancer := range bps.balancers { | ||
node, err := balancer.Elect() | ||
|
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
of