Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Commit

Permalink
report immediately on startup (#3)
Browse files Browse the repository at this point in the history
Signed-off-by: Benji Visser <benji@093b.org>
  • Loading branch information
noqcks authored Apr 30, 2023
1 parent 6279bc1 commit 555ab06
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 10 deletions.
37 changes: 28 additions & 9 deletions agent/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,42 @@ func HandleReport(report inventory.Report, cfg *config.Application) error {

// PeriodicallyGetInventoryReport periodically retrieve image results and report/output them according to the configuration.
// Note: Errors do not cause the function to exit, since this is periodically running
func PeriodicallyGetInventoryReport(cfg *config.Application) {
func PeriodicallyGetInventoryReport(ctx context.Context, cfg *config.Application, getInventoryReportFunc func(cfg *config.Application) (inventory.Report, error), reportHandler func(report inventory.Report, cfg *config.Application) error) {
// Fire off a ticker that reports according to a configurable polling interval
ticker := time.NewTicker(time.Duration(cfg.PollingIntervalMinutes) * time.Minute)
var ticker *time.Ticker
if cfg.PollingIntervalSeconds != 0 {
ticker = time.NewTicker(time.Duration(cfg.PollingIntervalSeconds) * time.Second)
}
if cfg.PollingIntervalMinutes != 0 {
ticker = time.NewTicker(time.Duration(cfg.PollingIntervalMinutes) * time.Minute)
}

// report immediately if this is the first time the agent is reporting
// this is to ensure the user get immediate feedback that the agent is running
firstReport := true

for {
report, err := GetInventoryReport(cfg)
if !firstReport {
// Wait at least as long as the ticker
select {
case <-ctx.Done():
return
case <-ticker.C:
}
}

log.Debugf("Start new gather: %s", time.Now())

report, err := getInventoryReportFunc(cfg)
if err != nil {
log.Errorf("Failed to get Inventory Report: %w", err)
log.Errorf("Failed to get Inventory Report: %v", err)
} else {
err := HandleReport(report, cfg)
err := reportHandler(report, cfg)
if err != nil {
log.Errorf("Failed to handle Inventory Report: %w", err)
log.Errorf("Failed to handle Inventory Report: %v", err)
}
}

// Wait at least as long as the ticker
log.Debugf("Start new gather: %s", <-ticker.C)
firstReport = false
}
}

Expand Down
40 changes: 40 additions & 0 deletions agent/lib_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package agent

import (
"context"
"testing"
"time"

"github.com/noqcks/xeol-agent/agent/inventory"
"github.com/noqcks/xeol-agent/internal/config"
)

func TestPeriodicallyGetInventoryReport(t *testing.T) {
cfg := &config.Application{
PollingIntervalSeconds: 1,
}

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Duration(cfg.PollingIntervalSeconds)*time.Second)
defer cancel()

reportTimes := []time.Time{}
reportHandler := func(report inventory.Report, cfg *config.Application) error {
reportTimes = append(reportTimes, time.Now())
return nil
}

getInventoryReportFunc := func(cfg *config.Application) (inventory.Report, error) {
return inventory.Report{}, nil
}
startTime := time.Now()
PeriodicallyGetInventoryReport(ctx, cfg, getInventoryReportFunc, reportHandler)

if len(reportTimes) < 2 {
t.Fatalf("Expected at least two reports, but got %d", len(reportTimes))
}

firstInterval := reportTimes[0].Sub(startTime)
if firstInterval >= time.Duration(cfg.PollingIntervalSeconds)*time.Second {
t.Fatalf("Expected the first report to be immediate, but the interval was %v", firstInterval)
}
}
4 changes: 3 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"fmt"
"os"
"runtime/pprof"
Expand Down Expand Up @@ -43,7 +44,8 @@ var rootCmd = &cobra.Command{

switch appConfig.RunMode {
case mode.PeriodicPolling:
agent.PeriodicallyGetInventoryReport(appConfig)
ctx := context.Background()
agent.PeriodicallyGetInventoryReport(ctx, appConfig, agent.GetInventoryReport, agent.HandleReport)
default:
report, err := agent.GetInventoryReport(appConfig)
if appConfig.Dev.ProfileCPU {
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type Application struct {
Mode string `mapstructure:"mode"`
IgnoreNotRunning bool `mapstructure:"ignore-not-running"`
PollingIntervalMinutes int `mapstructure:"polling-interval-minutes"`
PollingIntervalSeconds int `mapstructure:"polling-interval-seconds"`
XeolDetails XeolInfo `mapstructure:"xeol"`
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ runmode: 0
mode: adhoc
ignorenotrunning: true
pollingintervalminutes: 300
pollingintervalseconds: 0
xeoldetails:
apikey: '******'
http:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ runmode: 0
mode: ""
ignorenotrunning: false
pollingintervalminutes: 0
pollingintervalseconds: 0
xeoldetails:
apikey: ""
http:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ runmode: 0
mode: adhoc
ignorenotrunning: true
pollingintervalminutes: 300
pollingintervalseconds: 0
xeoldetails:
apikey: '******'
http:
Expand Down

0 comments on commit 555ab06

Please sign in to comment.