Files
threshold/internal/servers/worker/status.go
T

83 lines
2.5 KiB
Go

package worker
import (
"context"
"math/rand"
"time"
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
"github.com/hashicorp/boundary/internal/servers"
"github.com/hashicorp/boundary/internal/types/resource"
"google.golang.org/grpc/resolver"
)
// In the future we could make this configurable
const (
statusInterval = 2 * time.Second
)
func (w *Worker) startStatusTicking(cancelCtx context.Context) {
go func() {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
// This function exists to desynchronize calls to controllers from
// workers so we aren't always getting status updates at the exact same
// intervals, to ease the load on the DB.
getRandomInterval := func() time.Duration {
// 0 to 0.5 adjustment to the base
f := r.Float64() / 2
// Half a chance to be faster, not slower
if r.Float32() > 0.5 {
f = -1 * f
}
return statusInterval + time.Duration(f*float64(time.Second))
}
timer := time.NewTimer(0)
for {
select {
case <-cancelCtx.Done():
w.logger.Info("status ticking shutting down")
return
case <-timer.C:
w.controllerConns.Range(func(_, v interface{}) bool {
// If something is removed from the map while ranging, ignore it
if v == nil {
return true
}
c := v.(*controllerConnection)
result, err := c.client.Status(cancelCtx, &pbs.StatusRequest{
Worker: &servers.Server{
PrivateId: w.conf.RawConfig.Worker.Name,
Name: w.conf.RawConfig.Worker.Name,
Type: resource.Worker.String(),
Description: w.conf.RawConfig.Worker.Description,
Address: w.listeningAddress,
},
})
if err != nil {
w.logger.Error("error making status request to controller", "error", err)
} else {
w.logger.Trace("successfully sent status to controller")
addrs := make([]resolver.Address, 0, len(result.Controllers))
strAddrs := make([]string, 0, len(result.Controllers))
for _, v := range result.Controllers {
addrs = append(addrs, resolver.Address{Addr: v.Address})
strAddrs = append(strAddrs, v.Address)
}
w.Resolver().UpdateState(resolver.State{Addresses: addrs})
w.logger.Trace("found controllers", "addresses", strAddrs)
w.lastStatusSuccess.Store(time.Now())
}
return true
})
timer.Reset(getRandomInterval())
}
}
}()
}
func (w *Worker) LastStatusSuccess() time.Time {
return w.lastStatusSuccess.Load().(time.Time)
}