I am having some trouble figuring out how to make a database connection-attempt timeout properly in Go. I am using some of the examples at this excellent resource as a base. I believe I am setting up everything correctly, but my pings just refuse to time out after 2 seconds. I've extracted the code in question into a sample program as follows. Note that there is no database running at 172.1.2.3.
package main
import (
"context"
"database/sql"
_ "github.com/go-sql-driver/mysql" //MySQL driver
"log"
"time"
)
func main() {
log.Print("Trying to ping database!")
//Prepare a "context" to execute queries in, this will allow us to use timeouts
var bgCtx = context.Background()
var ctx2SecondTimeout, cancelFunc2SecondTimeout = context.WithTimeout(bgCtx, time.Second*2)
defer cancelFunc2SecondTimeout()
//Open database connection
db, err := sql.Open("mysql", "root:@tcp(172.1.2.3)/testdb?parseTime=true")
if err != nil {
log.Printf("Unable to open db, %s", err.Error())
return
}
log.Print("Successfully called open()")
//Ping database connection with 2 second timeout
err = db.PingContext(ctx2SecondTimeout)
if err != nil {
log.Printf("Can't ping database server in order to use storage, %s", err.Error())
return
}
log.Print("Successfully pinged database!")
}
Running the program should take up to about 2 seconds, but instead it takes 2+ minutes:
$ go run lambdatry.go
2018/09/03 16:33:33 Trying to ping database!
2018/09/03 16:33:33 Successfully called open()
2018/09/03 16:35:43 Can't ping database server in order to use storage, dial tcp 172.1.2.3:3306: connect: connection timed out
If I change the IP of the "database" (I just picked a random IP so there's no database at this address) the database sometimes times out immediately and sometimes takes a really long time to timeout.
I am running go 1.10.1 on ubuntu 18.04.