Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## ✒ 历史版本的特性介绍 (Features in old versions)

### v0.3.2

> 此版本发布于 2026-01-07

* 完善单元测试,将覆盖率提升到 100%

### v0.3.1-alpha

> 此版本发布于 2026-01-07
Expand Down
4 changes: 2 additions & 2 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
func main() {
ctx := context.Background()

// Limits the number of simultaneous goroutines and not reuses them.
// Limits goroutines.
limiter := goes.NewLimiter(4)

for i := 0; i < 20; i++ {
Expand All @@ -48,7 +48,7 @@ func main() {

limiter.Wait()

// Limits the number of simultaneous goroutines and reuses them.
// Reuses goroutines.
executor := goes.NewExecutor(4)
defer executor.Close()

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
func main() {
ctx := context.Background()

// Limits the number of simultaneous goroutines and not reuses them.
// Limits goroutines.
limiter := goes.NewLimiter(4)

for i := 0; i < 20; i++ {
Expand All @@ -48,7 +48,7 @@ func main() {

limiter.Wait()

// Limits the number of simultaneous goroutines and reuses them.
// Reuses goroutines.
executor := goes.NewExecutor(4)
defer executor.Close()

Expand Down
4 changes: 2 additions & 2 deletions _examples/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
func main() {
ctx := context.Background()

// Limits the number of simultaneous goroutines and not reuses them.
// Limits goroutines.
limiter := goes.NewLimiter(4)

for i := 0; i < 20; i++ {
Expand All @@ -27,7 +27,7 @@ func main() {

limiter.Wait()

// Limits the number of simultaneous goroutines and reuses them.
// Reuses goroutines.
executor := goes.NewExecutor(4)
defer executor.Close()

Expand Down
4 changes: 2 additions & 2 deletions _icons/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 9 additions & 7 deletions executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ var (
type Executor struct {
conf *config

tasks chan Task
done chan struct{}
closed atomic.Bool
group sync.WaitGroup
workers uint
tasks chan Task
done chan struct{}
closed atomic.Bool
group sync.WaitGroup
}

// NewExecutor creates a executor with workers.
Expand All @@ -43,9 +44,10 @@ func NewExecutor(workers uint, opts ...Option) *Executor {
}

executor := &Executor{
conf: conf,
tasks: make(chan Task, conf.queueSize),
done: make(chan struct{}),
conf: conf,
workers: workers,
tasks: make(chan Task, conf.queueSize),
done: make(chan struct{}),
}

for range workers {
Expand Down
87 changes: 87 additions & 0 deletions executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,90 @@ func TestExecutor(t *testing.T) {
t.Fatalf("gotTotalCount %d != totalCount %d", gotTotalCount, totalCount)
}
}

// go test -v -cover -run=^TestExecutorMinMax$
func TestExecutorMinMax(t *testing.T) {
executor := NewExecutor(minWorkers - 1)

if executor.workers != minWorkers {
t.Fatalf("got %d != want %d", executor.workers, minWorkers)
}

executor.Close()
executor = NewExecutor(maxWorkers + 1)

if executor.workers != maxWorkers {
t.Fatalf("got %d != want %d", executor.workers, maxWorkers)
}

executor.Close()
}

// go test -v -cover -run=^TestExecutorContext$
func TestExecutorContext(t *testing.T) {
executor := NewExecutor(4, WithQueueSize(1))
defer executor.Close()

got := uint(cap(executor.tasks))
if got != executor.conf.queueSize {
t.Fatalf("got %d != want %d", got, executor.conf.queueSize)
}

ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()

for i := uint(0); i <= executor.workers; i++ {
err := executor.Submit(ctx, func() {
time.Sleep(200 * time.Millisecond)
})

if err != nil {
t.Fatal(err)
}
}

err := executor.Submit(ctx, func() {})
if err != context.DeadlineExceeded {
t.Fatalf("got %+v != want %+v", err, context.DeadlineExceeded)
}
}

// go test -v -cover -run=^TestExecutorClose$
func TestExecutorClose(t *testing.T) {
executor := NewExecutor(4, WithQueueSize(1))
defer executor.Close()

if executor.closed.Load() {
t.Fatal("executor is closed")
}

ctx := context.Background()
for i := uint(0); i <= executor.workers; i++ {
err := executor.Submit(ctx, func() {
time.Sleep(200 * time.Millisecond)
})

if err != nil {
t.Fatal(err)
}
}

go func() {
err := executor.Submit(ctx, func() {})
if err != ErrExecutorClosed {
t.Errorf("got %+v != want %+v", err, ErrExecutorClosed)
}
}()

time.Sleep(10 * time.Millisecond)
executor.Close()

if !executor.closed.Load() {
t.Fatal("executor not closed")
}

err := executor.Submit(ctx, func() {})
if err != ErrExecutorClosed {
t.Errorf("got %+v != want %+v", err, ErrExecutorClosed)
}
}
17 changes: 17 additions & 0 deletions limiter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,20 @@ func TestLimiter(t *testing.T) {
t.Fatalf("gotTotalCount %d != totalCount %d", gotTotalCount, totalCount)
}
}

// go test -v -cover -run=^TestLimiterMinMax$
func TestLimiterMinMax(t *testing.T) {
limiter := NewLimiter(minLimit - 1)

got := cap(limiter.tokens)
if got != minLimit {
t.Fatalf("got %d != want %d", got, minLimit)
}

limiter = NewLimiter(maxLimit + 1)

got = cap(limiter.tokens)
if got != maxLimit {
t.Fatalf("got %d != want %d", got, maxLimit)
}
}
Loading