From 83903dd4c414d4a5cc306b33cd6fa7583320fb56 Mon Sep 17 00:00:00 2001 From: Sergey <83376337+freak12techno@users.noreply.github.com> Date: Sun, 5 Feb 2023 16:24:38 +0300 Subject: [PATCH] feat: use cron intervals (#30) --- .golangci.yml | 1 + config.example.toml | 9 ++++- go.mod | 1 + go.sum | 2 + pkg/app.go | 88 +++++++++++++++++++++++++++----------------- pkg/config/config.go | 2 +- 6 files changed, 66 insertions(+), 37 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index ca62db1..10bc40a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -39,3 +39,4 @@ linters: - gosec - testpackage - gci + - musttag diff --git a/config.example.toml b/config.example.toml index dd8d467..3b79220 100644 --- a/config.example.toml +++ b/config.example.toml @@ -2,8 +2,13 @@ state-path = "cosmos-proposals-checker-state.json" # A path to a file that will store mutes of this app. Omitting it will disable the mute functionality. mutes-path = "cosmos-proposals-checker-mutes.json" -# Interval to check and notify, in seconds. Defaults to 3600 (1 hour) -interval = 60 +# Interval to check and notify. +# Can be a cron-like interval (like "0 * * * *" for every hour), +# "@hourly"/"@daily" for hourly/daily intervals, or "@every 1h" +# for specifying intervals more granularly. +# See https://pkg.go.dev/github.com/robfig/cron?utm_source=godoc#hdr-CRON_Expression_Format for examples. +# Defaults to "@hourly" +interval = "@hourly" # Logging configuration [log] diff --git a/go.mod b/go.mod index 52d3bc2..78ff6fa 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require ( github.com/BurntSushi/toml v1.1.0 github.com/mcuadros/go-defaults v1.2.0 + github.com/robfig/cron/v3 v3.0.1 github.com/rs/zerolog v1.26.1 github.com/spf13/cobra v1.4.0 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index 82c4d51..a8d32b4 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= diff --git a/pkg/app.go b/pkg/app.go index 61cac83..5884e30 100644 --- a/pkg/app.go +++ b/pkg/app.go @@ -1,8 +1,6 @@ package pkg import ( - "time" - configPkg "main/pkg/config" "main/pkg/logger" mutesManager "main/pkg/mutes_manager" @@ -12,18 +10,23 @@ import ( "main/pkg/reporters/telegram" "main/pkg/state/generator" "main/pkg/state/manager" + + cron "github.com/robfig/cron/v3" + "github.com/rs/zerolog" ) type App struct { - ConfigPath string + Logger *zerolog.Logger + Config *configPkg.Config + StateManager *manager.StateManager + MutesManager *mutesManager.MutesManager + ReportGenerator *reportPkg.ReportGenerator + StateGenerator *generator.StateGenerator + Reporters []reportersPkg.Reporter } func NewApp(configPath string) *App { - return &App{ConfigPath: configPath} -} - -func (a *App) Start() { - config, err := configPkg.GetConfig(a.ConfigPath) + config, err := configPkg.GetConfig(configPath) if err != nil { logger.GetDefaultLogger().Fatal().Err(err).Msg("Could not load config") } @@ -35,47 +38,64 @@ func (a *App) Start() { log := logger.GetLogger(config.LogConfig) stateManager := manager.NewStateManager(config.StatePath, log) - stateManager.Load() - mutesManager := mutesManager.NewMutesManager(config.MutesPath, log) - mutesManager.Load() - reportGenerator := reportPkg.NewReportGenerator(stateManager, log, config.Chains) stateGenerator := generator.NewStateGenerator(log, config.Chains) - reporters := []reportersPkg.Reporter{ - pagerduty.NewPagerDutyReporter(config.PagerDutyConfig, log), - telegram.NewTelegramReporter(config.TelegramConfig, mutesManager, stateGenerator, log), + return &App{ + Logger: log, + Config: config, + StateManager: stateManager, + MutesManager: mutesManager, + ReportGenerator: reportGenerator, + StateGenerator: stateGenerator, + Reporters: []reportersPkg.Reporter{ + pagerduty.NewPagerDutyReporter(config.PagerDutyConfig, log), + telegram.NewTelegramReporter(config.TelegramConfig, mutesManager, stateGenerator, log), + }, } +} + +func (a *App) Start() { + a.StateManager.Load() + a.MutesManager.Load() - for _, reporter := range reporters { + for _, reporter := range a.Reporters { reporter.Init() if reporter.Enabled() { - log.Info().Str("name", reporter.Name()).Msg("Init reporter") + a.Logger.Info().Str("name", reporter.Name()).Msg("Init reporter") } } - for { - newState := stateGenerator.GetState(stateManager.State) - report := reportGenerator.GenerateReport(stateManager.State, newState) + c := cron.New() + if _, err := c.AddFunc(a.Config.Interval, func() { + a.Report() + }); err != nil { + a.Logger.Fatal().Err(err).Msg("Error processing cron pattern") + } + c.Start() + a.Logger.Info().Str("interval", a.Config.Interval).Msg("Scheduled proposals reporting") - if report.Empty() { - log.Debug().Msg("Empty report, not sending.") - time.Sleep(time.Second * time.Duration(config.Interval)) - continue - } + select {} +} - log.Debug().Int("len", len(report.Entries)).Msg("Got non-empty report") +func (a *App) Report() { + newState := a.StateGenerator.GetState(a.StateManager.State) + report := a.ReportGenerator.GenerateReport(a.StateManager.State, newState) - for _, reporter := range reporters { - if reporter.Enabled() { - log.Debug().Str("name", reporter.Name()).Msg("Sending report...") - if err := reporter.SendReport(report); err != nil { - log.Error().Err(err).Str("name", reporter.Name()).Msg("Failed to send report") - } + if report.Empty() { + a.Logger.Debug().Msg("Empty report, not sending.") + return + } + + a.Logger.Debug().Int("len", len(report.Entries)).Msg("Got non-empty report") + + for _, reporter := range a.Reporters { + if reporter.Enabled() { + a.Logger.Debug().Str("name", reporter.Name()).Msg("Sending report...") + if err := reporter.SendReport(report); err != nil { + a.Logger.Error().Err(err).Str("name", reporter.Name()).Msg("Failed to send report") } } - - time.Sleep(time.Second * time.Duration(config.Interval)) } } diff --git a/pkg/config/config.go b/pkg/config/config.go index e8b5d10..22cdcae 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -17,7 +17,7 @@ type Config struct { StatePath string `toml:"state-path"` MutesPath string `toml:"mutes-path"` Chains types.Chains `toml:"chains"` - Interval int64 `toml:"interval" default:"3600"` + Interval string `toml:"interval" default:"* * * * *"` } type PagerDutyConfig struct {