package handlers import ( "context" "database/sql" "time" "gitea.futuresens.co.uk/futuresens/hardlink/db" ) func (app *App) getDB(ctx context.Context) (*sql.DB, error) { app.dbMu.Lock() defer app.dbMu.Unlock() // Fast path: db exists and is alive if app.db != nil { pingCtx, cancel := context.WithTimeout(ctx, 1*time.Second) defer cancel() if err := app.db.PingContext(pingCtx); err == nil { return app.db, nil } // stale handle _ = app.db.Close() app.db = nil } // Reconnect once, bounded dialCtx, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() dbConn, err := db.InitMSSQL( app.cfg.Dbport, app.cfg.Dbuser, app.cfg.Dbpassword, app.cfg.Dbname, ) if err != nil { return nil, err } // Optional ping (InitMSSQL already pings, but this keeps semantics explicit) pingCtx, cancel2 := context.WithTimeout(dialCtx, 1*time.Second) defer cancel2() if err := dbConn.PingContext(pingCtx); err != nil { _ = dbConn.Close() return nil, err } app.db = dbConn return app.db, nil }