timer.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package logic
  2. import (
  3. "context"
  4. "fmt"
  5. "sync"
  6. "time"
  7. "github.com/gravitl/netmaker/logger"
  8. "github.com/gravitl/netmaker/models"
  9. )
  10. // == Constants ==
  11. // How long to wait before sending telemetry to server (24 hours)
  12. const timer_hours_between_runs = 24
  13. // HookManagerCh - channel to add any new hooks
  14. var HookManagerCh = make(chan models.HookDetails, 2)
  15. // == Public ==
  16. // TimerCheckpoint - Checks if 24 hours has passed since telemetry was last sent. If so, sends telemetry data to posthog
  17. func TimerCheckpoint() error {
  18. // get the telemetry record in the DB, which contains a timestamp
  19. telRecord, err := fetchTelemetryRecord()
  20. if err != nil {
  21. return err
  22. }
  23. sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Hour * time.Duration(timer_hours_between_runs))
  24. // can set to 2 minutes for testing
  25. // sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2)
  26. enoughTimeElapsed := time.Now().After(sendtime)
  27. // if more than 24 hours has elapsed, send telemetry to posthog
  28. if enoughTimeElapsed {
  29. // run any time hooks
  30. runHooks()
  31. return setTelemetryTimestamp(&telRecord)
  32. }
  33. return nil
  34. }
  35. // AddHook - adds a hook function to run every 24hrs
  36. func AddHook(ifaceToAdd interface{}) {
  37. timeHooks = append(timeHooks, ifaceToAdd)
  38. }
  39. // StartHookManager - listens on `HookManagerCh` to run any hook
  40. func StartHookManager(ctx context.Context, wg *sync.WaitGroup) {
  41. defer wg.Done()
  42. for {
  43. select {
  44. case <-ctx.Done():
  45. logger.Log(0, "## Stopping Hook Manager")
  46. return
  47. case newhook := <-HookManagerCh:
  48. wg.Add(1)
  49. go addHookWithInterval(ctx, wg, newhook.Hook, newhook.Interval)
  50. }
  51. }
  52. }
  53. func addHookWithInterval(ctx context.Context, wg *sync.WaitGroup, hook func() error, interval time.Duration) {
  54. defer wg.Done()
  55. ticker := time.NewTicker(interval)
  56. defer ticker.Stop()
  57. for {
  58. select {
  59. case <-ctx.Done():
  60. return
  61. case <-ticker.C:
  62. hook()
  63. }
  64. }
  65. }
  66. // == private ==
  67. // timeHooks - functions to run once a day, functions must take no parameters
  68. var timeHooks = []interface{}{
  69. loggerDump,
  70. sendTelemetry,
  71. }
  72. func loggerDump() error {
  73. logger.DumpFile(fmt.Sprintf("data/netmaker.log.%s", time.Now().Format(logger.TimeFormatDay)))
  74. return nil
  75. }
  76. // runHooks - runs the functions currently in the timeHooks data structure
  77. func runHooks() {
  78. for _, hook := range timeHooks {
  79. if err := hook.(func() error)(); err != nil {
  80. logger.Log(1, "error occurred when running timer function:", err.Error())
  81. }
  82. }
  83. }