Skip to content

Commit 306ad3d

Browse files
committed
[fix] Issue #1
Fixed goroutine leak as well as a data race when using concurrent `UI`s with a common `Engine`. Also enhanced error handling and documentation, too.
1 parent 057db83 commit 306ad3d

8 files changed

Lines changed: 228 additions & 129 deletions

File tree

engine.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type execReq struct {
2525

2626
// exec sends the given line to the backing engine and awaits the results.
2727
// this is a blocking call.
28-
func (ui *UI) exec(ctx context.Context, line string) int {
28+
func (ui *UI) exec(ctx context.Context, line string, reqCh chan execReq) int {
2929
req := execReq{
3030
ctx: ctx,
3131
line: line,
@@ -35,14 +35,19 @@ func (ui *UI) exec(ctx context.Context, line string) int {
3535
select {
3636
case <-ctx.Done():
3737
return 0
38-
case ui.reqCh <- req:
38+
case reqCh <- req:
3939
}
4040
return <-req.respCh
4141
}
4242

4343
// runEngine provides a container for an engine to run inside.
4444
func runEngine(ctx context.Context, eng Engine, reqChs chan chan execReq) {
45-
defer close(reqChs)
45+
defer func() {
46+
close(reqChs)
47+
engines.Lock()
48+
delete(engines.engs, eng)
49+
engines.Unlock()
50+
}()
4651

4752
for {
4853
select {

example/cobra/cmd_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func TestRootCmd(t *testing.T) {
6969
H: echoHandler,
7070
}
7171

72-
ui := sand.NewUI()
72+
ui := new(sand.UI)
7373

7474
ui.SetPrefix(">")
7575
ui.SetIO(&in, &out)
@@ -81,7 +81,9 @@ func TestRootCmd(t *testing.T) {
8181
subT.Errorf("failed writing to input buffer: %s", err)
8282
}
8383

84-
if err = ui.Run(nil, eng); err != io.EOF && err != nil {
84+
err = ui.Run(nil, eng)
85+
var ok bool
86+
if err, ok = sand.IsRecoverable(err); !ok || err != io.EOF && err != nil {
8587
subT.Errorf("unexpected error encountered during UI.Run(): %s", err)
8688
}
8789

example/echo/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (eng *EchoEngine) Exec(ctx context.Context, line string, ui io.ReadWriter)
2929
}
3030

3131
func main() {
32-
ui := sand.NewUI()
32+
ui := new(sand.UI)
3333

3434
log.SetOutput(os.Stdout)
3535
err := ui.Run(

example/tictactoe/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func hasWinner(board [][]Player) (player Player, ok bool) {
171171
}
172172

173173
func main() {
174-
ui := sand.NewUI()
174+
ui := new(sand.UI)
175175

176176
ui.SetPrefix(">")
177177
ui.SetIO(os.Stdin, os.Stdout)

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/Zaba505/sand
33
require (
44
github.com/golang/mock v1.1.1
55
github.com/inconshreveable/mousetrap v1.0.0 // indirect
6+
github.com/pkg/errors v0.8.0
67
github.com/spf13/cobra v0.0.3
78
github.com/spf13/pflag v1.0.3 // indirect
89
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
22
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
33
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
44
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
5+
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
6+
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
57
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
68
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
79
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=

0 commit comments

Comments
 (0)