Skip to content

GoPool is a high-performance, feature-rich, and easy-to-use worker pool library for Golang.

License

Notifications You must be signed in to change notification settings

devchat-ai/gopool

Repository files navigation


GoPool

PRs welcome build and test go report release

English 中文

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.

Project Time to Process 1M Tasks (s) Memory Consumption (MB)
GoPool 1.13 2.11
ants 1.43 8.94
pond 3.32 2.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:

  • GoPool
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
  • ants
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
  • pond
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

  • Task Queue: 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.

  • Concurrency Control: GoPool can control the number of concurrent tasks to prevent system overload.

  • Dynamic Worker Adjustment: GoPool can dynamically adjust the number of workers based on the number of tasks and system load.

  • Graceful Shutdown: GoPool can shut down gracefully. It stops accepting new tasks and waits for all ongoing tasks to complete before shutting down when there are no more tasks or a shutdown signal is received.

  • Task Error Handling: GoPool can handle errors that occur during task execution.

  • Task Timeout Handling: GoPool can handle task execution timeouts. If a task is not completed within the specified timeout period, the task is considered failed and a timeout error is returned.

  • Task Result Retrieval: GoPool provides a way to retrieve task results.

  • Task Retry: GoPool provides a retry mechanism for failed tasks.

  • Lock Customization: GoPool supports different types of locks. You can use the built-in sync.Mutex or a custom lock such as spinlock.SpinLock.

  • Task Priority: GoPool supports task priority. Tasks with higher priority are processed first.

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.

About

GoPool is a high-performance, feature-rich, and easy-to-use worker pool library for Golang.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages