From cfcaecbfe1f4aecc974bdd4e9a75a3ca2712ce31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zapletal?= Date: Thu, 20 Jul 2023 14:03:28 +0200 Subject: [PATCH] fix(HMS-2002): postpone db stats 10 minutes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lukáš Zapletal --- config/api.env.example | 2 +- internal/background/db_stats.go | 2 +- internal/config/config.go | 2 +- internal/dao/dao_interfaces.go | 2 +- internal/dao/pgx/stat_pgx.go | 17 +++++++++-------- internal/dao/tests/stats_test.go | 29 +++++++++++++++++++++++++++++ 6 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 internal/dao/tests/stats_test.go diff --git a/config/api.env.example b/config/api.env.example index f85a583b..8f016cc5 100644 --- a/config/api.env.example +++ b/config/api.env.example @@ -153,7 +153,7 @@ # STATS_JOBQUEUE_INTERVAL int64 # how often to pull job queue statistics (default "1m") # STATS_RESERVATIONS_INTERVAL int64 -# how often to pull reservation statistics (default "30m") +# how often to pull reservation statistics (default "10m") # TELEMETRY_ENABLED bool # open telemetry collecting (default "false") # TELEMETRY_JAEGER_ENABLED bool diff --git a/internal/background/db_stats.go b/internal/background/db_stats.go index a00bcd98..1e792fd4 100644 --- a/internal/background/db_stats.go +++ b/internal/background/db_stats.go @@ -46,7 +46,7 @@ func dbStatsObserveTick(ctx context.Context) { func dbStatsTick(ctx context.Context) error { logger := zerolog.Ctx(ctx) sdao := dao.GetStatDao(ctx) - stats, err := sdao.Get(ctx) + stats, err := sdao.Get(ctx, 10) if err != nil { return fmt.Errorf("stats error: %w", err) } diff --git a/internal/config/config.go b/internal/config/config.go index e97a501c..61c2e073 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -40,7 +40,7 @@ var config struct { } `env-prefix:"APP_"` Stats struct { JobQueue time.Duration `env:"JOBQUEUE_INTERVAL" env-default:"1m" env-description:"how often to pull job queue statistics"` - ReservationsInterval time.Duration `env:"RESERVATIONS_INTERVAL" env-default:"30m" env-description:"how often to pull reservation statistics"` + ReservationsInterval time.Duration `env:"RESERVATIONS_INTERVAL" env-default:"10m" env-description:"how often to pull reservation statistics"` } `env-prefix:"STATS_"` Database struct { Host string `env:"HOST" env-default:"localhost" env-description:"main database hostname"` diff --git a/internal/dao/dao_interfaces.go b/internal/dao/dao_interfaces.go index be96c7e9..3265df35 100644 --- a/internal/dao/dao_interfaces.go +++ b/internal/dao/dao_interfaces.go @@ -115,5 +115,5 @@ var GetStatDao func(ctx context.Context) StatDao // StatDao represents an account (tenant) type StatDao interface { - Get(ctx context.Context) (*models.Statistics, error) + Get(ctx context.Context, delayMin int) (*models.Statistics, error) } diff --git a/internal/dao/pgx/stat_pgx.go b/internal/dao/pgx/stat_pgx.go index 68b4ea15..c5f84497 100644 --- a/internal/dao/pgx/stat_pgx.go +++ b/internal/dao/pgx/stat_pgx.go @@ -20,10 +20,10 @@ func getStatDao(ctx context.Context) dao.StatDao { return &statDao{} } -func (x *statDao) getUsage(ctx context.Context, interval string) ([]*models.UsageStat, error) { +func (x *statDao) getUsage(ctx context.Context, iStart, iEnd string) ([]*models.UsageStat, error) { query := `select provider, 'success' as result, count(provider) as count from reservations - where created_at >= now() - cast($1 as interval) + where created_at between now() - cast($1 as interval) and now() - cast($2 as interval) and success = true group by provider @@ -31,7 +31,7 @@ func (x *statDao) getUsage(ctx context.Context, interval string) ([]*models.Usag select provider, 'failure' as result, count(provider) as count from reservations - where created_at >= now() - cast($1 as interval) + where created_at between now() - cast($1 as interval) and now() - cast($2 as interval) and success = false group by provider @@ -39,12 +39,12 @@ func (x *statDao) getUsage(ctx context.Context, interval string) ([]*models.Usag select provider, 'pending' as result, count(provider) as count from reservations - where created_at >= now() - cast($1 as interval) + where created_at between now() - cast($1 as interval) and now() - cast($2 as interval) and success is null group by provider` var result []*models.UsageStat - rows, err := db.Pool.Query(ctx, query, interval) + rows, err := db.Pool.Query(ctx, query, iStart, iEnd) if err != nil { return nil, fmt.Errorf("pgx error: %w", err) } @@ -57,13 +57,14 @@ func (x *statDao) getUsage(ctx context.Context, interval string) ([]*models.Usag return result, nil } -func (x *statDao) Get(ctx context.Context) (*models.Statistics, error) { - usage24h, err := x.getUsage(ctx, "24 hours") +func (x *statDao) Get(ctx context.Context, delayMin int) (*models.Statistics, error) { + delay := fmt.Sprintf("%d minutes", delayMin) + usage24h, err := x.getUsage(ctx, "24 hours "+delay, delay) if err != nil { return nil, fmt.Errorf("get usage error: %w", err) } - usage28d, err := x.getUsage(ctx, "28 days") + usage28d, err := x.getUsage(ctx, "28 days "+delay, delay) if err != nil { return nil, fmt.Errorf("get usage error: %w", err) } diff --git a/internal/dao/tests/stats_test.go b/internal/dao/tests/stats_test.go new file mode 100644 index 00000000..df301ef6 --- /dev/null +++ b/internal/dao/tests/stats_test.go @@ -0,0 +1,29 @@ +//go:build integration +// +build integration + +package tests + +import ( + "testing" + + "github.com/RHEnVision/provisioning-backend/internal/dao" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestStats(t *testing.T) { + reservationDao, ctx := setupReservation(t) + defer reset() + + t.Run("success", func(t *testing.T) { + res := newNoopReservation() + err := reservationDao.CreateNoop(ctx, res) + require.NoError(t, err) + + statDao := dao.GetStatDao(ctx) + stats, err := statDao.Get(ctx, 0) + + require.NoError(t, err) + assert.Equal(t, int64(1), stats.Usage24h[0].Count) + }) +}