worker
worker is a small Go pool for func() tasks. Create it with a minimum and
maximum worker count, then submit tasks:
pool, err := worker.New(2, 8)
if err != nil {
return err
}
defer pool.Close()
if err := pool.Submit(func() { doWork() }); err != nil {
return err
}
The pool creates the minimum workers immediately and grows on demand up to the
maximum. A channel-driven scheduler owns worker lifecycle and a FIFO task queue
with fixed capacity maxWorkers/2. Submissions first pass through a separate
FIFO ingress buffer, whose default capacity is 128. Configure it with
WithSubmitBuffer; zero keeps the ingress unbuffered, and negative capacities
are rejected:
pool, err := worker.New(2, 8, worker.WithSubmitBuffer(1024))
The ingress buffer and scheduler queue are separate capacity limits. When the
ingress buffer is full, Submit waits until the scheduler can accept more work
or the pool begins closing. With maxWorkers == 1, the scheduler queue has zero
capacity, though the ingress buffer can still hold its configured number of
tasks. A successful Submit means the pool accepted the task; it does not mean
the task has started or finished. Close stops new submissions and waits for
all accepted tasks, including buffered submissions, to finish.
After a task finishes, a worker exits immediately only when total > min and
the number of other idle workers is greater than min/2. There is no idle
timeout.
Only Close shuts down the pool. A task panic is logged and the same worker
continues with later tasks. A worker scheduling panic is logged and terminates
that worker; if accepted work is queued, a replacement worker takes the oldest
task. A panicking task is not retried. An exceptional worker exit with no
queued work does not proactively restore the minimum count; later submissions
can grow the pool again. During Close, queued accepted work is still drained.
Call Close from outside pool tasks so it does not wait for itself.
A task may submit another task to the same pool. If all workers block submitting to a full queue, the caller must resolve that deadlock in its task logic.