check / check (push) Successful in 4m39s
`ptr` keeps its field and shape. It now comes from Google, Cloudflare, AdGuard and Quad9 over RFC 8484, tried in turn within 2 seconds, in place of the host's resolver with no cache. Answers stay in memory and in a new `cache.db` for the record's TTL, at most 250,000 addresses. A reserved address is not sent to any resolver and has an empty `ptr`. Judgement call: each resolver gets an equal share of the time left, so a hung one does not use up the limit. Judgement call: the negative TTL is the smaller of the SOA minimum and the SOA's own TTL. Deviation: the cache is SQLite, by sneak's words, not the JSON file the standing rule asks for. Model: opus-5-5
52 lines
1.3 KiB
Go
52 lines
1.3 KiB
Go
// Package cachedb opens cache.db, the SQLite file in the state directory that
|
|
// holds RouteWatch's caches of answers from outside services. It is separate
|
|
// from the routes database so that a cache write never queues behind a write
|
|
// to that database.
|
|
package cachedb
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
_ "embed" // for schema.sql
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
_ "github.com/mattn/go-sqlite3" // CGO SQLite driver
|
|
)
|
|
|
|
const (
|
|
// fileName is the database's file in the state directory.
|
|
fileName = "cache.db"
|
|
|
|
// busyTimeoutMs is how long a write waits for another write to finish.
|
|
busyTimeoutMs = 5000
|
|
)
|
|
|
|
//go:embed schema.sql
|
|
var schema string
|
|
|
|
// Open opens cache.db in stateDir, creating the file and its tables when they
|
|
// do not exist. The caller closes the database.
|
|
func Open(ctx context.Context, stateDir string) (*sql.DB, error) {
|
|
dsn := fmt.Sprintf(
|
|
"file:%s?_journal_mode=WAL&_synchronous=NORMAL&_busy_timeout=%d"+
|
|
"&_txlock=immediate",
|
|
filepath.Join(stateDir, fileName),
|
|
busyTimeoutMs,
|
|
)
|
|
|
|
db, err := sql.Open("sqlite3", dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("opening the cache database: %w", err)
|
|
}
|
|
|
|
_, err = db.ExecContext(ctx, schema)
|
|
if err != nil {
|
|
_ = db.Close()
|
|
|
|
return nil, fmt.Errorf("creating the cache database's tables: %w", err)
|
|
}
|
|
|
|
return db, nil
|
|
}
|