Skip to content

Commit 996a895

Browse files
committedNov 14, 2020
Fix Channel Hack
1 parent fbad720 commit 996a895

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed
 

‎actions/actions.go

+6-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/chromedp/cdproto/page"
88
"github.com/chromedp/chromedp"
9+
"github.com/markoczy/crawler/types"
910
"golang.org/x/exp/errors/fmt"
1011
)
1112

@@ -19,30 +20,26 @@ type NavigateAndWaitLoadedAction struct {
1920
}
2021

2122
func (action *NavigateAndWaitLoadedAction) Do(ctx context.Context) error {
22-
loadErr := make(chan error, 10)
23+
chErr := types.NewErrorSwitchChannel()
2324
go func() {
24-
defer recoverChannelClosed()
2525
time.Sleep(action.timeout)
26-
loadErr <- fmt.Errorf("Timeout while loading DOM Content")
26+
chErr.Send(fmt.Errorf("Timeout while loading DOM Content"))
2727
}()
2828
chromedp.ListenTarget(ctx, func(v interface{}) {
29-
defer recoverChannelClosed()
3029
switch v.(type) {
3130
case *page.EventDomContentEventFired:
32-
loadErr <- nil
31+
chErr.Send(nil)
3332
}
3433
})
3534
go func() {
36-
defer recoverChannelClosed()
3735
err := chromedp.Run(ctx, chromedp.Tasks{
3836
chromedp.Navigate(action.url),
3937
})
4038
if err != nil {
41-
loadErr <- err
39+
chErr.Send(err)
4240
}
4341
}()
44-
err := <-loadErr
45-
close(loadErr)
42+
err := chErr.Receive()
4643
return err
4744
}
4845

‎types/channel.go

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package types
2+
3+
import (
4+
"sync"
5+
)
6+
7+
type ErrorSwitchChannel interface {
8+
Send(err error)
9+
Receive() error
10+
}
11+
12+
type errorSwitchChannel struct {
13+
done bool
14+
err error
15+
mux sync.Mutex
16+
errCh chan error
17+
}
18+
19+
func (ch *errorSwitchChannel) Send(err error) {
20+
ch.mux.Lock()
21+
if !ch.done {
22+
ch.errCh <- err
23+
close(ch.errCh)
24+
ch.done = true
25+
}
26+
ch.mux.Unlock()
27+
}
28+
29+
func (ch *errorSwitchChannel) Receive() error {
30+
return <-ch.errCh
31+
}
32+
33+
func NewErrorSwitchChannel() ErrorSwitchChannel {
34+
return &errorSwitchChannel{
35+
done: false,
36+
err: nil,
37+
mux: sync.Mutex{},
38+
errCh: make(chan error, 1),
39+
}
40+
}

0 commit comments

Comments
 (0)
Please sign in to comment.