diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml
index 89b75ae..2a4a59c 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yaml
@@ -11,7 +11,7 @@ body:
value: |
## Before you go any further
- Please read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) ( Chinese translation: [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)) before you file an issue formally.
- - Keep in mind that there is always welcome to ask questions on [Gitter](https://gitter.im/ants-pool/ants).
+ - Keep in mind that there is always welcome to ask questions on [Discord](https://discord.gg/Cuy7KPaWQc).
- type: checkboxes
id: checklist
attributes:
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yaml b/.github/ISSUE_TEMPLATE/feature-request.yaml
index eadc2d5..0d92e4d 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.yaml
+++ b/.github/ISSUE_TEMPLATE/feature-request.yaml
@@ -11,7 +11,7 @@ body:
value: |
## Before you go any further
- Please read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) ( Chinese translation: [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)) before you file an issue formally.
- - Keep in mind that there is always welcome to ask questions on [Gitter](https://gitter.im/ants-pool/ants).
+ - Keep in mind that there is always welcome to ask questions on [Discord](https://discord.gg/Cuy7KPaWQc).
- type: textarea
id: feature-request
attributes:
diff --git a/.github/ISSUE_TEMPLATE/question.yaml b/.github/ISSUE_TEMPLATE/question.yaml
index ed605e3..df18ea7 100644
--- a/.github/ISSUE_TEMPLATE/question.yaml
+++ b/.github/ISSUE_TEMPLATE/question.yaml
@@ -9,7 +9,7 @@ body:
value: |
## Before you go any further
- Please read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) ( Chinese translation: [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)) before you file an issue formally.
- - Keep in mind that there is always welcome to ask questions on [Gitter](https://gitter.im/ants-pool/ants).
+ - Keep in mind that there is always welcome to ask questions on [Discord](https://discord.gg/Cuy7KPaWQc).
- type: textarea
id: question
attributes:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 56a7542..c1df467 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -42,20 +42,20 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
fetch-depth: 2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ uses: github/codeql-action/init@v3
with:
languages: go
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below).
- name: Autobuild
- uses: github/codeql-action/autobuild@v2
+ uses: github/codeql-action/autobuild@v3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -69,4 +69,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
\ No newline at end of file
+ uses: github/codeql-action/analyze@v3
\ No newline at end of file
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 33ff07a..d304abe 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -37,17 +37,17 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Setup Go
- uses: actions/setup-go@v3
+ uses: actions/setup-go@v5
with:
go-version: '^1.16'
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup and run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
- version: v1.51.2
+ version: v1.55.2
args: --timeout 5m -v -E gofumpt -E gocritic -E misspell -E revive -E godot
test:
needs: lint
@@ -60,12 +60,12 @@ jobs:
runs-on: ${{ matrix.os}}
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: Setup Go
- uses: actions/setup-go@v3
+ uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
@@ -83,7 +83,7 @@ jobs:
echo "GO_CACHE=$(go env GOCACHE)" >> $GITHUB_OUTPUT
- name: Cache go modules
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
${{ steps.go-env.outputs.GO_CACHE }}
@@ -96,11 +96,12 @@ jobs:
run: go test -v -race -coverprofile="codecov.report" -covermode=atomic
- name: Upload code coverage report to Codecov
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v4
with:
file: ./codecov.report
flags: unittests
name: codecov-ants
fail_ci_if_error: true
verbose: true
-
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/README.md b/README.md
index bacefbd..b06a61e 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,6 @@
-
@@ -122,6 +121,39 @@ func main() {
wg.Wait()
fmt.Printf("running goroutines: %d\n", p.Running())
fmt.Printf("finish all tasks, result is %d\n", sum)
+ if sum != 499500 {
+ panic("the final result is wrong!!!")
+ }
+
+ // Use the MultiPool and set the capacity of the 10 goroutine pools to unlimited.
+ // If you use -1 as the pool size parameter, the size will be unlimited.
+ // There are two load-balancing algorithms for pools: ants.RoundRobin and ants.LeastTasks.
+ mp, _ := ants.NewMultiPool(10, -1, ants.RoundRobin)
+ defer mp.ReleaseTimeout(5 * time.Second)
+ for i := 0; i < runTimes; i++ {
+ wg.Add(1)
+ _ = mp.Submit(syncCalculateSum)
+ }
+ wg.Wait()
+ fmt.Printf("running goroutines: %d\n", mp.Running())
+ fmt.Printf("finish all tasks.\n")
+
+ // Use the MultiPoolFunc and set the capacity of 10 goroutine pools to (runTimes/10).
+ mpf, _ := ants.NewMultiPoolWithFunc(10, runTimes/10, func(i interface{}) {
+ myFunc(i)
+ wg.Done()
+ }, ants.LeastTasks)
+ defer mpf.ReleaseTimeout(5 * time.Second)
+ for i := 0; i < runTimes; i++ {
+ wg.Add(1)
+ _ = mpf.Invoke(int32(i))
+ }
+ wg.Wait()
+ fmt.Printf("running goroutines: %d\n", mpf.Running())
+ fmt.Printf("finish all tasks, result is %d\n", sum)
+ if sum != 499500*2 {
+ panic("the final result is wrong!!!")
+ }
}
```
@@ -327,7 +359,7 @@ The source code in `ants` is available under the [MIT License](/LICENSE).
The following companies/organizations use `ants` in production.
-
+
### open-source software
@@ -351,6 +383,8 @@ The open-source projects below do concurrent programming with the help of `ants`
- [AdGuardDNS](https://github.com/AdguardTeam/AdGuardDNS): AdGuard DNS is an alternative solution for tracker blocking, privacy protection, and parental control.
- [WatchAD2.0](https://github.com/Qihoo360/WatchAD2.0): WatchAD2.0 是 360 信息安全中心开发的一款针对域安全的日志分析与监控系统,它可以收集所有域控上的事件日志、网络流量,通过特征匹配、协议分析、历史行为、敏感操作和蜜罐账户等方式来检测各种已知与未知威胁,功能覆盖了大部分目前的常见内网域渗透手法。
- [vanus](https://github.com/vanus-labs/vanus): Vanus is a Serverless, event streaming system with processing capabilities. It easily connects SaaS, Cloud Services, and Databases to help users build next-gen Event-driven Applications.
+- [trpc-go](https://github.com/trpc-group/trpc-go): A pluggable, high-performance RPC framework written in Golang.
+- [motan-go](https://github.com/weibocom/motan-go): a remote procedure call (RPC) framework for the rapid development of high-performance distributed services.
#### All use cases:
diff --git a/README_ZH.md b/README_ZH.md
index d3bb007..cefcd87 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -7,7 +7,6 @@
-
@@ -122,6 +121,39 @@ func main() {
wg.Wait()
fmt.Printf("running goroutines: %d\n", p.Running())
fmt.Printf("finish all tasks, result is %d\n", sum)
+ if sum != 499500 {
+ panic("the final result is wrong!!!")
+ }
+
+ // Use the MultiPool and set the capacity of the 10 goroutine pools to unlimited.
+ // If you use -1 as the pool size parameter, the size will be unlimited.
+ // There are two load-balancing algorithms for pools: ants.RoundRobin and ants.LeastTasks.
+ mp, _ := ants.NewMultiPool(10, -1, ants.RoundRobin)
+ defer mp.ReleaseTimeout(5 * time.Second)
+ for i := 0; i < runTimes; i++ {
+ wg.Add(1)
+ _ = mp.Submit(syncCalculateSum)
+ }
+ wg.Wait()
+ fmt.Printf("running goroutines: %d\n", mp.Running())
+ fmt.Printf("finish all tasks.\n")
+
+ // Use the MultiPoolFunc and set the capacity of 10 goroutine pools to (runTimes/10).
+ mpf, _ := ants.NewMultiPoolWithFunc(10, runTimes/10, func(i interface{}) {
+ myFunc(i)
+ wg.Done()
+ }, ants.LeastTasks)
+ defer mpf.ReleaseTimeout(5 * time.Second)
+ for i := 0; i < runTimes; i++ {
+ wg.Add(1)
+ _ = mpf.Invoke(int32(i))
+ }
+ wg.Wait()
+ fmt.Printf("running goroutines: %d\n", mpf.Running())
+ fmt.Printf("finish all tasks, result is %d\n", sum)
+ if sum != 499500*2 {
+ panic("the final result is wrong!!!")
+ }
}
```
@@ -328,7 +360,7 @@ pool.Reboot()
以下公司/组织在生产环境上使用了 `ants`。
-
+
### 开源软件
@@ -352,6 +384,8 @@ pool.Reboot()
- [AdGuardDNS](https://github.com/AdguardTeam/AdGuardDNS): AdGuard DNS is an alternative solution for tracker blocking, privacy protection, and parental control.
- [WatchAD2.0](https://github.com/Qihoo360/WatchAD2.0): WatchAD2.0 是 360 信息安全中心开发的一款针对域安全的日志分析与监控系统,它可以收集所有域控上的事件日志、网络流量,通过特征匹配、协议分析、历史行为、敏感操作和蜜罐账户等方式来检测各种已知与未知威胁,功能覆盖了大部分目前的常见内网域渗透手法。
- [vanus](https://github.com/vanus-labs/vanus): Vanus is a Serverless, event streaming system with processing capabilities. It easily connects SaaS, Cloud Services, and Databases to help users build next-gen Event-driven Applications.
+- [trpc-go](https://github.com/trpc-group/trpc-go): 一个 Go 实现的可插拔的高性能 RPC 框架。
+- [motan-go](https://github.com/weibocom/motan-go): 一套高性能、易于使用的分布式远程服务调用(RPC)框架。motan-go 是 motan 的 Go 语言实现。
#### 所有案例:
diff --git a/ants_benchmark_test.go b/ants_benchmark_test.go
index 83cd920..f39b0e6 100644
--- a/ants_benchmark_test.go
+++ b/ants_benchmark_test.go
@@ -200,3 +200,27 @@ func BenchmarkAntsMultiPoolThroughput(b *testing.B) {
}
}
}
+
+func BenchmarkParallelAntsPoolThroughput(b *testing.B) {
+ p, _ := NewPool(PoolCap, WithExpiryDuration(DefaultExpiredTime))
+ defer p.Release()
+
+ b.ResetTimer()
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ _ = p.Submit(demoFunc)
+ }
+ })
+}
+
+func BenchmarkParallelAntsMultiPoolThroughput(b *testing.B) {
+ p, _ := NewMultiPool(10, PoolCap/10, RoundRobin, WithExpiryDuration(DefaultExpiredTime))
+ defer p.ReleaseTimeout(DefaultExpiredTime) //nolint:errcheck
+
+ b.ResetTimer()
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ _ = p.Submit(demoFunc)
+ }
+ })
+}
diff --git a/examples/main.go b/examples/main.go
index 3e1d9e5..b967098 100644
--- a/examples/main.go
+++ b/examples/main.go
@@ -63,7 +63,7 @@ func main() {
fmt.Printf("running goroutines: %d\n", ants.Running())
fmt.Printf("finish all tasks.\n")
- // Use the pool with a method,
+ // Use the pool with a function,
// set 10 to the capacity of goroutine pool and 1 second for expired duration.
p, _ := ants.NewPoolWithFunc(10, func(i interface{}) {
myFunc(i)
@@ -81,4 +81,34 @@ func main() {
if sum != 499500 {
panic("the final result is wrong!!!")
}
+
+ // Use the MultiPool and set the capacity of the 10 goroutine pools to unlimited.
+ // If you use -1 as the pool size parameter, the size will be unlimited.
+ // There are two load-balancing algorithms for pools: ants.RoundRobin and ants.LeastTasks.
+ mp, _ := ants.NewMultiPool(10, -1, ants.RoundRobin)
+ defer mp.ReleaseTimeout(5 * time.Second)
+ for i := 0; i < runTimes; i++ {
+ wg.Add(1)
+ _ = mp.Submit(syncCalculateSum)
+ }
+ wg.Wait()
+ fmt.Printf("running goroutines: %d\n", mp.Running())
+ fmt.Printf("finish all tasks.\n")
+
+ // Use the MultiPoolFunc and set the capacity of 10 goroutine pools to (runTimes/10).
+ mpf, _ := ants.NewMultiPoolWithFunc(10, runTimes/10, func(i interface{}) {
+ myFunc(i)
+ wg.Done()
+ }, ants.LeastTasks)
+ defer mpf.ReleaseTimeout(5 * time.Second)
+ for i := 0; i < runTimes; i++ {
+ wg.Add(1)
+ _ = mpf.Invoke(int32(i))
+ }
+ wg.Wait()
+ fmt.Printf("running goroutines: %d\n", mpf.Running())
+ fmt.Printf("finish all tasks, result is %d\n", sum)
+ if sum != 499500*2 {
+ panic("the final result is wrong!!!")
+ }
}
diff --git a/multipool.go b/multipool.go
index 1e8b27b..1de75ae 100644
--- a/multipool.go
+++ b/multipool.go
@@ -56,6 +56,9 @@ type MultiPool struct {
// NewMultiPool instantiates a MultiPool with a size of the pool list and a size
// per pool, and the load-balancing strategy.
func NewMultiPool(size, sizePerPool int, lbs LoadBalancingStrategy, options ...Option) (*MultiPool, error) {
+ if lbs != RoundRobin && lbs != LeastTasks {
+ return nil, ErrInvalidLoadBalancingStrategy
+ }
pools := make([]*Pool, size)
for i := 0; i < size; i++ {
pool, err := NewPool(sizePerPool, options...)
@@ -64,9 +67,6 @@ func NewMultiPool(size, sizePerPool int, lbs LoadBalancingStrategy, options ...O
}
pools[i] = pool
}
- if lbs != RoundRobin && lbs != LeastTasks {
- return nil, ErrInvalidLoadBalancingStrategy
- }
return &MultiPool{pools: pools, lbs: lbs}, nil
}
diff --git a/multipool_func.go b/multipool_func.go
index 8101d31..c7d31ff 100644
--- a/multipool_func.go
+++ b/multipool_func.go
@@ -45,6 +45,9 @@ type MultiPoolWithFunc struct {
// NewMultiPoolWithFunc instantiates a MultiPoolWithFunc with a size of the pool list and a size
// per pool, and the load-balancing strategy.
func NewMultiPoolWithFunc(size, sizePerPool int, fn func(interface{}), lbs LoadBalancingStrategy, options ...Option) (*MultiPoolWithFunc, error) {
+ if lbs != RoundRobin && lbs != LeastTasks {
+ return nil, ErrInvalidLoadBalancingStrategy
+ }
pools := make([]*PoolWithFunc, size)
for i := 0; i < size; i++ {
pool, err := NewPoolWithFunc(sizePerPool, fn, options...)
@@ -53,9 +56,6 @@ func NewMultiPoolWithFunc(size, sizePerPool int, fn func(interface{}), lbs LoadB
}
pools[i] = pool
}
- if lbs != RoundRobin && lbs != LeastTasks {
- return nil, ErrInvalidLoadBalancingStrategy
- }
return &MultiPoolWithFunc{pools: pools, lbs: lbs}, nil
}