package main
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"sync"
"time"
)
// Untimed diagnostic: samples backend waits while a write-bearing endpoint runs.
// It is not a benchmark and its polling overhead must not enter performance claims.
func diagnoseWaits(ctx context.Context, dsn, url, output string, n, concurrency int) error {
c, err := openDB(ctx, dsn)
if err != nil {
return err
}
defer c.Close(ctx)
if err = fixture(ctx, c); err != nil {
return err
}
done := make(chan []float64, 1)
client := &http.Client{Timeout: 10 * time.Second}
go func() {
durations := make([]float64, n)
jobs := make(chan int)
var wg sync.WaitGroup
for range concurrency {
wg.Add(1)
go func() {
defer wg.Done()
for i := range jobs {
start := time.Now()
resp, err := client.Get(url + "/api/posts/1")
if err == nil {
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
}
durations[i] = float64(time.Since(start)) / 1e6
}
}()
}
for i := 0; i < n; i++ {
jobs <- i
}
close(jobs)
wg.Wait()
done <- durations
}()
counts := map[string]int{}
ticker := time.NewTicker(5 * time.Millisecond)
defer ticker.Stop()
for {
select {
case durations := <-done:
if err = os.MkdirAll(filepath.Dir(output), 0755); err != nil {
return err
}
raw, _ := json.MarshalIndent(map[string]any{"diagnostic_only": true, "wait_samples": counts, "latencies_ms": durations}, "", " ")
if err = os.WriteFile(output, append(raw, '\n'), 0644); err != nil {
return err
}
fmt.Println(counts)
return nil
case <-ticker.C:
rows, err := c.Query(ctx, `SELECT coalesce(wait_event_type,'CPU'),coalesce(wait_event,'running') FROM pg_stat_activity WHERE datname=current_database() AND pid<>pg_backend_pid() AND state='active'`)
if err != nil {
return err
}
for rows.Next() {
var kind, event string
rows.Scan(&kind, &event)
counts[kind+":"+event]++
}
err = rows.Err()
rows.Close()
if err != nil {
return err
}
}
}
}