Home

Awesome

<div align="center"> </br> <img src="./logo/gopool-logo-350.png" width="120">

GoPool

PRs welcome build and test go report release

English中文
</div>

Welcome to GoPool, a project with 95% of the code is generated by GPT. You can find the corresponding list of Commit and Prompt at pro.devchat.ai.

GoPool is a high-performance, feature-rich, and easy-to-use worker pool library for Golang. It is designed to manage and recycle a pool of goroutines to complete tasks concurrently, improving the efficiency and performance of your applications.

Performance Testing

This table shows the performance testing results for three Go libraries: GoPool, ants, and pond. The table includes the time it takes for each library to process 1 million tasks and the memory consumption in MB.

ProjectTime to Process 1M Tasks (s)Memory Consumption (MB)
GoPool1.132.11
ants1.438.94
pond3.322.20

You can run the following commands to test the performance of GoPool, ants, and pond on your machine:

$ go test -benchmem -run=^$ -bench ^BenchmarkGoPoolWithMutex$ github.com/devchat-ai/gopool
$ go test -benchmem -run=^$ -bench ^BenchmarkAnts$ github.com/devchat-ai/gopool
$ go test -benchmem -run=^$ -bench ^BenchmarkPond$ github.com/devchat-ai/gopool

The results of the performance testing on my machine are as follows:

go test -benchmem -run=^$ -bench ^BenchmarkGoPool$ github.com/devchat-ai/gopool

goos: darwin
goarch: arm64
pkg: github.com/devchat-ai/gopool
=== RUN   BenchmarkGoPool
BenchmarkGoPool
BenchmarkGoPool-10             1        1131749792 ns/op         2212096 B/op      17447 allocs/op
PASS
ok      github.com/devchat-ai/gopool    1.342s
go test -benchmem -run=^$ -bench ^BenchmarkAnts$ github.com/devchat-ai/gopool

goos: darwin
goarch: arm64
pkg: github.com/devchat-ai/gopool
=== RUN   BenchmarkAnts
BenchmarkAnts
BenchmarkAnts-10               1        1429439750 ns/op         9369552 B/op      70259 allocs/op
PASS
ok      github.com/devchat-ai/gopool    1.681s
go test -benchmem -run=^$ -bench ^BenchmarkPond$ github.com/devchat-ai/gopool

goos: darwin
goarch: arm64
pkg: github.com/devchat-ai/gopool
=== RUN   BenchmarkPond
BenchmarkPond
BenchmarkPond-10               1        3322063917 ns/op         2310840 B/op      21325 allocs/op
PASS
ok      github.com/devchat-ai/gopool    3.541s

Features

<div align="center"> <img src="./logo/gopool.png" width="750"> </div>

Installation

To install GoPool, use go get:

go get -u github.com/devchat-ai/gopool

Usage

Here is a simple example of how to use GoPool with sync.Mutex:

package main

import (
    "sync"
    "time"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100)
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error){
            time.Sleep(10 * time.Millisecond)
            return nil, nil
        })
    }
    pool.Wait()
}

And here is how to use GoPool with spinlock.SpinLock:

package main

import (
    "time"

    "github.com/daniel-hutao/spinlock"
    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithLock(new(spinlock.SpinLock)))
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error){
            time.Sleep(10 * time.Millisecond)
            return nil, nil
        })
    }
    pool.Wait()
}

Configurable Task Queue Size

GoPool uses a thread-safe task queue to store tasks waiting to be processed. Multiple workers can simultaneously fetch tasks from this queue. The size of the task queue can be configured when creating the pool using the WithTaskQueueSize option.

Here is an example of how to use GoPool with a configurable task queue size:

package main

import (
    "time"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithTaskQueueSize(5000))
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error){
            time.Sleep(10 * time.Millisecond)
            return nil, nil
        })
    }
    pool.Wait()
}

Dynamic Worker Adjustment

GoPool supports dynamic worker adjustment. This means that the number of workers in the pool can increase or decrease based on the number of tasks in the queue. This feature can be enabled by setting the MinWorkers option when creating the pool.

Here is an example of how to use GoPool with dynamic worker adjustment:

package main

import (
    "time"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithMinWorkers(50))
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error){
            time.Sleep(10 * time.Millisecond)
            return nil, nil
        })
    }
    pool.Wait()
}

In this example, the pool starts with 50 workers. If the number of tasks in the queue exceeds 3/4 of the current number of workers and the current number of workers is less than MaxWorkers, the pool will double the number of workers until it reaches MaxWorkers. If the number of tasks in the queue is zero and the current number of workers is more than MinWorkers, the pool will halve the number of workers until it reaches MinWorkers.

Task Timeout Handling

GoPool supports task timeout. If a task takes longer than the specified timeout, it will be cancelled. This feature can be enabled by setting the WithTimeout option when creating the pool.

Here is an example of how to use GoPool with task timeout:

package main

import (
    "time"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithTimeout(1*time.Second))
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error) {
            time.Sleep(2 * time.Second)
            return nil, nil
        })
    }
    pool.Wait()
}

In this example, the task will be cancelled if it takes longer than 1 second.

Task Error Handling

GoPool supports task error handling. If a task returns an error, the error callback function will be called. This feature can be enabled by setting the WithErrorCallback option when creating the pool.

Here is an example of how to use GoPool with error handling:

package main

import (
    "errors"
    "fmt"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithErrorCallback(func(err error) {
        fmt.Println("Task error:", err)
    }))
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error) {
            return nil, errors.New("task error")
        })
    }
    pool.Wait()
}

In this example, if a task returns an error, the error will be printed to the console.

Task Result Retrieval

GoPool supports task result retrieval. If a task returns a result, the result callback function will be called. This feature can be enabled by setting the WithResultCallback option when creating the pool.

Here is an example of how to use GoPool with task result retrieval:

package main

import (
    "fmt"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithResultCallback(func(result interface{}) {
        fmt.Println("Task result:", result)
    }))
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error) {
            return "task result", nil
        })
    }
    pool.Wait()
}

In this example, if a task returns a result, the result will be printed to the console.

Task Retry

GoPool supports task retry. If a task fails, it can be retried for a specified number of times. This feature can be enabled by setting the WithRetryCount option when creating the pool.

Here is an example of how to use GoPool with task retry:

package main

import (
    "errors"
    "fmt"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithRetryCount(3))
    defer pool.Release()

    for i := 0; i < 1000; i++ {
        pool.AddTask(func() (interface{}, error) {
            return nil, errors.New("task error")
        })
    }
    pool.Wait()
}

In this example, if a task fails, it will be retried up to 3 times.