83 lines
2.5 KiB
Go
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)
|
|
}
|