diff --git a/README.md b/README.md index a28d59d..cc00e00 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Some common scenarios include: - Supports Non-blocking and Blocking task submission modes (buffered / unbuffered) - Very high performance and efficient resource usage under heavy workloads, even outperforming unbounded goroutines in some scenarios (See [benchmarks](./benchmark/README.md)) - **New (since v1.3.0)**: configurable pool resizing strategy, with 3 presets for common scenarios: Eager, Balanced and Lazy. +- **New (since v1.5.0)**: complete pool metrics such as number of running workers, tasks waiting in the queue [and more](#metrics--monitoring). - [API reference](https://pkg.go.dev/github.com/alitto/pond) ## How to install @@ -176,6 +177,23 @@ The following chart illustrates the behaviour of the different pool resizing str As the name suggests, the "Eager" strategy always spawns an extra worker when there are no idles, which causes the pool to grow almost linearly with the number of submitted tasks. On the other end, the "Lazy" strategy creates one worker every N submitted tasks, where N is the maximum number of available CPUs ([GOMAXPROCS](https://golang.org/pkg/runtime/#GOMAXPROCS)). The "Balanced" strategy represents a middle ground between the previous two because it creates a worker every N/2 submitted tasks. +### Metrics & monitoring + +Each worker pool instance exposes useful metrics that can be queried through the following methods: + +- `pool.RunningWorkers() int`: Current number of running workers +- `pool.IdleWorkers() int`: Current number of idle workers +- `pool.MinWorkers() int`: Minimum number of worker goroutines +- `pool.MaxWorkers() int`: Maxmimum number of worker goroutines +- `pool.MaxCapacity() int`: Maximum number of tasks that can be waiting in the queue at any given time (queue capacity) +- `pool.SubmittedTasks() uint64`: Total number of tasks submitted since the pool was created +- `pool.WaitingTasks() uint64`: Current number of tasks in the queue that are waiting to be executed +- `pool.SuccessfulTasks() uint64`: Total number of tasks that have successfully completed their exection since the pool was created +- `pool.FailedTasks() uint64`: Total number of tasks that completed with panic since the pool was created +- `pool.CompletedTasks() uint64`: Total number of tasks that have completed their exection either successfully or with panic since the pool was created + +In our [Prometheus example](./examples/prometheus/prometheus.go) we showcase how to configure collectors for these metrics and expose them to Prometheus. + ## API Reference Full API reference is available at https://pkg.go.dev/github.com/alitto/pond diff --git a/pond.go b/pond.go index edb8eae..aebc61c 100644 --- a/pond.go +++ b/pond.go @@ -135,22 +135,22 @@ func New(maxWorkers, maxCapacity int, options ...Option) *WorkerPool { return pool } -// RunningWorkers returns the number of running workers +// RunningWorkers returns the current number of running workers func (p *WorkerPool) RunningWorkers() int { return int(atomic.LoadInt32(&p.workerCount)) } -// IdleWorkers returns the number of idle workers +// IdleWorkers returns the current number of idle workers func (p *WorkerPool) IdleWorkers() int { return int(atomic.LoadInt32(&p.idleWorkerCount)) } -// MinWorkers returns minimum number of worker goroutines +// MinWorkers returns the minimum number of worker goroutines func (p *WorkerPool) MinWorkers() int { return p.minWorkers } -// MaxWorkers returns maximum number of worker goroutines +// MaxWorkers returns the maximum number of worker goroutines func (p *WorkerPool) MaxWorkers() int { return p.maxWorkers } @@ -166,7 +166,7 @@ func (p *WorkerPool) Strategy() ResizingStrategy { return p.strategy } -// SubmittedTasks returns the number of tasks submitted since the pool was created +// SubmittedTasks returns the total number of tasks submitted since the pool was created func (p *WorkerPool) SubmittedTasks() uint64 { return atomic.LoadUint64(&p.submittedTaskCount) } @@ -176,18 +176,18 @@ func (p *WorkerPool) WaitingTasks() uint64 { return atomic.LoadUint64(&p.waitingTaskCount) } -// SuccessfulTasks returns the number of tasks that have successfully completed their exection +// SuccessfulTasks returns the total number of tasks that have successfully completed their exection // since the pool was created func (p *WorkerPool) SuccessfulTasks() uint64 { return atomic.LoadUint64(&p.successfulTaskCount) } -// FailedTasks returns the number of tasks that completed with panic since the pool was created +// FailedTasks returns the total number of tasks that completed with panic since the pool was created func (p *WorkerPool) FailedTasks() uint64 { return atomic.LoadUint64(&p.failedTaskCount) } -// CompletedTasks returns the number of tasks that have completed their exection either successfully +// CompletedTasks returns the total number of tasks that have completed their exection either successfully // or with panic since the pool was created func (p *WorkerPool) CompletedTasks() uint64 { return p.SuccessfulTasks() + p.FailedTasks()