119 lines
2.3 KiB
Go
119 lines
2.3 KiB
Go
package app
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func (r *transportHealthRefresher) syncKnownClients(items []TransportClient) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
known := make(map[string]struct{}, len(items))
|
|
for _, it := range items {
|
|
id := strings.TrimSpace(it.ID)
|
|
if id == "" {
|
|
continue
|
|
}
|
|
known[id] = struct{}{}
|
|
entry := r.entries[id]
|
|
if entry == nil {
|
|
entry = &transportHealthRefreshEntry{
|
|
swr: newRefreshCoordinator(
|
|
transportHealthFreshTTL,
|
|
transportHealthBackoffMin,
|
|
transportHealthBackoffMax,
|
|
),
|
|
}
|
|
r.entries[id] = entry
|
|
}
|
|
if ts, ok := parseTransportHealthLastCheck(it); ok {
|
|
entry.swr.setUpdatedAt(ts)
|
|
}
|
|
}
|
|
|
|
for id := range r.entries {
|
|
if _, ok := known[id]; !ok {
|
|
delete(r.entries, id)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *transportHealthRefresher) begin(item TransportClient, force bool, now time.Time) bool {
|
|
id := strings.TrimSpace(item.ID)
|
|
if id == "" {
|
|
return false
|
|
}
|
|
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
entry := r.entries[id]
|
|
if entry == nil {
|
|
entry = &transportHealthRefreshEntry{
|
|
swr: newRefreshCoordinator(
|
|
transportHealthFreshTTL,
|
|
transportHealthBackoffMin,
|
|
transportHealthBackoffMax,
|
|
),
|
|
}
|
|
r.entries[id] = entry
|
|
}
|
|
if ts, ok := parseTransportHealthLastCheck(item); ok {
|
|
entry.swr.setUpdatedAt(ts)
|
|
}
|
|
hasData := strings.TrimSpace(item.Health.LastCheck) != ""
|
|
return entry.swr.beginRefresh(now, force, hasData)
|
|
}
|
|
|
|
func (r *transportHealthRefresher) finishSuccess(id string, now time.Time) {
|
|
id = strings.TrimSpace(id)
|
|
if id == "" {
|
|
return
|
|
}
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
entry := r.entries[id]
|
|
if entry == nil {
|
|
return
|
|
}
|
|
entry.swr.finishSuccess(now)
|
|
}
|
|
|
|
func (r *transportHealthRefresher) finishError(id, msg string, now time.Time) {
|
|
id = strings.TrimSpace(id)
|
|
if id == "" {
|
|
return
|
|
}
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
entry := r.entries[id]
|
|
if entry == nil {
|
|
return
|
|
}
|
|
entry.swr.finishError(msg, now)
|
|
}
|
|
|
|
func (r *transportHealthRefresher) acquire() {
|
|
r.sem <- struct{}{}
|
|
}
|
|
|
|
func (r *transportHealthRefresher) release() {
|
|
select {
|
|
case <-r.sem:
|
|
default:
|
|
}
|
|
}
|
|
|
|
func parseTransportHealthLastCheck(item TransportClient) (time.Time, bool) {
|
|
ts := strings.TrimSpace(item.Health.LastCheck)
|
|
if ts == "" {
|
|
return time.Time{}, false
|
|
}
|
|
t, err := time.Parse(time.RFC3339, ts)
|
|
if err != nil {
|
|
return time.Time{}, false
|
|
}
|
|
return t, true
|
|
}
|