driver

package
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package driver plays the world outside the sprint table, on a tick: workers taking and finishing work cards, readers reporting read cards, each stream's merge step with its facts, and fleet members going down and up. The mechanical moves are the machine's (nova-sprint run): the driver plays only the outside actors, and refuses to play while no machine is running. It has no access of its own to the core or the store: everything it does is a nova-sprint verb run through the command's own entry point with an argument list, and everything it knows it reads from the read verbs' --json output. It never runs the coordinator's verbs (accept, rework, drop, rank, resume, return, start, stop) nor the machine's (tick, run); it keeps playing while things wait for the coordinator, says what waits and for how long, and stops when every stream has landed.

Index

Constants

View Source
const DefaultWidth = 64

DefaultWidth is the work cards a member takes a tick when the view shows no width for it.

View Source
const Most = 2000

Most is the cards one batched verb names: the table layer's bound of IDs in an entry and in a log line. A batch larger than this is cut at it; the rest wait a tick.

View Source
const ReadUsage = "input=1000 output=100"

ReadUsage is the token report every reader of the played world gives with its verdict (read --usage): a read is priced as work is, and a routed read's verdict with no usage is no verdict (sprint.ReadUsageMissing).

Variables

View Source
var Aliases = map[string][]string{"flap": {"down", "up"}}

Aliases are flags that set several chances at once, unless the chance is named itself: --flap is --down and --up with the one chance.

View Source
var ChanceRows = []Chance{
	{"broken", 0.05, 0.10, "the chance a read finds the work broken", func(c *Chances) *float64 { return &c.Broken }},
	{"fail", 0.10, 0.10, "the chance a work card comes back failed", func(c *Chances) *float64 { return &c.Fail }},
	{"stuck", 0.10, 0.10, "the chance a batch has a card that does not merge", func(c *Chances) *float64 { return &c.Stuck }},
	{"cross", 0.01, 0.01, "the chance a batch has a card that needs a card of another stream first", func(c *Chances) *float64 { return &c.Cross }},
	{"down", 0, 0.01, "the chance, per member and second, that a member's machine that is up goes down (stops beating)", func(c *Chances) *float64 { return &c.Down }},
	{"up", 0, 0.10, "the chance, per member and second, that a member's machine that is down comes back (beats again)", func(c *Chances) *float64 { return &c.Up }},
}

ChanceRows are the six chances, one row each, in the order the simulation names them. The locked column is the owner's: a change to the simulation is a change to a row here, and the flags, the help and the tests follow it.

Functions

func PerTick

func PerTick(p float64, every time.Duration) float64

PerTick is the chance a tick of every draws against, given a chance p each second: the chance of at least one such event in that much time, and p itself at one second, and for a tick of no time. The length of a tick is the configured every, not the time that passes between two draws.

func Valid

func Valid(flag string, p float64) error

Valid is nil for a chance from 0 to 1, and a refusal naming the flag for anything else (a number outside it, or not a number).

Types

type Chance

type Chance struct {
	Flag   string
	Plain  float64
	Locked float64
	Usage  string
	At     func(*Chances) *float64
}

Chance is one row of the table of chances: the flag that sets it, its value when a run is not a simulation, its locked value under --simulation, what the flag says, and where the chance is kept.

type Chances

type Chances struct {
	Broken, Fail, Stuck, Cross, Down, Up float64
}

Chances are the six chances the seeded facts draw against, each a probability from 0 to 1. Broken and Fail are per report, drawn each time a card is reported, so a card reworked and reported again draws again (a reader finds the work broken; work comes back not ok from the fleet), Stuck and Cross are per merge batch (a merge needs help from the coordinator within its stream; across streams), Down and Up are per member and second (a machine that is up goes down; one that is down comes back).

func Set

func Set(simulation bool, given map[string]float64) (Chances, error)

Set is the chances of a run: each row at its plain value, or at its locked value when simulating, then each flag the person gave, whatever it is (a chance of 0 given is 0). given holds the chances named on the command line by flag name; a chance outside 0 to 1 is refused, naming its flag.

func (Chances) String

func (c Chances) String() string

String is the chances as flags, in the order of the table, each to six significant digits (a chance made from a second's chance by PerTick does not print its last digits of rounding).

type Clock

type Clock interface {
	Now() time.Time
	Sleep(time.Duration)
}

Clock is the driver's time: read, and slept on between ticks.

type Config

type Config struct {
	Every time.Duration // between ticks
	Batch int           // a merge step's batch
	// TakeLimit is the work cards a member takes in its one take of a tick;
	// 0 is the member's width, as the view shows it, else DefaultWidth.
	TakeLimit int
	// ReadLimit is the read cards a reader begins, and reports, in its one
	// call of each a tick; 0 is its whole queue. Every batch is cut at Most.
	ReadLimit int
	Ticks     int // stop after this many ticks; 0 is until every stream lands
	// Hold plays the facts' downs as the coordinator's hold (fleet down and
	// fleet up); without it a member the facts take down falls silent (its
	// machine stops beating), takes no work while it is down, and comes back
	// by beating again and taking work again.
	Hold bool
	// Silent is members silent for a while: each stops beating From after
	// the driver starts, for For.
	Silent []Silence
}

Config is how the driver plays.

type Driver

type Driver struct {
	Run    func(args []string, stdout, stderr io.Writer) int
	Base   []string
	Facts  Facts
	Clock  Clock
	Out    io.Writer
	Config Config
	// Header is a line Loop prints once, before its first tick, when it has
	// read that it may play; a Loop that refuses to play prints nothing.
	Header string
	// contains filtered or unexported fields
}

Driver runs the loop. Run is the command's entry point; Base is the flags every verb it runs gets (the store), and they are printed with each command line so the line can be typed by hand.

func (*Driver) Loop

func (d *Driver) Loop() (string, error)

Loop plays until every stream has landed (exit 0), or until Ticks ticks. It returns the reason it stopped.

type Facts

type Facts interface {
	// Work is how a worker's work card came back.
	Work(card string) (ok bool, report string)
	// Read is what a reader found in a read card.
	Read(card string) (ok bool, finding string)
	// Merge is how a stream's batch went on its branch. others reads, when
	// called, the cards queued in the other streams' merge queues, which a
	// card may need first: a source calls it only for a cross-stream fact,
	// and it reads them then, after every merge step before this one.
	Merge(stream string, batch []string, others func() []string) Outcome
	// Up is which members are up this tick, given which are up now: a member
	// up may go down, and a member down may come up, each with its own chance.
	Up(tick int, members []string, up map[string]bool) map[string]bool
}

Facts is where the outside world's results come from. The loop does not know whether they are real or invented.

type Outcome

type Outcome struct {
	Conflict string // a card that did not merge
	Cross    string // <card>=<other>: a card needs a card of another stream first
	Red      bool
	Suspects []string // on red, the cards the branch's failure points at
}

Outcome is a merge batch's facts: at most one of them; none is green.

type Seeded

type Seeded struct {
	Fail, Broken, Stuck, Cross, Red float64
	Down, Back                      float64
	// contains filtered or unexported fields
}

Seeded is invented facts from a seed: the same seed, against the same table, plays the same run. Each probability is per report (work, read: a card reported again draws again), per batch (stuck, cross, red) or per member and tick (Down, and Back, the chance a member that is down comes up).

func NewSeeded

func NewSeeded(seed uint64) *Seeded

NewSeeded is a seeded source.

func (*Seeded) Drawn

func (s *Seeded) Drawn() Chances

Drawn is the chances this source draws against, as it holds them: Down and Up are the chance of one tick, which is the flags' own only at a tick of a second. It is what a run prints as the chances it draws with.

func (*Seeded) Merge

func (s *Seeded) Merge(stream string, batch []string, others func() []string) Outcome

Merge draws a batch's fact; others is read only for a cross fact, and a cross drawn with no card queued in another stream is green.

func (*Seeded) Read

func (s *Seeded) Read(card string) (bool, string)

func (*Seeded) Up

func (s *Seeded) Up(tick int, members []string, up map[string]bool) map[string]bool

Up draws each member once: an up member goes down with the chance Down, and a down member comes up with the chance Back. A chance of 0 draws nothing.

func (*Seeded) Use

func (s *Seeded) Use(c Chances, every time.Duration)

Use sets the chances the source draws against: the per report and per batch chances as they are, and Down and Up, which are each second's, as the chance of a tick of every (PerTick: the configured every, not the time that passes between two draws).

func (*Seeded) Work

func (s *Seeded) Work(card string) (bool, string)

type Silence

type Silence struct {
	Member    string
	From, For time.Duration
}

Silence is one member's machine not beating for a while.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL