Added multiple attempts with backoff delay to datebase connection

This commit is contained in:
Fred Boniface 2024-04-14 21:21:13 +01:00
parent 86da330b91
commit f97bea78eb
2 changed files with 54 additions and 12 deletions

View File

@ -3,9 +3,9 @@ package dbAccess
import ( import (
"git.fjla.uk/owlboard/timetable-mgr/helpers" "git.fjla.uk/owlboard/timetable-mgr/helpers"
"git.fjla.uk/owlboard/timetable-mgr/log" "git.fjla.uk/owlboard/timetable-mgr/log"
"go.uber.org/zap"
"context" "context"
"fmt"
"time" "time"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
@ -26,19 +26,43 @@ var bsonOpts = &options.BSONOptions{
UseJSONStructTags: true, UseJSONStructTags: true,
} }
// Initialise the DB Connection
func InitDataAccess(cfg *helpers.Configuration) { func InitDataAccess(cfg *helpers.Configuration) {
uri := getDbUri(cfg) log.Debug("Starting database connection")
url := getDbUri(cfg)
const maxRetries = 8
for attempt := 1; attempt <= maxRetries; attempt++ {
log.Info("Attempting to connect to database", zap.Int("attempt", attempt), zap.Int("max-tries", maxRetries))
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri).SetBSONOptions(bsonOpts))
client, err := mongo.Connect(ctx, options.Client().ApplyURI(url).SetBSONOptions(bsonOpts))
if err != nil { if err != nil {
fmt.Println(err) log.Warn("Error connecting to database", zap.Int("attempt", attempt), zap.Int("max-tries", maxRetries))
log.Fatal("Error connecting to database: " + err.Error()) cancel()
} else { if attempt != maxRetries {
log.Info("Database connection initialising") helpers.BackoffDelay(attempt)
} }
continue
}
err = client.Ping(ctx, nil)
if err != nil {
log.Warn("Error pinging database", zap.Int("attempt", attempt), zap.Int("max-tries", maxRetries))
cancel()
if attempt != maxRetries {
helpers.BackoffDelay(attempt)
}
continue
}
MongoClient = client MongoClient = client
log.Info("Database connection successful")
return
}
log.Fatal("Failed to connect to database on multiple attempts", zap.Int("attempts", maxRetries))
} }
// Closes the connection to the database - used for cleanup functions // Closes the connection to the database - used for cleanup functions

18
helpers/backoff.go Normal file
View File

@ -0,0 +1,18 @@
package helpers
import (
"math"
"time"
"git.fjla.uk/owlboard/timetable-mgr/log"
"go.uber.org/zap"
)
// Implements an exponential backoff strategy and sleeps for a duration calculated as 1 second to the power of (attempt - 1).
// The backoff time doubles with each attempt, starting from 1 second for the first attempt.
func BackoffDelay(attempt int) {
base := time.Second
backoff := base * time.Duration(math.Pow(2, float64(attempt-1)))
log.Info("Retry backoff", zap.Duration("delay", backoff))
time.Sleep(backoff)
}