-
-
Save blinsay/044f39176eeab7f3020d1b527df5bdd7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"database/sql" | |
"flag" | |
"fmt" | |
"log" | |
"sync" | |
"time" | |
_ "github.com/lib/pq" | |
) | |
var jitter = flag.Int("jitter-ms", 10, "jitter in millis") | |
var timeout = flag.Int("timeout-ms", 1000, "query timeout in millis") | |
var reps = flag.Int("reps", 100, "number of times the query is made") | |
func main() { | |
flag.Parse() | |
query := fmt.Sprintf(`SELECT pg_sleep_for('%d ms') || 'a string to return'`, *timeout) | |
fmt.Println(query) | |
var timeouts []time.Duration | |
for i := 0; i < *jitter*1000; i++ { | |
millis := time.Duration(*timeout-i) * time.Millisecond | |
for j := 0; j < 100; j++ { | |
timeouts = append(timeouts, millis-(time.Duration(j)*10*time.Microsecond)) | |
} | |
} | |
db, openErr := openAndPing("postgres", "postgres:///pq_test?sslmode=disable") | |
if openErr != nil { | |
log.Fatalf("failed to open a connection: %s", openErr) | |
} | |
_, createErr := db.Exec(`CREATE TABLE IF NOT EXISTS test (something text)`) | |
if createErr != nil { | |
log.Fatalf("failed to create table: %s", createErr) | |
} | |
for _, timeout := range timeouts { | |
wg := sync.WaitGroup{} | |
for i := 0; i < *reps; i++ { | |
wg.Add(1) | |
go func(rep int, timeout time.Duration) { | |
defer wg.Done() | |
ctx, cancel := context.WithTimeout(context.Background(), timeout) | |
defer cancel() | |
tx, err := db.BeginTx(ctx, nil) | |
if err != nil { | |
log.Printf("timeout=%.08fs rep=%d status=error error=%q", timeout.Seconds(), rep, err) | |
return | |
} | |
var result string | |
if err := tx.QueryRowContext(ctx, query).Scan(&result); err != nil { | |
log.Printf("timeout=%.08fs rep=%d status=error error=%q", timeout.Seconds(), rep, err) | |
} else { | |
log.Printf("timeout=%.08fs rep=%d status=ok", timeout.Seconds(), rep) | |
} | |
}(i, timeout) | |
} | |
wg.Wait() | |
time.Sleep(1 * time.Second) | |
} | |
} | |
func openAndPing(driver, source string) (*sql.DB, error) { | |
db, err := sql.Open("postgres", "postgres:///pq_test?sslmode=disable") | |
if err != nil { | |
return nil, err | |
} | |
if err := db.Ping(); err != nil { | |
return nil, err | |
} | |
return db, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment