Close the database after web server is stopped.

Previously all of the shutdown tasks were running concurrently, which meant the db could be closed before the webserver is finished using it.
This commit is contained in:
jholdstock 2020-06-10 10:03:36 +01:00 committed by David Hill
parent 4f2766352b
commit a304fc9890
3 changed files with 21 additions and 27 deletions

View File

@ -42,11 +42,11 @@ var (
// a time.
var backupMtx sync.Mutex
func writeBackup(db *bolt.DB, dbFile string) error {
func writeBackup(db *bolt.DB) error {
backupMtx.Lock()
defer backupMtx.Unlock()
backupPath := dbFile + "-backup"
backupPath := db.Path() + "-backup"
tempPath := backupPath + "~"
// Write backup to temporary file.
@ -153,28 +153,6 @@ func Open(ctx context.Context, shutdownWg *sync.WaitGroup, dbFile string, backup
log.Debugf("Opened database file %s", dbFile)
// Add the graceful shutdown to the waitgroup.
shutdownWg.Add(1)
go func() {
// Wait until shutdown is signaled before shutting down.
<-ctx.Done()
log.Debug("Closing database...")
err := writeBackup(db, dbFile)
if err != nil {
log.Errorf("Failed to write database backup: %v", err)
}
err = db.Close()
if err != nil {
log.Errorf("Error closing database: %v", err)
} else {
log.Debug("Database closed")
}
shutdownWg.Done()
}()
// Start a ticker to update the backup file at the specified interval.
shutdownWg.Add(1)
go func() {
@ -182,7 +160,7 @@ func Open(ctx context.Context, shutdownWg *sync.WaitGroup, dbFile string, backup
for {
select {
case <-ticker.C:
err := writeBackup(db, dbFile)
err := writeBackup(db)
if err != nil {
log.Errorf("Failed to write database backup: %v", err)
}
@ -197,6 +175,20 @@ func Open(ctx context.Context, shutdownWg *sync.WaitGroup, dbFile string, backup
return &VspDatabase{db: db}, nil
}
func (vdb *VspDatabase) Close() {
err := writeBackup(vdb.db)
if err != nil {
log.Errorf("Failed to write database backup: %v", err)
}
err = vdb.db.Close()
if err != nil {
log.Errorf("Error closing database: %v", err)
} else {
log.Debug("Database closed")
}
}
func (vdb *VspDatabase) KeyPair() (ed25519.PrivateKey, ed25519.PublicKey, error) {
var seed []byte
err := vdb.db.View(func(tx *bolt.Tx) error {

View File

@ -56,6 +56,7 @@ func run(ctx context.Context) error {
shutdownWg.Wait()
return err
}
defer db.Close()
// Create RPC client for local dcrd instance (used for broadcasting and
// checking the status of fee transactions).
@ -91,7 +92,8 @@ func run(ctx context.Context) error {
// dcrd if the connection drops.
background.Start(ctx, db, dcrd, dcrdWithNotifs, wallets, cfg.netParams.Params)
// Wait for shutdown tasks to complete before returning.
// Wait for shutdown tasks to complete before running deferred tasks and
// returning.
shutdownWg.Wait()
return ctx.Err()

View File

@ -107,7 +107,7 @@ func Start(ctx context.Context, requestShutdownChan chan struct{}, shutdownWg *s
log.Debug("Stopping webserver...")
// Give the webserver 5 seconds to finish what it is doing.
timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
timeoutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(timeoutCtx); err != nil {
log.Errorf("Failed to stop webserver cleanly: %v", err)