Skip to content

Commit

Permalink
optimize: latencyString shows realLatency(+offset) (#307)
Browse files Browse the repository at this point in the history
  • Loading branch information
luochen1990 authored Sep 2, 2023
1 parent b9b1624 commit eaf9684
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 56 deletions.
86 changes: 34 additions & 52 deletions component/outbound/dialer/alive_dialer_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ const (
)

type minLatency struct {
latency time.Duration
dialer *Dialer
sortingLatency time.Duration
dialer *Dialer
}

// AliveDialerSet assumes mapping between index and dialer MUST remain unchanged.
Expand Down Expand Up @@ -80,7 +80,7 @@ func NewAliveDialerSet(
selectionPolicy: selectionPolicy,
minLatency: minLatency{
// Initiate the latency with a very big value.
latency: time.Hour,
sortingLatency: time.Hour,
},
}
for _, d := range dialers {
Expand All @@ -102,9 +102,13 @@ func (a *AliveDialerSet) GetRand() *Dialer {
return a.inorderedAliveDialerSet[ind]
}

func (a *AliveDialerSet) SortingLatency(d *Dialer) time.Duration {
return a.dialerToLatency[d] + a.dialerToLatencyOffset[d]
}

// GetMinLatency acquires correct selectionPolicy.
func (a *AliveDialerSet) GetMinLatency() (d *Dialer, latency time.Duration) {
return a.minLatency.dialer, a.minLatency.latency
return a.minLatency.dialer, a.minLatency.sortingLatency
}

func (a *AliveDialerSet) printLatencies() {
Expand All @@ -113,57 +117,38 @@ func (a *AliveDialerSet) printLatencies() {
var alive []*struct {
d *Dialer
l time.Duration
o time.Duration
}
for _, d := range a.inorderedAliveDialerSet {
latency, ok := a.dialerToLatency[d]
if !ok {
continue
}
offset := a.dialerToLatencyOffset[d]
alive = append(alive, &struct {
d *Dialer
l time.Duration
}{d, latency})
o time.Duration
}{d, latency, offset})
}
sort.SliceStable(alive, func(i, j int) bool {
return alive[i].l < alive[j].l
return alive[i].l+alive[i].o < alive[j].l+alive[j].o
})
for i, dl := range alive {
builder.WriteString(fmt.Sprintf("%4d. %v: %v\n", i+1, dl.d.property.Name, a.latencyString(dl.d, dl.l)))
builder.WriteString(fmt.Sprintf("%4d. %v: %v\n", i+1, dl.d.property.Name, latencyString(dl.l, dl.o)))
}
a.log.Infoln(strings.TrimSuffix(builder.String(), "\n"))
}

func (a *AliveDialerSet) offsetLatency(d *Dialer, latency time.Duration, reverse bool) time.Duration {
offset := a.dialerToLatencyOffset[d]
var result time.Duration
if !reverse {
result = latency + offset
} else {
result = latency - offset
}
epsilon := 1 * time.Nanosecond
if result < +epsilon {
return +epsilon
}
if result > Timeout-epsilon {
result = Timeout - epsilon
}
return result
}

func (a *AliveDialerSet) latencyString(d *Dialer, afterLatency time.Duration) string {
return latencyString(afterLatency, a.offsetLatency(d, afterLatency, true))
}

// NotifyLatencyChange should be invoked when dialer every time latency and alive state changes.
func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
a.mu.Lock()
defer a.mu.Unlock()
var (
rawLatency time.Duration
latency time.Duration
hasLatency bool
minPolicy bool
rawLatency time.Duration
sortingLatency time.Duration
hasLatency bool
minPolicy bool
)

switch a.selectionPolicy {
Expand All @@ -178,11 +163,6 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
hasLatency = rawLatency > 0
minPolicy = true
}
if hasLatency {
latency = a.offsetLatency(dialer, rawLatency, false)
} else {
latency = rawLatency
}

if alive {
index := a.dialerToIndex[dialer]
Expand Down Expand Up @@ -233,15 +213,16 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
if hasLatency {
bakOldBestDialer := a.minLatency.dialer
// Calc minLatency.
a.dialerToLatency[dialer] = latency
a.dialerToLatency[dialer] = rawLatency
sortingLatency = a.SortingLatency(dialer)
if alive &&
latency <= a.minLatency.latency && // To avoid arithmetic overflow.
latency <= a.minLatency.latency-a.tolerance {
a.minLatency.latency = latency
sortingLatency <= a.minLatency.sortingLatency && // To avoid arithmetic overflow.
sortingLatency <= a.minLatency.sortingLatency-a.tolerance {
a.minLatency.sortingLatency = sortingLatency
a.minLatency.dialer = dialer
} else if a.minLatency.dialer == dialer {
a.minLatency.latency = latency
if !alive || latency > a.minLatency.latency {
a.minLatency.sortingLatency = sortingLatency
if !alive || sortingLatency > a.minLatency.sortingLatency {
// Latency increases.
if !alive {
a.minLatency.dialer = nil
Expand All @@ -265,7 +246,7 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
oldDialerName = bakOldBestDialer.property.Name
}
a.log.WithFields(logrus.Fields{
string(a.selectionPolicy): a.latencyString(a.minLatency.dialer, a.minLatency.latency),
string(a.selectionPolicy): latencyString(a.dialerToLatency[a.minLatency.dialer], a.dialerToLatencyOffset[a.minLatency.dialer]),
"_new_dialer": a.minLatency.dialer.property.Name,
"_old_dialer": oldDialerName,
"group": a.dialerGroupName,
Expand Down Expand Up @@ -299,22 +280,23 @@ func (a *AliveDialerSet) calcMinLatency() {
var minLatency = time.Hour
var minDialer *Dialer
for _, d := range a.inorderedAliveDialerSet {
latency, ok := a.dialerToLatency[d]
_, ok := a.dialerToLatency[d]
if !ok {
continue
}
if latency < minLatency {
minLatency = latency
sortingLatency := a.SortingLatency(d)
if sortingLatency < minLatency {
minLatency = sortingLatency
minDialer = d
}
}
if a.minLatency.dialer == nil {
a.minLatency.latency = minLatency
a.minLatency.sortingLatency = minLatency
a.minLatency.dialer = minDialer
} else if minDialer != nil &&
minLatency <= a.minLatency.latency && // To avoid arithmetic overflow.
minLatency <= a.minLatency.latency-a.tolerance {
a.minLatency.latency = minLatency
minLatency <= a.minLatency.sortingLatency && // To avoid arithmetic overflow.
minLatency <= a.minLatency.sortingLatency-a.tolerance {
a.minLatency.sortingLatency = minLatency
a.minLatency.dialer = minDialer
}
}
19 changes: 15 additions & 4 deletions component/outbound/dialer/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ package dialer

import "time"

func latencyString(latencyAfterOffset, latencyBeforeOffset time.Duration) string {
if latencyBeforeOffset == latencyAfterOffset {
return latencyAfterOffset.Truncate(time.Millisecond).String()
func showDuration(d time.Duration) string {
return d.Truncate(time.Millisecond).String()
}

func latencyString(realLatency, latencyOffset time.Duration) string {
var offsetSign string = "+"
if latencyOffset < 0 {
offsetSign = "-"
}
return latencyAfterOffset.Truncate(time.Millisecond).String() + "(" + latencyBeforeOffset.Truncate(time.Millisecond).String() + ")"

var offsetPart string = ""
if latencyOffset != 0 {
offsetPart = "(" + offsetSign + showDuration(latencyOffset.Abs()) + "=" + showDuration(realLatency+latencyOffset) + ")"
}

return showDuration(realLatency) + offsetPart
}

0 comments on commit eaf9684

Please sign in to comment.