pinpool

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 6 Imported by: 0

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

View Source
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.

View Source
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

type Pool struct {
	Workers  int
	Reporter Reporter
}

Pool holds shared configuration for dispatching work across goroutines. Create one in the pipeline entry point and reuse it across phases.

func New

func New(workers int, r Reporter) *Pool

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.

Jump to

Keyboard shortcuts

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