Explorar el Código

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 <[email protected]>
Co-authored-by: Jakob Borg <[email protected]>
Tommy van der Vorst hace 3 días
padre
commit
5cf9168dc2
Se han modificado 3 ficheros con 33 adiciones y 9 borrados
  1. 6 1
      internal/db/interface.go
  2. 19 6
      internal/db/sqlite/db_service.go
  3. 8 2
      lib/syncthing/syncthing.go

+ 6 - 1
internal/db/interface.go

@@ -19,7 +19,12 @@ type DBService interface {
 	suture.Service
 
 	// 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 {

+ 19 - 6
internal/db/sqlite/db_service.go

@@ -39,7 +39,7 @@ type Service struct {
 	sdb                 *DB
 	maintenanceInterval time.Duration
 	internalMeta        *db.Typed
-	start               chan struct{}
+	start               chan chan error
 }
 
 func (s *Service) String() string {
@@ -51,15 +51,17 @@ func newService(sdb *DB, maintenanceInterval time.Duration) *Service {
 		sdb:                 sdb,
 		maintenanceInterval: maintenanceInterval,
 		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 {
-	case s.start <- struct{}{}:
+	case s.start <- finishChan:
 	default:
 	}
+	return finishChan
 }
 
 func (s *Service) Serve(ctx context.Context) error {
@@ -80,14 +82,20 @@ func (s *Service) Serve(ctx context.Context) error {
 	}
 
 	for {
+		var finishChan chan error
 		select {
 		case <-ctx.Done():
 			return ctx.Err()
 		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)
 		}
 
@@ -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 {
 	t0 := time.Now()
 	slog.DebugContext(ctx, "Periodic start")

+ 8 - 2
lib/syncthing/syncthing.go

@@ -116,8 +116,14 @@ func (a *App) Start() error {
 }
 
 // StartMaintenance asynchronously triggers database maintenance to start.
-func (a *App) StartMaintenance() {
-	a.dbService.StartMaintenance()
+func (a *App) StartMaintenance() <-chan error {
+	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 {