I have a long running daemon written in Go, that listens to a port and spins up multiple go routines for every new connection to handle the data. There is a global variable db
that is assigned connection context returned by database/sql
library's open()
function in the func main() of my script.
We store the db password in a vault which rotates it every couple of days for security reasons. I can fetch the password from the vault the first time it creates the connection context and the same context is used in all go routines for creating new db connections. However, when the password is rotated by the vault, all new db connections fail. I would like to know what is the best way of handling this so that it fetches the password from the vault on failure and reconnects. If it was an oop language, I could extend the db library and override the connection function to catch the error and fetch password from the vault on connection failure. Is there a similar approach that can be used in Go or are there any other way of handling this? I am very new to Go, and apologies if I have not framed the question right.
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"net"
)
var db *sql.DB
const port = "port number"
func main() {
db, err = sql.Open("mysql","<Connection string that contains the password fetched from vault>")
db.SetMaxOpenConns(100)
listener, err := net.Listen("tcp", ":"+port)
for {
conn, err := listener.Accept()
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
// Uses db variable to connect to db.
}