ants Goroutine Pool

repository·dev·Indexed 12 days ago

https://github.com/panjf2000/ants

A 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.

Tokens
8K
Snippets
38
Records
48
Agent score
95%

What's inside ants

  1. Configure ants pools using functional options

    dev
    Customizing a pool is achieved by passing various functional options to NewPool, NewPoolWithFunc, or NewPoolWithFuncGeneric. These options set values within the ants.Options struct.
  2. Configure pool using functional options

    dev
    The 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.
  3. Use MultiPool for high-concurrency task submission

    dev

    A 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
    })
  4. Configure LoadBalancingStrategy for MultiPoolWithFunc

    dev

    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.
  5. Configure ants pool using functional options

    dev

    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))
  6. Use the default global pool

    dev

    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()
    }
  7. Release and Reboot a pool

    dev

    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()
  8. Dynamically adjust pool capacity with Tune

    dev

    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 100000
  9. Pre-allocate goroutine queue memory

    dev

    For 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))
  10. Initialize a pool with a specific capacity

    dev

    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)