Skip to content

Instantly share code, notes, and snippets.

@bgentry
Created April 12, 2012 04:42
Show Gist options
  • Save bgentry/2364641 to your computer and use it in GitHub Desktop.
Save bgentry/2364641 to your computer and use it in GitHub Desktop.
dbsqlconnfail: pq or database/sql ErrBadConn unhealthy connection reuse
$ go install
$ dbsqlconnfail

In another window:

$ curl localhost:8080/1
OK
$ # kill postgres, let it restart
$ curl localhost:8080/1
FAIL

Restart postgres + dbsqlconnfail, then:

$ curl localhost:8080/2
OK
$ # kill postgres, let it restart
$ curl localhost:8080/2
OK
package main
import (
"database/sql"
"fmt"
"github.com/bmizerany/pq"
"net/http"
)
func main() {
opendb("postgres://bgentry:@localhost:5432/maestro")
http.HandleFunc("/1", func(w http.ResponseWriter, r *http.Request) {
response(w, TestDbConnection1())
})
http.HandleFunc("/2", func (w http.ResponseWriter, r *http.Request) {
response(w, TestDbConnection2())
})
switch {
case !TestDbConnection1(): panic("failed test 1")
case !TestDbConnection2(): panic("failed test 2")
}
http.ListenAndServe(":8080", nil)
}
var pg *sql.DB
func opendb(databaseURL string) {
cs, err := pq.ParseURL(databaseURL)
if err != nil {
fmt.Printf("fatal database_url_parse_error error=%v\n", err.Error())
}
cs += " sslmode=disable"
pg, err = sql.Open("postgres", cs)
if err != nil {
fmt.Printf("fatal database_connection_error error=%v\n", err.Error())
}
}
func response(w http.ResponseWriter, result bool) {
if result {
w.Write([]byte("OK\n"))
} else {
w.WriteHeader(500)
w.Write([]byte("FAIL\n"))
}
}
func TestDbConnection1() bool {
var r int
err := pg.QueryRow("SELECT 1").Scan(&r)
return handleConnTest(r, err)
}
func TestDbConnection2() bool {
var r int
rows, err := pg.Query("SELECT 1")
if err != nil {
fmt.Printf("Error during test query: %v\n", err)
return false
}
rows.Next()
err = rows.Scan(&r)
if err != nil {
fmt.Printf("Error during test scan: %v\n", err)
return false
}
return handleConnTest(r, err)
}
func handleConnTest(r int, err error) bool {
switch {
case err != nil:
fmt.Printf("error db_connection_test_failure error=%v\n", err.Error())
return false
case r != 1:
fmt.Printf("error db_connection_test_failure error=%v\n", fmt.Sprintf("query returned %v", r))
return false
}
return true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment