chore(db): add ability to wait for programmatically started database maintenance, query last maintenance time (#10565)
Also adds a method to query the last database maintenance time. Signed-off-by: Tommy van der Vorst <tommy@pixelspark.nl> Co-authored-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
co-authored by
Jakob Borg
parent
0b5a08c99a
commit
5cf9168dc2
@@ -19,7 +19,12 @@ type DBService interface {
|
|||||||
suture.Service
|
suture.Service
|
||||||
|
|
||||||
// Starts maintenance asynchronously, if not already running
|
// Starts maintenance asynchronously, if not already running
|
||||||
StartMaintenance()
|
// Returns a channel that will receive the result when the requested maintenance finishes
|
||||||
|
StartMaintenance() <-chan error
|
||||||
|
|
||||||
|
// Returns the last time database maintenance completed
|
||||||
|
// This will return time zero when database maintenance has never completed successfully.
|
||||||
|
LastMaintenanceTime() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB interface {
|
type DB interface {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type Service struct {
|
|||||||
sdb *DB
|
sdb *DB
|
||||||
maintenanceInterval time.Duration
|
maintenanceInterval time.Duration
|
||||||
internalMeta *db.Typed
|
internalMeta *db.Typed
|
||||||
start chan struct{}
|
start chan chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) String() string {
|
func (s *Service) String() string {
|
||||||
@@ -51,15 +51,17 @@ func newService(sdb *DB, maintenanceInterval time.Duration) *Service {
|
|||||||
sdb: sdb,
|
sdb: sdb,
|
||||||
maintenanceInterval: maintenanceInterval,
|
maintenanceInterval: maintenanceInterval,
|
||||||
internalMeta: db.NewTyped(sdb, internalMetaPrefix),
|
internalMeta: db.NewTyped(sdb, internalMetaPrefix),
|
||||||
start: make(chan struct{}),
|
start: make(chan chan error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) StartMaintenance() {
|
func (s *Service) StartMaintenance() <-chan error {
|
||||||
|
finishChan := make(chan error, 1)
|
||||||
select {
|
select {
|
||||||
case s.start <- struct{}{}:
|
case s.start <- finishChan:
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
return finishChan
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Serve(ctx context.Context) error {
|
func (s *Service) Serve(ctx context.Context) error {
|
||||||
@@ -80,14 +82,20 @@ func (s *Service) Serve(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
var finishChan chan error
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
case <-s.start:
|
case finishChan = <-s.start:
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.periodic(ctx); err != nil {
|
err := s.periodic(ctx)
|
||||||
|
if finishChan != nil {
|
||||||
|
finishChan <- err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
return wrap(err)
|
return wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +108,11 @@ func (s *Service) Serve(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) LastMaintenanceTime() time.Time {
|
||||||
|
lastMaint, _, _ := s.internalMeta.Time(lastMaintKey)
|
||||||
|
return lastMaint
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) periodic(ctx context.Context) error {
|
func (s *Service) periodic(ctx context.Context) error {
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
slog.DebugContext(ctx, "Periodic start")
|
slog.DebugContext(ctx, "Periodic start")
|
||||||
|
|||||||
@@ -116,8 +116,14 @@ func (a *App) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StartMaintenance asynchronously triggers database maintenance to start.
|
// StartMaintenance asynchronously triggers database maintenance to start.
|
||||||
func (a *App) StartMaintenance() {
|
func (a *App) StartMaintenance() <-chan error {
|
||||||
a.dbService.StartMaintenance()
|
return a.dbService.StartMaintenance()
|
||||||
|
}
|
||||||
|
|
||||||
|
// LastMaintenanceTime returns the last time database maintenance completed successfully
|
||||||
|
// This will return time zero when database maintenance has never completed successfully.
|
||||||
|
func (a *App) LastMaintenanceTime() time.Time {
|
||||||
|
return a.dbService.LastMaintenanceTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) startup() error {
|
func (a *App) startup() error {
|
||||||
|
|||||||
Reference in New Issue
Block a user