Skip to content

Commit ad928e0

Browse files
committed
动态增加 worker
1 parent 808ad9a commit ad928e0

12 files changed

Lines changed: 51 additions & 34 deletions

README.en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ goarch: amd64
7575
cpu: AMD EPYC 7K62 48-Core Processor
7676

7777
BenchmarkLimiter-2 2417040 498.5 ns/op 24 B/op 1 allocs/op
78-
BenchmarkExecutor-2 23793781 49.9 ns/op 0 B/op 0 allocs/op
78+
BenchmarkExecutor-2 20458502 58.3 ns/op 0 B/op 0 allocs/op
7979
BenchmarkAntsPool-2 4295964 271.7 ns/op 0 B/op 0 allocs/op
8080

8181
BenchmarkLimiterTime-2: num is 1000000, cost is 300.936441ms
82-
BenchmarkExecutorTime-2: num is 1000000, cost is 51.350509ms
82+
BenchmarkExecutorTime-2: num is 1000000, cost is 63.026947ms
8383
BenchmarkAntsPoolTime-2: num is 999744, cost is 346.972287ms
8484
```
8585

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ goarch: amd64
7575
cpu: AMD EPYC 7K62 48-Core Processor
7676

7777
BenchmarkLimiter-2 2417040 498.5 ns/op 24 B/op 1 allocs/op
78-
BenchmarkExecutor-2 23793781 49.9 ns/op 0 B/op 0 allocs/op
78+
BenchmarkExecutor-2 20458502 58.3 ns/op 0 B/op 0 allocs/op
7979
BenchmarkAntsPool-2 4295964 271.7 ns/op 0 B/op 0 allocs/op
8080

8181
BenchmarkLimiterTime-2: num is 1000000, cost is 300.936441ms
82-
BenchmarkExecutorTime-2: num is 1000000, cost is 51.350509ms
82+
BenchmarkExecutorTime-2: num is 1000000, cost is 63.026947ms
8383
BenchmarkAntsPoolTime-2: num is 999744, cost is 346.972287ms
8484
```
8585

_icons/coverage.svg

Lines changed: 2 additions & 2 deletions
Loading

config.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type config struct {
1515
workerQueueSize int
1616
recoverFunc func(r any)
1717
newLockerFunc func() sync.Locker
18-
newSchedulerFunc func(workers []*worker) scheduler
18+
newSchedulerFunc func(workers ...*worker) scheduler
1919
}
2020

2121
func newDefaultConfig(workerNum int) *config {
@@ -42,10 +42,10 @@ func (c *config) newLocker() sync.Locker {
4242
return c.newLockerFunc()
4343
}
4444

45-
func (c *config) newScheduler(workers []*worker) scheduler {
45+
func (c *config) newScheduler(workers ...*worker) scheduler {
4646
if c.newSchedulerFunc == nil {
47-
return newRoundRobinScheduler(workers)
47+
return newRoundRobinScheduler(workers...)
4848
}
4949

50-
return c.newSchedulerFunc(workers)
50+
return c.newSchedulerFunc(workers...)
5151
}

config_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,19 @@ func TestConfigNewScheduler(t *testing.T) {
6868
conf := newDefaultConfig(workerNum)
6969

7070
workers := make([]*worker, workerNum)
71-
got := conf.newScheduler(workers)
71+
got := conf.newScheduler(workers...)
7272

7373
if _, ok := got.(*roundRobinScheduler); !ok {
7474
t.Fatalf("got %T is not *roundRobinScheduler", got)
7575
}
7676

7777
want := &roundRobinScheduler{}
78-
conf.newSchedulerFunc = func(workers []*worker) scheduler {
78+
conf.newSchedulerFunc = func(workers ...*worker) scheduler {
7979
want.workers = workers
8080
return want
8181
}
8282

83-
got = conf.newScheduler(workers)
83+
got = conf.newScheduler(workers...)
8484
if fmt.Sprintf("%p", got) != fmt.Sprintf("%p", want) {
8585
t.Fatalf("got %p != want %p", got, want)
8686
}

executor.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,27 @@ func NewExecutor(workerNum int, opts ...Option) *Executor {
4545
panic("goes: worker's queue size <= 0")
4646
}
4747

48-
executor := &Executor{
49-
conf: conf,
50-
closed: false,
51-
lock: conf.newLocker(),
52-
}
53-
5448
workers := make([]*worker, 0, conf.workerNum)
55-
for range conf.workerNum {
56-
worker := newWorker(executor)
57-
workers = append(workers, worker)
49+
executor := &Executor{
50+
conf: conf,
51+
workers: workers,
52+
scheduler: conf.newScheduler(),
53+
closed: false,
54+
lock: conf.newLocker(),
5855
}
5956

60-
executor.workers = workers
61-
executor.scheduler = conf.newScheduler(workers)
57+
executor.spawnWorker()
6258
return executor
6359
}
6460

61+
func (e *Executor) spawnWorker() *worker {
62+
worker := newWorker(e)
63+
64+
e.workers = append(e.workers, worker)
65+
e.scheduler.Set(e.workers)
66+
return worker
67+
}
68+
6569
// AvailableWorkers returns the number of workers available in the executor.
6670
func (e *Executor) AvailableWorkers() int {
6771
e.lock.Lock()
@@ -84,6 +88,19 @@ func (e *Executor) Submit(task Task) error {
8488
return ErrWorkerIsNil
8589
}
8690

91+
// We don't need to create a new worker if we got a worker with no tasks.
92+
if worker.WaitingTasks() <= 0 || len(e.workers) >= e.conf.workerNum {
93+
worker.Accept(task)
94+
return nil
95+
}
96+
97+
// The number of workers has reached the limit, so we can only use the worker we got.
98+
if len(e.workers) >= e.conf.workerNum {
99+
worker.Accept(task)
100+
return nil
101+
}
102+
103+
worker = e.spawnWorker()
87104
worker.Accept(task)
88105
return nil
89106
}

option.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ func WithSyncMutex() Option {
6262

6363
// WithRoundRobinScheduler sets the new scheduler function using round robin strategy.
6464
func WithRoundRobinScheduler() Option {
65-
newSchedulerFunc := func(workers []*worker) scheduler {
66-
return newRoundRobinScheduler(workers)
65+
newSchedulerFunc := func(workers ...*worker) scheduler {
66+
return newRoundRobinScheduler(workers...)
6767
}
6868

6969
return func(conf *config) {
@@ -73,8 +73,8 @@ func WithRoundRobinScheduler() Option {
7373

7474
// WithRandomScheduler sets the new scheduler function using random strategy.
7575
func WithRandomScheduler() Option {
76-
newSchedulerFunc := func(workers []*worker) scheduler {
77-
return newRandomScheduler(workers)
76+
newSchedulerFunc := func(workers ...*worker) scheduler {
77+
return newRandomScheduler(workers...)
7878
}
7979

8080
return func(conf *config) {

option_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func TestWithRoundRobinScheduler(t *testing.T) {
7979
WithRoundRobinScheduler()(conf)
8080

8181
workers := make([]*worker, 0, workerNum)
82-
got := conf.newSchedulerFunc(workers)
82+
got := conf.newSchedulerFunc(workers...)
8383

8484
scheduler, ok := got.(*roundRobinScheduler)
8585
if !ok {
@@ -98,7 +98,7 @@ func TestWithRandomScheduler(t *testing.T) {
9898
WithRandomScheduler()(conf)
9999

100100
workers := make([]*worker, 0, workerNum)
101-
got := conf.newSchedulerFunc(workers)
101+
got := conf.newSchedulerFunc(workers...)
102102

103103
scheduler, ok := got.(*randomScheduler)
104104
if !ok {

random.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type randomScheduler struct {
1414
random *rand.Rand
1515
}
1616

17-
func newRandomScheduler(workers []*worker) *randomScheduler {
17+
func newRandomScheduler(workers ...*worker) *randomScheduler {
1818
scheduler := &randomScheduler{
1919
workers: workers,
2020
random: rand.New(rand.NewSource(time.Now().Unix())),

random_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func TestRandomScheduler(t *testing.T) {
1717
workers = append(workers, new(worker))
1818
}
1919

20-
scheduler := newRandomScheduler(workers)
20+
scheduler := newRandomScheduler(workers...)
2121
if fmt.Sprintf("%p", scheduler.workers) != fmt.Sprintf("%p", workers) {
2222
t.Fatalf("scheduler.workers %p != workers %p", scheduler.workers, workers)
2323
}

0 commit comments

Comments
 (0)