timetable-extension #1
@ -3,9 +3,9 @@ package dbAccess
 | 
			
		||||
import (
 | 
			
		||||
	"git.fjla.uk/owlboard/timetable-mgr/helpers"
 | 
			
		||||
	"git.fjla.uk/owlboard/timetable-mgr/log"
 | 
			
		||||
	"go.uber.org/zap"
 | 
			
		||||
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.mongodb.org/mongo-driver/mongo"
 | 
			
		||||
@ -26,19 +26,43 @@ var bsonOpts = &options.BSONOptions{
 | 
			
		||||
	UseJSONStructTags: true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Initialise the DB Connection
 | 
			
		||||
func InitDataAccess(cfg *helpers.Configuration) {
 | 
			
		||||
	uri := getDbUri(cfg)
 | 
			
		||||
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 | 
			
		||||
	defer cancel()
 | 
			
		||||
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri).SetBSONOptions(bsonOpts))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println(err)
 | 
			
		||||
		log.Fatal("Error connecting to database: " + err.Error())
 | 
			
		||||
	} else {
 | 
			
		||||
		log.Info("Database connection initialising")
 | 
			
		||||
	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)
 | 
			
		||||
		defer cancel()
 | 
			
		||||
 | 
			
		||||
		client, err := mongo.Connect(ctx, options.Client().ApplyURI(url).SetBSONOptions(bsonOpts))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Warn("Error connecting to database", zap.Int("attempt", attempt), zap.Int("max-tries", maxRetries))
 | 
			
		||||
			cancel()
 | 
			
		||||
			if attempt != maxRetries {
 | 
			
		||||
				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
 | 
			
		||||
		log.Info("Database connection successful")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	MongoClient = client
 | 
			
		||||
 | 
			
		||||
	log.Fatal("Failed to connect to database on multiple attempts", zap.Int("attempts", maxRetries))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user