Skip to content

Commit ef9232f

Browse files
committed
Avoid isolation issues
1 parent efd0ad6 commit ef9232f

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

www/db.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"database/sql"
5+
"fmt"
56
"time"
67

78
_ "github.com/mattn/go-sqlite3"
@@ -44,11 +45,23 @@ type ResolverStats struct {
4445
}
4546

4647
func NewDB(path string) (*DB, error) {
47-
db, err := sql.Open("sqlite3", path+"?_journal_mode=WAL&_busy_timeout=5000")
48+
db, err := sql.Open("sqlite3", path+"?_journal_mode=WAL&_busy_timeout=5000&_synchronous=NORMAL")
4849
if err != nil {
4950
return nil, err
5051
}
5152

53+
// Use a single connection to avoid WAL snapshot isolation issues.
54+
// With multiple connections, readers can see stale data because each
55+
// connection may hold an old snapshot of the WAL. A single connection
56+
// ensures all reads see the latest committed writes.
57+
db.SetMaxOpenConns(1)
58+
59+
// Verify connection works
60+
if err := db.Ping(); err != nil {
61+
db.Close()
62+
return nil, fmt.Errorf("failed to ping database: %w", err)
63+
}
64+
5265
if err := createTables(db); err != nil {
5366
db.Close()
5467
return nil, err
@@ -111,11 +124,19 @@ func (d *DB) UpsertResolver(name, typ, description, sourceFile string) (int64, e
111124
}
112125

113126
func (d *DB) RecordTest(resolverID int64, stamp string, success bool, rttMs int64, errMsg string) error {
114-
_, err := d.db.Exec(`
127+
result, err := d.db.Exec(`
115128
INSERT INTO test_results (resolver_id, stamp, success, rtt_ms, error)
116129
VALUES (?, ?, ?, ?, ?)
117130
`, resolverID, stamp, success, rttMs, errMsg)
118-
return err
131+
if err != nil {
132+
return err
133+
}
134+
// Verify the insert actually happened
135+
rows, _ := result.RowsAffected()
136+
if rows == 0 {
137+
return fmt.Errorf("no rows inserted for resolver %d", resolverID)
138+
}
139+
return nil
119140
}
120141

121142
func (d *DB) GetAllStats() ([]ResolverStats, error) {
@@ -251,3 +272,18 @@ func (d *DB) RemoveStaleResolvers(noSuccessSince time.Duration) ([]string, error
251272

252273
return names, nil
253274
}
275+
276+
// GetTestCount returns the total number of test results and the timestamp of the most recent one
277+
func (d *DB) GetTestCount() (count int64, lastTest time.Time, err error) {
278+
var lastTestStr sql.NullString
279+
err = d.db.QueryRow(`
280+
SELECT COUNT(*), MAX(tested_at) FROM test_results
281+
`).Scan(&count, &lastTestStr)
282+
if err != nil {
283+
return 0, time.Time{}, err
284+
}
285+
if lastTestStr.Valid {
286+
lastTest, _ = time.Parse("2006-01-02 15:04:05", lastTestStr.String)
287+
}
288+
return count, lastTest, nil
289+
}

www/main.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ func main() {
3131
tester := NewTester(db, *concurrency, *timeout)
3232

3333
runTests := func() {
34+
startTime := time.Now()
35+
log.Printf("Starting test run at %s", startTime.Format(time.RFC3339))
36+
3437
resolvers, err := parser.ParseAll()
3538
if err != nil {
3639
log.Printf("Failed to parse resolvers: %v", err)
@@ -45,6 +48,16 @@ func main() {
4548
} else if len(removed) > 0 {
4649
log.Printf("Removed %d stale resolvers: %v", len(removed), removed)
4750
}
51+
52+
// Log database state after test run
53+
count, lastTest, err := db.GetTestCount()
54+
if err != nil {
55+
log.Printf("Failed to get test count: %v", err)
56+
} else {
57+
log.Printf("Database: %d total tests, last at %s", count, lastTest.Format(time.RFC3339))
58+
}
59+
60+
log.Printf("Test run completed in %v", time.Since(startTime))
4861
}
4962

5063
if *runOnce {

www/tester.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (t *Tester) TestAll(resolvers []Resolver) {
121121
close(results)
122122
}()
123123

124-
successCount, failCount := 0, 0
124+
successCount, failCount, recordErrors := 0, 0, 0
125125

126126
for result := range results {
127127
if result.ResolverID == 0 {
@@ -137,6 +137,7 @@ func (t *Tester) TestAll(resolvers []Resolver) {
137137
err := t.db.RecordTest(result.ResolverID, result.Stamp, result.Success, result.RTT.Milliseconds(), errMsg)
138138
if err != nil {
139139
log.Printf("Failed to record test result: %v", err)
140+
recordErrors++
140141
}
141142

142143
if result.Success {
@@ -146,7 +147,7 @@ func (t *Tester) TestAll(resolvers []Resolver) {
146147
}
147148
}
148149

149-
log.Printf("Test completed: %d success, %d failed", successCount, failCount)
150+
log.Printf("Test completed: %d success, %d failed, %d record errors", successCount, failCount, recordErrors)
150151
}
151152

152153
func (t *Tester) testOne(job TestJob) TestJobResult {

0 commit comments

Comments
 (0)