cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / internal / sheet / observe.go
observe.go 2.2K
1package sheet23import "time"45// RecalcInfo describes one recalculation, for telemetry. It holds counts6// only, never contents.7type RecalcInfo struct {8 Full bool // every formula, as after loading9 Evaluated int // cells marked dirty and recomputed10 Cells int // cells stored on every sheet, including formatting-only ones11 Volatile int // volatile formulas on every sheet, recomputed every time12 Circular bool13 // Duration includes the pivot tables the recalculation refreshed,14 // and the recalculation of what reads their results.15 Duration time.Duration16}1718// The engine knows nothing of logging; cmd/012 points these hooks at19// telemetry. They run on the goroutine that changed the workbook and20// must be cheap. trace is the workbook's (see SetTrace), handed back so21// the engine's work is timed as spans nested in whatever the workbook's22// owner has open: a command, an import, a macro run.23var (24 // OnBegin, when set, is called as a recalculation ("recalc") or a25 // pivot table refresh ("pivot") begins; OnRecalc or OnPivot as it26 // ends. They pair up like parentheses: a recalculation holds the27 // pivot refreshes it causes, which follow its own evaluation.28 OnBegin func(trace any, op string)29 // OnRecalc, when set, is called after every recalculation of any30 // workbook.31 OnRecalc func(trace any, i RecalcInfo)32)3334// SetTrace gives the workbook its owner's trace, opaque to the engine:35// a *telemetry.Trace from the program or import that holds the workbook,36// which only its goroutine uses, as with the workbook itself.37func (w *Workbook) SetTrace(trace any) { w.trace = trace }3839// recalcStart is when a recalculation began, or zero when nobody is40// watching, so an unobserved recalculation doesn't read the clock.41func (w *Workbook) recalcStart() time.Time {42 if OnRecalc == nil {43 return time.Time{}44 }45 if OnBegin != nil {46 OnBegin(w.trace, "recalc")47 }48 return time.Now()49}5051func (w *Workbook) observe(full bool, start time.Time, evaluated int) {52 if OnRecalc == nil || start.IsZero() {53 return54 }55 info := RecalcInfo{Full: full, Evaluated: evaluated, Circular: w.Circular}56 for _, s := range w.sheets {57 info.Cells += s.cells.len()58 info.Volatile += len(s.volatile)59 }60 info.Duration = time.Since(start)61 OnRecalc(w.trace, info)62}