* [COMPLIANCE] Update Copyright and License Headers * chore: make gen to generate files with copyright headers * chore: update missed copyright headers --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Justin Nguyen <justin.nguyen@hashicorp.com>
93 lines
2.9 KiB
Go
93 lines
2.9 KiB
Go
// Copyright IBM Corp. 2020, 2025
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package worker
|
|
|
|
import (
|
|
"context"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"github.com/hashicorp/boundary/internal/daemon/worker/session"
|
|
"github.com/hashicorp/boundary/internal/errors"
|
|
"github.com/hashicorp/boundary/internal/event"
|
|
pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services"
|
|
)
|
|
|
|
// lastStatistics holds the last successful statistics RPC time.
|
|
type lastStatistics struct {
|
|
LastSuccessfulRequestTime time.Time
|
|
}
|
|
|
|
func (w *Worker) startStatisticsTicking(cancelCtx context.Context) {
|
|
const op = "worker.(Worker).startStatisticsTicking"
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
timer := time.NewTimer(0)
|
|
for {
|
|
select {
|
|
case <-cancelCtx.Done():
|
|
event.WriteSysEvent(w.baseContext, op, "statistics ticking shutting down")
|
|
return
|
|
case <-timer.C:
|
|
err := w.sendStatistic(cancelCtx)
|
|
if err != nil {
|
|
event.WriteError(w.baseContext, op, err)
|
|
}
|
|
// Add a bit of jitter to the wait, so we aren't always getting,
|
|
// statistics updates at the exact same intervals, to ease the load on the DB.
|
|
timer.Reset(w.statisticsInterval + getRandomInterval(r))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (w *Worker) sendStatistic(cancelCtx context.Context) error {
|
|
const op = "worker.(Worker).sendStatistic"
|
|
// skip when the workerId is not available
|
|
if w.LastRoutingInfoSuccess() == nil {
|
|
return errors.New(cancelCtx, errors.Internal, op, "missing latest status")
|
|
}
|
|
workerId := w.LastRoutingInfoSuccess().GetWorkerId()
|
|
if workerId == "" {
|
|
return errors.New(cancelCtx, errors.Internal, op, "worker id is empty")
|
|
}
|
|
sessions := []*pbs.SessionStatistics{}
|
|
w.sessionManager.ForEachLocalSession(func(s session.Session) bool {
|
|
localConnections := s.GetLocalConnections()
|
|
connections := make([]*pbs.Connection, 0, len(localConnections))
|
|
for connectionId, conn := range localConnections {
|
|
connections = append(connections, &pbs.Connection{
|
|
ConnectionId: connectionId,
|
|
BytesUp: conn.BytesUp(),
|
|
BytesDown: conn.BytesDown(),
|
|
Status: conn.Status,
|
|
})
|
|
}
|
|
sessions = append(sessions, &pbs.SessionStatistics{
|
|
SessionId: s.GetId(),
|
|
Connections: connections,
|
|
})
|
|
return true
|
|
})
|
|
// skip when there are no sessions to report
|
|
if len(sessions) == 0 {
|
|
return nil
|
|
}
|
|
clientCon := w.GrpcClientConn.Load()
|
|
client := pbs.NewServerCoordinationServiceClient(clientCon)
|
|
statisticsCtx, statusCancel := context.WithTimeout(cancelCtx, time.Duration(w.statisticsCallTimeoutDuration.Load()))
|
|
defer statusCancel()
|
|
_, err := client.Statistics(statisticsCtx, &pbs.StatisticsRequest{
|
|
WorkerId: workerId,
|
|
Sessions: sessions,
|
|
})
|
|
if err != nil {
|
|
return errors.Wrap(cancelCtx, err, op, errors.WithCode(errors.Internal), errors.WithMsg("error making statistics request to controller: controller_address: %s", clientCon.Target()))
|
|
}
|
|
|
|
w.lastStatisticsSuccess.Store(&lastStatistics{
|
|
LastSuccessfulRequestTime: time.Now(),
|
|
})
|
|
|
|
return nil
|
|
}
|