Refactor settings handling to support context-based reloading and add utility functions for context management
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -554,7 +554,7 @@ func CreateTableReport(logger *slog.Logger, Database db.Database, ctx context.Co
|
|||||||
if err := db.ValidateTableName(tableName); err != nil {
|
if err := db.ValidateTableName(tableName); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
reportCfg := reloadReportSettingsForReport(logger, cfg)
|
reportCfg := reloadReportSettingsForReport(ctx, logger, cfg)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
logger.Debug("Create table report start", "table", tableName)
|
logger.Debug("Create table report start", "table", tableName)
|
||||||
|
|
||||||
@@ -792,13 +792,17 @@ func CreateTableReport(logger *slog.Logger, Database db.Database, ctx context.Co
|
|||||||
return buffer.Bytes(), nil
|
return buffer.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func reloadReportSettingsForReport(logger *slog.Logger, cfg *settings.Settings) *settings.Settings {
|
func reloadReportSettingsForReport(ctx context.Context, logger *slog.Logger, cfg *settings.Settings) *settings.Settings {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(cfg.SettingsPath) == "" {
|
if strings.TrimSpace(cfg.SettingsPath) == "" {
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
if settings.IsReloadedInContext(ctx, cfg) {
|
||||||
|
logger.Debug("settings already reloaded for current run; using in-memory settings", "settings_file", cfg.SettingsPath)
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
reloaded := settings.New(logger, cfg.SettingsPath)
|
reloaded := settings.New(logger, cfg.SettingsPath)
|
||||||
if err := reloaded.ReadYMLSettings(); err != nil {
|
if err := reloaded.ReadYMLSettings(); err != nil {
|
||||||
|
|||||||
28
internal/settings/context.go
Normal file
28
internal/settings/context.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package settings
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type reloadedContextKey struct{}
|
||||||
|
|
||||||
|
// MarkReloadedInContext marks that a given Settings instance has been refreshed in this context flow.
|
||||||
|
func MarkReloadedInContext(ctx context.Context, cfg *Settings) context.Context {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
if cfg == nil {
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
return context.WithValue(ctx, reloadedContextKey{}, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsReloadedInContext reports whether this context flow already refreshed the provided Settings.
|
||||||
|
func IsReloadedInContext(ctx context.Context, cfg *Settings) bool {
|
||||||
|
if ctx == nil || cfg == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
marked, ok := ctx.Value(reloadedContextKey{}).(*Settings)
|
||||||
|
if !ok || marked == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return marked == cfg
|
||||||
|
}
|
||||||
@@ -15,12 +15,17 @@ import (
|
|||||||
"vctp/db"
|
"vctp/db"
|
||||||
"vctp/internal/metrics"
|
"vctp/internal/metrics"
|
||||||
"vctp/internal/report"
|
"vctp/internal/report"
|
||||||
|
"vctp/internal/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunVcenterDailyAggregate summarizes hourly snapshots into a daily summary table.
|
// RunVcenterDailyAggregate summarizes hourly snapshots into a daily summary table.
|
||||||
func (c *CronTask) RunVcenterDailyAggregate(ctx context.Context, logger *slog.Logger) (err error) {
|
func (c *CronTask) RunVcenterDailyAggregate(ctx context.Context, logger *slog.Logger) (err error) {
|
||||||
jobTimeout := durationFromSeconds(c.Settings.Values.Settings.DailyJobTimeoutSeconds, 15*time.Minute)
|
jobTimeout := durationFromSeconds(c.Settings.Values.Settings.DailyJobTimeoutSeconds, 15*time.Minute)
|
||||||
return c.runAggregateJob(ctx, "daily_aggregate", jobTimeout, func(jobCtx context.Context) error {
|
return c.runAggregateJob(ctx, "daily_aggregate", jobTimeout, func(jobCtx context.Context) error {
|
||||||
|
if err := c.Settings.ReadYMLSettings(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jobCtx = settings.MarkReloadedInContext(jobCtx, c.Settings)
|
||||||
startedAt := time.Now()
|
startedAt := time.Now()
|
||||||
defer func() {
|
defer func() {
|
||||||
logger.Info("Daily summary job finished", "duration", time.Since(startedAt))
|
logger.Info("Daily summary job finished", "duration", time.Since(startedAt))
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"vctp/db/queries"
|
"vctp/db/queries"
|
||||||
"vctp/internal/metrics"
|
"vctp/internal/metrics"
|
||||||
"vctp/internal/report"
|
"vctp/internal/report"
|
||||||
|
"vctp/internal/settings"
|
||||||
"vctp/internal/utils"
|
"vctp/internal/utils"
|
||||||
"vctp/internal/vcenter"
|
"vctp/internal/vcenter"
|
||||||
|
|
||||||
@@ -116,8 +117,11 @@ func (c *CronTask) RunVcenterSnapshotHourly(ctx context.Context, logger *slog.Lo
|
|||||||
// Best-effort cleanup of legacy IsPresent columns to simplify inserts.
|
// Best-effort cleanup of legacy IsPresent columns to simplify inserts.
|
||||||
c.dropLegacyIsPresentColumns(jobCtx)
|
c.dropLegacyIsPresentColumns(jobCtx)
|
||||||
|
|
||||||
// reload settings in case vcenter list has changed
|
// Reload settings once for this run (for example, in case vCenter list has changed).
|
||||||
c.Settings.ReadYMLSettings()
|
if err := c.Settings.ReadYMLSettings(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ctx = settings.MarkReloadedInContext(ctx, c.Settings)
|
||||||
|
|
||||||
if c.FirstHourlySnapshotCheck {
|
if c.FirstHourlySnapshotCheck {
|
||||||
if err := report.EnsureSnapshotRegistry(ctx, c.Database); err != nil {
|
if err := report.EnsureSnapshotRegistry(ctx, c.Database); err != nil {
|
||||||
|
|||||||
@@ -14,12 +14,17 @@ import (
|
|||||||
"vctp/db"
|
"vctp/db"
|
||||||
"vctp/internal/metrics"
|
"vctp/internal/metrics"
|
||||||
"vctp/internal/report"
|
"vctp/internal/report"
|
||||||
|
"vctp/internal/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunVcenterMonthlyAggregate summarizes the previous month's daily snapshots.
|
// RunVcenterMonthlyAggregate summarizes the previous month's daily snapshots.
|
||||||
func (c *CronTask) RunVcenterMonthlyAggregate(ctx context.Context, logger *slog.Logger) (err error) {
|
func (c *CronTask) RunVcenterMonthlyAggregate(ctx context.Context, logger *slog.Logger) (err error) {
|
||||||
jobTimeout := durationFromSeconds(c.Settings.Values.Settings.MonthlyJobTimeoutSeconds, 20*time.Minute)
|
jobTimeout := durationFromSeconds(c.Settings.Values.Settings.MonthlyJobTimeoutSeconds, 20*time.Minute)
|
||||||
return c.runAggregateJob(ctx, "monthly_aggregate", jobTimeout, func(jobCtx context.Context) error {
|
return c.runAggregateJob(ctx, "monthly_aggregate", jobTimeout, func(jobCtx context.Context) error {
|
||||||
|
if err := c.Settings.ReadYMLSettings(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jobCtx = settings.MarkReloadedInContext(jobCtx, c.Settings)
|
||||||
startedAt := time.Now()
|
startedAt := time.Now()
|
||||||
defer func() {
|
defer func() {
|
||||||
logger.Info("Monthly summary job finished", "duration", time.Since(startedAt))
|
logger.Info("Monthly summary job finished", "duration", time.Since(startedAt))
|
||||||
|
|||||||
Reference in New Issue
Block a user