Documentation
¶
Overview ¶
Package nntpserver provides an in-process NNTP server that speaks enough of the wire protocol for a real *nntppool.Client to connect, authenticate, pipeline commands, and fetch yEnc article bodies.
It exists because the questions "how much does a STAT sweep cost a live stream" and "does the priority lane actually protect playback" cannot be answered with a client-level fake. Those behaviours live inside nntppool's per-connection scheduler — the shared inflight semaphore, the separate body semaphore, the priority/normal request channels, and the strict FIFO reply ordering of a single NNTP connection. internal/testsupport/fakepool replaces that scheduler wholesale, so it cannot observe any of it.
Wire fidelity ¶
The one property that matters is pipelining with in-order replies: a client may have many commands outstanding on one connection, the server may work on them concurrently, but responses MUST come back in the order the commands arrived. Each connection therefore runs a reader that enqueues a response future per command and a writer that drains those futures in order. Without this, head-of-line effects — a STAT queued behind a 750 KB body, a priority BODY queued behind a hundred STATs — silently disappear.
Timing model ¶
RTT (± jitter) is applied per command as time-to-first-byte, concurrently across the connection's outstanding commands. Body payload bytes are then written by the single writer goroutine at BandwidthPerConn, which models one wire shared by everything in flight on that connection.
All exported methods are safe for concurrent use.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// RTT is the time-to-first-byte applied to every command.
RTT time.Duration
// Jitter is the maximum symmetric deviation from RTT (uniform in
// [-Jitter, +Jitter]). Zero makes latency deterministic.
Jitter time.Duration
// BandwidthPerConn throttles body payload bytes per connection, in bytes
// per second. Zero disables the throttle.
BandwidthPerConn int64
// AggregateBandwidth caps total body payload bytes across ALL connections,
// in bytes per second. Zero disables it.
//
// Without this, N connections each throttled to R sum to N×R, which no real
// link does — and a harness that lets 100 connections reach 800 MB/s draws
// exactly the wrong conclusions about whether spending connections on
// latency costs throughput. Set it to the deployment's actual link rate.
AggregateBandwidth int64
// ArticleSize is the decoded size of the single article every BODY
// request returns.
ArticleSize int
// Missing is the set of message-ids answered with 430 instead of a hit.
// A nil map means every id exists.
Missing map[string]struct{}
// RequireAuth makes the server reject commands until AUTHINFO succeeds.
RequireAuth bool
}
Config describes the simulated provider.
type Counters ¶
type Counters struct {
Conns int64
Stats int64
StatMisses int64
Bodies int64
BytesWritten int64
PeakInflight int64 // highest number of concurrently-computing commands on any one connection
UnknownCmds int64
}
Counters is a snapshot of what the server has served.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a running fake NNTP provider.
func (*Server) ResetPeakInflight ¶
func (s *Server) ResetPeakInflight()
ResetPeakInflight zeroes the pipeline-depth high-water mark, so a benchmark can measure its own window rather than inheriting a warm-up burst.