Skip to content

Commit

Permalink
Merge pull request #9 from alitto/feature/1.5.0
Browse files Browse the repository at this point in the history
Metrics, Prometheus example, Upgrade to Go 1.15 and fixes
  • Loading branch information
alitto authored Dec 31, 2020
2 parents 5f7cd69 + 5b37421 commit a5eea7f
Show file tree
Hide file tree
Showing 11 changed files with 726 additions and 65 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ go:
- 1.12.x
- 1.13.x
- 1.14.x
- 1.15.x

# Enable Go Modules
env:
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions examples/dynamic_size/go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module github.com/alitto/pond/examples/dynamic_size

go 1.14
go 1.15

require (
github.com/alitto/pond v1.3.0
github.com/alitto/pond v1.5.0
)

replace github.com/alitto/pond => ../../
4 changes: 2 additions & 2 deletions examples/fixed_size/go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module github.com/alitto/pond/examples/fixed_size

go 1.14
go 1.15

require (
github.com/alitto/pond v1.3.0
github.com/alitto/pond v1.5.0
)

replace github.com/alitto/pond => ../../
10 changes: 10 additions & 0 deletions examples/prometheus/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/alitto/pond/examples/fixed_size

go 1.15

require (
github.com/alitto/pond v1.5.0
github.com/prometheus/client_golang v1.9.0
)

replace github.com/alitto/pond => ../../
400 changes: 400 additions & 0 deletions examples/prometheus/go.sum

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions examples/prometheus/prometheus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package main

import (
"fmt"
"net/http"
"time"

"github.com/alitto/pond"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {

// Create a worker pool
pool := pond.New(10, 100)

// Register pool metrics collectors

// Worker pool metrics
prometheus.MustRegister(prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Name: "pool_workers_running",
Help: "Number of running worker goroutines",
},
func() float64 {
return float64(pool.RunningWorkers())
}))
prometheus.MustRegister(prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Name: "pool_workers_idle",
Help: "Number of idle worker goroutines",
},
func() float64 {
return float64(pool.IdleWorkers())
}))

// Task metrics
prometheus.MustRegister(prometheus.NewCounterFunc(
prometheus.CounterOpts{
Name: "pool_tasks_submitted_total",
Help: "Number of tasks submitted",
},
func() float64 {
return float64(pool.SubmittedTasks())
}))
prometheus.MustRegister(prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Name: "pool_tasks_waiting_total",
Help: "Number of tasks waiting in the queue",
},
func() float64 {
return float64(pool.WaitingTasks())
}))
prometheus.MustRegister(prometheus.NewCounterFunc(
prometheus.CounterOpts{
Name: "pool_tasks_successful_total",
Help: "Number of tasks that completed successfully",
},
func() float64 {
return float64(pool.SuccessfulTasks())
}))
prometheus.MustRegister(prometheus.NewCounterFunc(
prometheus.CounterOpts{
Name: "pool_tasks_failed_total",
Help: "Number of tasks that completed with panic",
},
func() float64 {
return float64(pool.FailedTasks())
}))
prometheus.MustRegister(prometheus.NewCounterFunc(
prometheus.CounterOpts{
Name: "pool_tasks_completed_total",
Help: "Number of tasks that completed either successfully or with panic",
},
func() float64 {
return float64(pool.CompletedTasks())
}))

// Expose the registered metrics via HTTP
http.Handle("/metrics", promhttp.Handler())

go submitTasks(pool)

// Start the server
http.ListenAndServe(":8080", nil)

}

func submitTasks(pool *pond.WorkerPool) {

// Submit 1000 tasks
for i := 0; i < 1000; i++ {
n := i
pool.Submit(func() {
fmt.Printf("Running task #%d\n", n)
time.Sleep(500 * time.Millisecond)
})
}
}
4 changes: 2 additions & 2 deletions examples/task_group/go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module github.com/alitto/pond/examples/task_group

go 1.14
go 1.15

require (
github.com/alitto/pond v1.3.0
github.com/alitto/pond v1.5.0
)

replace github.com/alitto/pond => ../../
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/alitto/pond

go 1.14
go 1.15
Loading

0 comments on commit a5eea7f

Please sign in to comment.