Documentation
¶
Index ¶
- Constants
- Variables
- func Audit(ctx context.Context, dbPath string, trace map[string]TraceRecord, w io.Writer) error
- func AuditPostgres(ctx context.Context, url string, trace map[string]TraceRecord, w io.Writer) error
- func Generate(ctx context.Context, db *sql.DB, s Scale, now time.Time) error
- func WriteReport(w io.Writer, title string, meta []string, rows []*Row) (failed int)
- type BackgroundWriter
- type Budget
- type Client
- type Result
- type Row
- type Runner
- type Scale
- type Step
- type TraceRecord
- type Viewer
Constants ¶
const Password = "etherperf-password"
Credentials minted into the throwaway copy. Every viewer signs in with Password through the real protocol sign-in routes; Plex and the owner console use a minted Plex token; Stremio uses a minted surface grant.
const RestrictedViewer = 2
RestrictedViewer is the fixture viewer with a rating cap and a plex.tv share filter, so restricted listings are measured on a full library.
Variables ¶
var Budgets = map[string]Budget{ // contains filtered or unexported fields }
var LargeScale = Scale{Movies: 250_000, Shows: 10_000, SeasonsPerShow: 4, EpisodesPerSeason: 6, Viewers: 2, HistoryPerViewer: 20_000, InProgressPerViewer: 40}
LargeScale is the CI gate's library: 500k+ catalogue rows and a household with deep watch history.
var SmallScale = LargeScale.Divide(10)
SmallScale is LargeScale's household over a tenth of its library; the gate compares the two, so only the library differs.
Functions ¶
func Audit ¶
audit runs EXPLAIN QUERY PLAN for every statement the trace attributes to a request and ranks them by the time they cost, flagging full scans of large tables, temporary sort trees, automatic indexes, correlated subqueries and statements repeated within one request.
func AuditPostgres ¶
func AuditPostgres(ctx context.Context, url string, trace map[string]TraceRecord, w io.Writer) error
AuditPostgres audits the same statements against a PostgreSQL database (a cluster node's, or a copy of one) with EXPLAIN (GENERIC_PLAN), which plans a parameterized statement without values (PostgreSQL 16+). It flags sequential scans of large tables, sorts and correlated subplans.
Types ¶
type BackgroundWriter ¶
type BackgroundWriter struct {
// contains filtered or unexported fields
}
backgroundWriter imitates a catalogue refresh against the same database: write transactions of 500 title rows, back to back with a short pause, so request paths meet a busy writer the way they do while the mirror syncs.
func StartBackgroundWriter ¶
func StartBackgroundWriter(dbPath string) (*BackgroundWriter, error)
func (*BackgroundWriter) Close ¶
func (w *BackgroundWriter) Close() string
type Budget ¶
budget is the latency a class must meet: p95 of the warm phase, the single cold request, and p95 under concurrent viewers or a busy writer.
type Client ¶
type Client struct {
Name string
Surface string
// Port offset from the base port (0 main, 1 Jellyfin, 2 Emby, 3 Silo),
// or SharedPrefix on the main port when the runner shares one port.
Port int
Prefix string
Headers func(s *session) http.Header
SignIn *Step
Steps []Step
}
client is one real client's request sequence against one protocol.
type Result ¶
type Result struct {
Phase string `json:"phase"`
Client string `json:"client"`
Surface string `json:"surface"`
Step string `json:"step"`
Class string `json:"class"`
Viewer string `json:"viewer"`
Tag string `json:"tag"`
Status int `json:"status"`
Bytes int `json:"bytes"`
Dur time.Duration `json:"dur"`
Err string `json:"err,omitempty"`
Skipped string `json:"skipped,omitempty"`
}
result is one timed request.
type Row ¶
type Row struct {
Client, Step, Class string
RowsBound int
Cold, WarmP50, WarmP95, ConcP95, BgP95 time.Duration
Queries, Writes, Rows int64
// The fewest and most statements and rows over the cold and warm
// passes. A pass may or may not be answered by a cache, so the gate
// compares the large library's least work with the small one's most.
QueriesMin, QueriesMax, RowsMin, RowsMax int64
DBTime, LockWait time.Duration
Status string
Fails []string
Skipped string
Errors []string
// contains filtered or unexported fields
}
row is one endpoint's line in the report.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
func NewRunner ¶
NewRunner drives a server whose main port is basePort. With shared set, Jellyfin, Emby and Silo are reached under their path prefixes on that port; otherwise on basePort+1, +2 and +3.
func (*Runner) Concurrent ¶
concurrent runs n workers, each a viewer working through every client in its own order, rounds times.
func (*Runner) Sequential ¶
sequential runs every client for each viewer, one request at a time.
func (*Runner) SetTimeout ¶
SetTimeout caps each request (60 s by default).
type Scale ¶
type Scale struct {
Movies int
Shows int
SeasonsPerShow int
EpisodesPerSeason int
// Viewers beyond the owner, each with HistoryPerViewer watched titles
// and InProgressPerViewer partly watched ones.
Viewers int
HistoryPerViewer int
InProgressPerViewer int
}
Scale sizes a synthetic library. Every title is browsable, detailed and fresh, so a request never needs TMDB: the fixture measures Ether, not a provider.
type Step ¶
type Step struct {
Name string
Class string
// RowsBound, when set, is a hard bound on the rows the step reads,
// whatever the library's size: a search reads at most its candidate
// window, so its rows grow with the matches only until the window
// fills. The gate checks the bound instead of comparing scales.
RowsBound int
Method string
Path string
Body string
Discover func(vars map[string]string, body []byte)
}
type TraceRecord ¶
type TraceRecord struct {
Tag string `json:"tag"`
Surface string `json:"surface"`
Method string `json:"method"`
Path string `json:"path"`
Status int `json:"status"`
Duration time.Duration `json:"duration"`
Queries int64 `json:"queries"`
Writes int64 `json:"writes"`
Rows int64 `json:"rows"`
DBTime time.Duration `json:"dbTime"`
LockWait time.Duration `json:"lockWait"`
Statements []statementStat `json:"statements"`
}
traceRecord mirrors app.PerfTraceRecord (one line of ETHER_PERF_TRACE).
func ReadTrace ¶
func ReadTrace(path string) (map[string]TraceRecord, []TraceRecord, error)