Configure ants pools using functional options
devNewPool, NewPoolWithFunc, or NewPoolWithFuncGeneric. These options set values within the ants.Options struct.repository·dev·Indexed 12 days ago
https://github.com/panjf2000/antsA high-performance goroutine pool for Go (v2) that manages and recycles a massive number of goroutines to limit concurrency, reduce memory allocation, and handle panics gracefully. It features a default global pool, customizable pools via functional options, and MultiPool implementations with RoundRobin or LeastTasks load-balancing strategies to mitigate lock contention in high-concurrency scenarios.
NewPool, NewPoolWithFunc, or NewPoolWithFuncGeneric. These options set values within the ants.Options struct.ants pool is highly customizable via ants.Options. You can pass various ants.Option functions to NewPool, NewPoolWithFunc, or NewPoolWithFuncGeneric to configure behavior such as pre-allocation.To install the current version of ants (v2), ensure GO111MODULE=on is set and use the following command:
go get -u github.com/panjf2000/ants/v2To use the legacy v1 version of ants, run the following command:
go get -u github.com/panjf2000/antsA MultiPool consists of multiple underlying Pool instances. It is designed to reduce lock contention and improve performance in scenarios with a very large number of tasks. Instead of a single pool becoming a bottleneck due to fine-grained locking, MultiPool distributes tasks across its constituent pools using a selected load-balancing strategy.
To use it, instantiate it with NewMultiPool, which allows you to define the number of pools, the capacity of each individual pool, and the load-balancing strategy.
// Create a MultiPool with 5 sub-pools, each having a capacity of 1000
// using the RoundRobin strategy.
mp, err := ants.NewMultiPool(5, 1000, ants.RoundRobin)
if err != nil {
panic(err)
}
defer mp.Release()
// Submit tasks to the MultiPool
err = mp.Submit(func() {
// your task logic
})When creating a MultiPoolWithFunc, you must choose a LoadBalancingStrategy to determine how tasks are distributed across the internal pools:
RoundRobin: Distributes tasks sequentially across pools. If a pool returns ErrPoolOverload, the system will attempt to retry the task in a pool selected via the LeastTasks strategy.LeastTasks: Selects the pool currently running the fewest workers.The ants library uses the functional options pattern to configure a pool during instantiation. You can pass multiple Option functions to customize behavior such as worker expiration, memory pre-allocation, and panic handling.
Commonly used configuration functions include:
WithOptions(options Options): Pass a complete Options struct.WithExpiryDuration(expiryDuration time.Duration): Sets the interval for the scavenger goroutine to clean up workers that haven't been used for more than the specified duration.WithPreAlloc(preAlloc bool): If true, memory is pre-allocated for workers during initialization.WithMaxBlockingTasks(maxBlockingTasks int): Sets the maximum number of goroutines allowed to block on Pool.Submit. A value of 0 means no limit.WithNonblocking(nonblocking bool): If true, Pool.Submit will never block and will instead return ErrPoolOverload if no workers are available. Note that MaxBlockingTasks is ignored when Nonblocking is true.WithPanicHandler(panicHandler func(any)): Provides a custom function to handle panics within worker goroutines. If nil, the default behavior is to capture the panic value, resume execution, and print the value with a stack trace.WithLogger(logger Logger): Sets a custom logger. If not set, the standard log package is used.WithDisablePurge(disable bool): If true, workers are not purged and remain resident in the pool.// Example of configuring a pool with functional options
pool, err := ants.NewPool(10, ants.WithPreAlloc(true), ants.WithMaxBlockingTasks(100))The ants package provides a default global goroutine pool that can be used without manual initialization. This is useful for simple use cases where you don't need fine-grained control over pool configuration.
Key functions for the default pool:
Submit(task func()) error: Submits a task to the default pool.Running() int: Returns the number of currently running goroutines.Cap() int: Returns the capacity of the default pool.Free() int: Returns the number of available goroutines.Release(): Closes the default pool.Reboot(): Reboots the default pool (only works if the pool is currently closed).package main
import "github.com/panjf2000/ants/v2"
func main() {
// Submit a task to the default pool
_ = ants.Submit(func() {
println("hello world")
})
// Check pool status
println("Running:", ants.Running())
println("Free:", ants.Free())
// Clean up
ants.Release()
}To clean up resources, use Release() or ReleaseTimeout(duration). If you need to reactivate a pool that has been destroyed, you can use the Reboot() method.
pool.Release()
// Or with a timeout
pool.ReleaseTimeout(time.Second * 3)
// Reactivate a destroyed pool
pool.Reboot()The Tune method allows you to change the capacity of an existing pool at runtime. This method is thread-safe.
pool.Tune(1000) // Tune its capacity to 1000
pool.Tune(100000) // Tune its capacity to 100000For scenarios requiring ultra-large capacities or where tasks run for long durations, you can use the ants.WithPreAlloc(true) functional option. This pre-mallocs the entire capacity of the pool during initialization, reducing memory allocation overhead in the goroutine queue.
// ants will pre-malloc the whole capacity of pool when calling ants.NewPool.
p, _ := ants.NewPool(100000, ants.WithPreAlloc(true))You can create a new goroutine pool with a fixed capacity using ants.NewPool. This allows you to limit the number of concurrent goroutines in your program.
p, _ := ants.NewPool(10000)