Documentation
¶
Overview ¶
Package pinpool is a small generic worker pool with a Reporter hook for per-slot UI status. Run dispatches jobs across goroutines and returns the first non-nil error after all workers finish.
Index ¶
Constants ¶
const DefaultStallThreshold = 5 * time.Second
DefaultStallThreshold is how long a slot may sit on the same status before the watcher tags it with a "(still working…)" hint. Tunable via the GH_ACTIONS_LOCK_STALL_HINT_MS env var; set to 0 to disable the watcher.
const DefaultWorkers = 8
DefaultWorkers is a reasonable number of concurrent pins to run when run is called with workers <= 0.
Variables ¶
This section is empty.
Functions ¶
func RunTyped ¶
func RunTyped[T any]( p *Pool, ctx context.Context, label string, jobs []T, display func(T) string, run func(ctx context.Context, slot int, j T) error, ) error
RunTyped dispatches typed jobs through the pool. This is a generic helper that wraps p.Run, boxing each job to any and unboxing in the display and run callbacks.
Types ¶
type Pool ¶
Pool holds shared configuration for dispatching work across goroutines. Create one in the pipeline entry point and reuse it across phases.
func New ¶
New returns a Pool with the given worker count and reporter. If workers is <= 0, DefaultWorkers is used. A nil reporter is replaced with a silent no-op.
func (*Pool) Run ¶
func (p *Pool) Run( ctx context.Context, label string, jobs []any, display func(any) string, run func(ctx context.Context, slot int, j any) error, ) error
Run dispatches jobs across up to p.Workers goroutines.
The pool observes ctx: if ctx is canceled before all jobs drain, workers stop pulling new jobs and Run returns ctx.Err() unless a job error already won the race. Jobs in flight are left to finish; cancellation is cooperative through the ctx the caller passes to run.
Worker slots are not cleared between jobs; the next job overwrites the previous status so the spinner never flickers down to a bare header. Slots are cleared only when their worker exits.
The first non-nil job error is returned after every worker has finished. Callers with non-fatal sentinels should normalize them to nil inside run.
Workers are clamped to len(jobs). Returns nil when len(jobs) == 0 without touching the reporter. display and run must be non-nil when len(jobs) > 0.
An empty label suppresses the pool's own "done/total label" writes, leaving the spinner label to the caller; per-worker status rows and stall hints are unaffected.
type Reporter ¶
type Reporter interface {
// SetWorkerStatus paints (or clears, with "") the status row for a
// given worker slot. Slots are stable for the lifetime of a Run call.
SetWorkerStatus(slot int, status string)
// SetWorkerHint sets (or clears, with "") a dim suffix appended after
// the slot's status text. Used by the stall watcher to flag workers
// that have been on the same status longer than the stall threshold
// without disturbing the main status text. A subsequent
// SetWorkerStatus call is expected to clear any active hint as a side
// effect so a stale hint can't bleed into the next job.
SetWorkerHint(slot int, hint string)
// UpdateLabel replaces the spinner's top label.
UpdateLabel(label string)
}
Reporter is the small surface the pool calls back into so the caller can show progress. `*internal/ui.UI` satisfies it.