diff --git a/backend/pkg/api/instances.go b/backend/pkg/api/instances.go index 85d0e7d26..7786bf315 100644 --- a/backend/pkg/api/instances.go +++ b/backend/pkg/api/instances.go @@ -49,7 +49,7 @@ const ( const ( validityInterval postgresDuration = "1 days" - defaultInterval time.Duration = 2 * time.Hour + defaultInterval time.Duration = time.Hour ) // Instance represents an instance running one or more applications for which @@ -642,6 +642,11 @@ func (api *API) instanceStatusHistoryQuery(instanceID, appID, groupID string, li Limit(uint(limit)) } +// GetDefaultInterval returns the default interval used for instance stats queries. +func (api *API) GetDefaultInterval() time.Duration { + return defaultInterval +} + // instanceStatsQuery returns a SelectDataset prepared to return all instances // that have been checked in during a given duration from a given time. func (api *API) instanceStatsQuery(t *time.Time, duration *time.Duration) *goqu.SelectDataset { @@ -777,9 +782,9 @@ func (api *API) GetInstanceStatsByTimestamp(t time.Time) ([]InstanceStats, error return instances, nil } -// updateInstanceStats updates the instance_stats table with instances checked +// UpdateInstanceStats updates the instance_stats table with instances checked // in during a given duration from a given time. -func (api *API) updateInstanceStats(t *time.Time, duration *time.Duration) error { +func (api *API) UpdateInstanceStats(t *time.Time, duration *time.Duration) error { insertQuery, _, err := goqu.Insert(goqu.T("instance_stats")). Cols("timestamp", "channel_name", "arch", "version", "instances"). FromQuery(api.instanceStatsQuery(t, duration)). diff --git a/backend/pkg/api/instances_test.go b/backend/pkg/api/instances_test.go index 296dc4d5f..be3e766c3 100644 --- a/backend/pkg/api/instances_test.go +++ b/backend/pkg/api/instances_test.go @@ -325,7 +325,7 @@ func TestUpdateInstanceStats(t *testing.T) { ts := time.Now().UTC() elapsed := ts.Sub(start) - err = a.updateInstanceStats(&ts, &elapsed) + err = a.UpdateInstanceStats(&ts, &elapsed) assert.NoError(t, err) instances, err = a.GetInstanceStats() @@ -354,7 +354,7 @@ func TestUpdateInstanceStats(t *testing.T) { ts3 := time.Now().UTC() elapsed = ts3.Sub(ts2) - err = a.updateInstanceStats(&ts3, &elapsed) + err = a.UpdateInstanceStats(&ts3, &elapsed) assert.NoError(t, err) instances, err = a.GetInstanceStats() @@ -387,7 +387,7 @@ func TestUpdateInstanceStatsNoArch(t *testing.T) { // Use large duration to have some test coverage for durationToInterval elapsed := 3*time.Hour + 45*time.Minute + 30*time.Second + 1000*time.Microsecond - err := a.updateInstanceStats(&ts, &elapsed) + err := a.UpdateInstanceStats(&ts, &elapsed) assert.NoError(t, err) instanceStats, err := a.GetInstanceStatsByTimestamp(ts) diff --git a/backend/pkg/server/server.go b/backend/pkg/server/server.go index df6f69825..5609bf6c9 100644 --- a/backend/pkg/server/server.go +++ b/backend/pkg/server/server.go @@ -7,6 +7,7 @@ import ( "net/url" "path" "strings" + "time" oapimiddleware "github.com/deepmap/oapi-codegen/pkg/middleware" "github.com/getkin/kin-openapi/openapi3filter" @@ -47,6 +48,7 @@ var ( ) // New takes the config and db connection to create the server and returns it. +// It also starts a background job to update instance stats periodically. func New(conf *config.Config, db *db.API) (*echo.Echo, error) { // Setup Echo Server e := echo.New() @@ -132,6 +134,24 @@ func New(conf *config.Config, db *db.API) (*echo.Echo, error) { e.DefaultHTTPErrorHandler(err, c) } codegen.RegisterHandlers(e, handlers) + + // setup background job for updating instance stats + go func() { + err := db.UpdateInstanceStats(nil, nil) + if err != nil { + logger.Err(err).Msg("Error updating instance stats") + } + ticker := time.NewTicker(db.GetDefaultInterval()) + defer ticker.Stop() + + for range ticker.C { + err := db.UpdateInstanceStats(nil, nil) + if err != nil { + logger.Err(err).Msg("Error updating instance stats") + } + } + }() + return e, nil }