-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The permitpool module contains a single package that implements a pool of permits, allowing limited number of concurrent executions.
- Loading branch information
1 parent
48acf69
commit 9a84a09
Showing
5 changed files
with
141 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module github.com/hashicorp/go-secure-stdlib/permitpool | ||
|
||
go 1.23 | ||
|
||
require github.com/stretchr/testify v1.10.0 | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= | ||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package permitpool | ||
|
||
// DefaultParallelOperations is the default number of parallel operations | ||
// allowed by the permit pool. | ||
const DefaultParallelOperations = 128 | ||
|
||
// Pool is used to limit maximum outstanding requests | ||
type Pool struct { | ||
sem chan struct{} | ||
} | ||
|
||
// New returns a new permit pool with the provided | ||
// number of permits. If permits is less than 1, the | ||
// default number of parallel operations is used. | ||
func New(permits int) *Pool { | ||
if permits < 1 { | ||
permits = DefaultParallelOperations | ||
} | ||
return &Pool{ | ||
sem: make(chan struct{}, permits), | ||
} | ||
} | ||
|
||
// Acquire returns when a permit has been acquired | ||
func (c *Pool) Acquire() { | ||
c.sem <- struct{}{} | ||
} | ||
|
||
// Release returns a permit to the pool | ||
func (c *Pool) Release() { | ||
<-c.sem | ||
} | ||
|
||
// CurrentPermits gets the number of used permits. | ||
// This corresponds to the number of running operations. | ||
func (c *Pool) CurrentPermits() int { | ||
return len(c.sem) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package permitpool_test | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/hashicorp/go-secure-stdlib/permitpool" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestPermitPool(t *testing.T) { | ||
t.Parallel() | ||
pool := permitpool.New(2) | ||
require.NotNil(t, pool) | ||
assert.Equal(t, 0, pool.CurrentPermits(), "Expected 0 permits initially") | ||
|
||
pool.Acquire() | ||
assert.Equal(t, 1, pool.CurrentPermits(), "Expected 1 permit after Acquire") | ||
|
||
pool.Acquire() | ||
assert.Equal(t, 2, pool.CurrentPermits(), "Expected 2 permits after second Acquire") | ||
|
||
pool.Release() | ||
assert.Equal(t, 1, pool.CurrentPermits(), "Expected 1 permit after Release") | ||
|
||
pool.Release() | ||
assert.Equal(t, 0, pool.CurrentPermits(), "Expected 0 permits after second Release") | ||
|
||
pool.Acquire() | ||
pool.Acquire() | ||
|
||
start := make(chan struct{}) | ||
testChan := make(chan struct{}) | ||
go func() { | ||
close(start) | ||
pool.Acquire() | ||
defer pool.Release() | ||
close(testChan) | ||
}() | ||
|
||
// Wait for the goroutine to start | ||
<-start | ||
select { | ||
case <-testChan: | ||
t.Error("Expected Acquire when no permits available to block") | ||
case <-time.After(10 * time.Millisecond): | ||
// Success, the goroutine is blocked | ||
} | ||
|
||
pool.Release() | ||
pool.Release() | ||
select { | ||
case <-testChan: | ||
// Success, the goroutine has acquired the permit | ||
case <-time.After(10 * time.Millisecond): | ||
t.Error("Expected Acquire to unblock when a permit is available") | ||
} | ||
} |