timetable-extension #1
@ -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
18
helpers/backoff.go
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user