Files
worker/README.md
2026-10-25 21:11:49 +08:00

2.1 KiB

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.