Skip to content
This repository was archived by the owner on Mar 5, 2026. It is now read-only.

Commit 3dced99

Browse files
committed
add test case & update README:
1 parent 0c5457b commit 3dced99

File tree

7 files changed

+80
-16
lines changed

7 files changed

+80
-16
lines changed

README.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
A Golang package for supporting worker supervisor model.
66
The package help developer easy to run parallel tasks.
7-
It's scalable with minimum effort.
7+
It's scalable with minimal effort.
88

9-
easyworker package is inspired by Erlang OTP.
9+
easyworker is inspired by Erlang OTP.
1010

1111
# Design
1212

@@ -19,7 +19,7 @@ The package has two main part:
1919

2020
Start workers and monitor workers.
2121
Send task to workers and get result(for task & stream).
22-
Restart children if they're failed (depends restart strategy).
22+
Restart(depends restart strategy) children if they're failed to call user function or panic.
2323
Supervisor has one goroutine for send & manage signal to children.
2424

2525
## Child
@@ -32,7 +32,7 @@ Each child has a goroutine to run its task.
3232

3333
easyworker support 3 type of workers:
3434

35-
* Supervisor, Start a supervisor for managing custom workers. Workers can run many type of tasks.
35+
* Supervisor, Start a supervisor for managing children. Children can run many type of tasks.
3636
* Task, Add a list of task and run workers. Workers run same type of task.
3737
* Stream, Start workers then push tasks to workers from channel. Workers run same type of task.
3838

@@ -63,8 +63,8 @@ Every children has a owner restart strategy.
6363

6464
Currently, child has three type of restart strategy:
6565

66-
* ALWAYS_RESTART, supervisor always restart children if it panic/done.
67-
* ERROR_RESTART, supervisor will restart if children was panic.
66+
* ALWAYS_RESTART, supervisor always restart children if it panic or done task.
67+
* ERROR_RESTART, supervisor will only restart if children was panic.
6868
* NO_RESTART, supervisor will don't restart children for any reason.
6969

7070
Children will be started after they are added to supervisor.
@@ -250,14 +250,16 @@ fnStr := func(a int, suffix string) string {
250250
return fmt.Sprintf("%d_%s", a, suffix)
251251
}
252252

253+
num := easyworker.DefaultNumWorkers()
254+
253255
// input channel.
254-
inCh := make(chan []any)
256+
inCh := make(chan []any, num)
255257

256258
// result channel.
257-
outCh := make(chan any)
259+
outCh := make(chan any, num)
258260

259261
// number of workers = number of cpu cores (logical cores).
260-
config, _ := easyworker.NewConfig(fnStr, easyworker.DefaultNumWorkers(), 3, 1000)
262+
config, _ := easyworker.NewConfig(fnStr, num, 3, 1000)
261263

262264
// test with stream.
263265
myStream, _ := easyworker.NewStream(config, inCh, outCh)
@@ -291,15 +293,15 @@ myStream.Stop()
291293

292294
### Monitor Go
293295

294-
A wrapper for goroutine for easy monitor when goroutine was panic or run task done.
296+
A wrapper for goroutine for easy to monitor when goroutine was panic or run task done.
295297

296298
`Monitor` function will return two params.
297299
First param is unique reference id.
298300
Second param is channel that user can receive signal.
299301

300302
Signal is a struct with reference id and kind of end (failed, done).
301303

302-
Go doesn't support return value, you need an other way to get if you neened.
304+
If you need get result from last run, please call `GetResult`.
303305

304306
Example 1:
305307

caller_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package easyworker
22

33
import (
44
"errors"
5+
"fmt"
56
"log"
67
"testing"
78
)
@@ -43,7 +44,7 @@ func TestInvokeIncorrectNumArg(t *testing.T) {
4344

4445
func TestInvokeIncorrectNumArg2(t *testing.T) {
4546
_, err := invokeFun(simpleLoopWithPanic)
46-
47+
fmt.Println(err)
4748
if err == nil {
4849
t.Error("test invoke with incorrect argument failed")
4950
}
@@ -67,6 +68,17 @@ func TestInvokePanic(t *testing.T) {
6768
}
6869
}
6970

71+
func TestInvokePanic2(t *testing.T) {
72+
printLog = true
73+
_, err := invokeFun(simpleLoopWithPanic, 5)
74+
75+
if err == nil {
76+
t.Error("expected error but no return error.")
77+
} else {
78+
log.Println("expected is ok, err: ", err)
79+
}
80+
}
81+
7082
func TestInvokeReturn(t *testing.T) {
7183
result, err := invokeFun(simpleLoopReturn, 5)
7284

config_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,11 @@ func TestIncorrectRetryTime(t *testing.T) {
6565
t.Error("incorrect retry time is passed, ", err)
6666
}
6767
}
68+
69+
func TestPrintLog(t *testing.T) {
70+
EnableLog(true)
71+
72+
if !printLog {
73+
t.Error("Enable Log failed.")
74+
}
75+
}

gomonitor.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (g *Go) run_task() {
187187
if r := recover(); r != nil {
188188
msg.Signal = SIGNAL_FAILED
189189
if printLog {
190-
log.Println(g.id, ", goroutine was panic, ", r)
190+
log.Println(g.id, ", Go was panic, ", r)
191191
}
192192
}
193193

@@ -212,7 +212,7 @@ func (g *Go) run_task() {
212212
if err != nil {
213213
msg.Signal = SIGNAL_FAILED
214214
if printLog {
215-
log.Println(g.id, "goroutine call user function failed, reason:", err)
215+
log.Println(g.id, "Go call user function failed, reason:", err)
216216
}
217217
}
218218
}

gomonitor_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ func TestGoStop(t *testing.T) {
339339

340340
g.Stop()
341341

342+
if g.State() != STOPPED {
343+
t.Error("wrong state")
344+
}
345+
342346
if g.GetResult() != nil {
343347
t.Error("not reset result")
344348
return

supervisor.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,27 @@ func (s *Supervisor) AddChild(child *Child) {
137137
Remove a child to out of supervisor.
138138
*/
139139
func (s *Supervisor) RemoveChild(child *Child) {
140-
delete(s.children, child.id)
140+
if child != nil {
141+
if child.getState() == RUNNING {
142+
child.stop()
143+
}
144+
145+
delete(s.children, child.id)
146+
}
147+
141148
}
142149

143150
/*
144151
Remove a child to out of supervisor by child id.
145152
*/
146153
func (s *Supervisor) RemoveChildById(id int64) {
147-
delete(s.children, id)
154+
if child, existed := s.children[id]; existed {
155+
if child.getState() == RUNNING {
156+
child.stop()
157+
}
158+
159+
delete(s.children, child.id)
160+
}
148161
}
149162

150163
/*

supervisor_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,27 @@ func TestSupFunNoArg(t *testing.T) {
213213
sup.Stop()
214214
}
215215

216+
func TestSupRemoveChild(t *testing.T) {
217+
sup := NewSupervisor()
218+
219+
id, _ := sup.NewChild(ALWAYS_RESTART, simpleLoopNoArg)
220+
child, _ := NewChild(ALWAYS_RESTART, simpleLoopNoArg)
221+
sup.AddChild(child)
222+
223+
time.Sleep(time.Millisecond)
224+
225+
sup.RemoveChildById(id)
226+
sup.RemoveChild(child)
227+
228+
total, _, _, _ := sup.Stats()
229+
230+
if total != 0 {
231+
t.Error("remove children failed")
232+
}
233+
234+
sup.Stop()
235+
}
236+
216237
func TestSupStop(t *testing.T) {
217238
ch := make(chan int)
218239

@@ -301,6 +322,10 @@ func TestSupContext(t *testing.T) {
301322

302323
sup.NewChild(NO_RESTART, simpleLoopWithContext, 3)
303324

325+
child, _ := NewChild(ALWAYS_RESTART, simpleLoopWithContext, 3)
326+
327+
sup.AddChild(child)
328+
304329
time.Sleep(time.Millisecond * 100)
305330

306331
sup.Stop()

0 commit comments

Comments
 (0)