netmaker/logic/timer.go

105 lines
2.5 KiB
Go
Raw Normal View History

2022-01-26 00:00:56 +08:00
package logic
import (
"context"
2022-01-26 00:00:56 +08:00
"fmt"
"sync"
2022-01-26 00:00:56 +08:00
"time"
2024-01-19 17:21:51 +08:00
"github.com/gravitl/netmaker/logger"
"golang.org/x/exp/slog"
"github.com/gravitl/netmaker/models"
2022-01-26 00:00:56 +08:00
)
2022-01-26 01:36:25 +08:00
// == Constants ==
2022-01-26 00:00:56 +08:00
2022-01-26 01:36:25 +08:00
// How long to wait before sending telemetry to server (24 hours)
const timer_hours_between_runs = 24
2022-01-26 00:00:56 +08:00
// HookManagerCh - channel to add any new hooks
var HookManagerCh = make(chan models.HookDetails, 3)
2022-01-26 01:36:25 +08:00
// == Public ==
2022-01-26 00:00:56 +08:00
// TimerCheckpoint - Checks if 24 hours has passed since telemetry was last sent. If so, sends telemetry data to posthog
func TimerCheckpoint() error {
// get the telemetry record in the DB, which contains a timestamp
2024-01-19 17:21:51 +08:00
telRecord, err := FetchTelemetryRecord()
2022-01-26 00:00:56 +08:00
if err != nil {
return err
}
2022-01-26 01:36:25 +08:00
sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Hour * time.Duration(timer_hours_between_runs))
2022-01-26 00:00:56 +08:00
// can set to 2 minutes for testing
// sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2)
enoughTimeElapsed := time.Now().After(sendtime)
// if more than 24 hours has elapsed, send telemetry to posthog
if enoughTimeElapsed {
// run any time hooks
runHooks()
2022-05-28 22:23:32 +08:00
return setTelemetryTimestamp(&telRecord)
2022-01-26 00:00:56 +08:00
}
2022-05-28 22:23:32 +08:00
return nil
2022-01-26 00:00:56 +08:00
}
2022-01-26 01:36:25 +08:00
// AddHook - adds a hook function to run every 24hrs
func AddHook(ifaceToAdd interface{}) {
timeHooks = append(timeHooks, ifaceToAdd)
}
// StartHookManager - listens on `HookManagerCh` to run any hook
func StartHookManager(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
for {
select {
case <-ctx.Done():
slog.Error("## Stopping Hook Manager")
return
case newhook := <-HookManagerCh:
wg.Add(1)
go addHookWithInterval(ctx, wg, newhook.Hook, newhook.Interval)
}
}
}
func addHookWithInterval(ctx context.Context, wg *sync.WaitGroup, hook func() error, interval time.Duration) {
defer wg.Done()
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if err := hook(); err != nil {
slog.Error(err.Error())
}
}
}
}
2022-01-26 01:36:25 +08:00
// == private ==
// timeHooks - functions to run once a day, functions must take no parameters
var timeHooks = []interface{}{
loggerDump,
sendTelemetry,
}
func loggerDump() error {
// TODO use slog?
2022-01-26 01:36:25 +08:00
logger.DumpFile(fmt.Sprintf("data/netmaker.log.%s", time.Now().Format(logger.TimeFormatDay)))
return nil
}
// runHooks - runs the functions currently in the timeHooks data structure
func runHooks() {
for _, hook := range timeHooks {
if err := hook.(func() error)(); err != nil {
slog.Error("error occurred when running timer function", "error", err.Error())
2022-01-26 01:36:25 +08:00
}
}
}