-
Notifications
You must be signed in to change notification settings - Fork 44
Remove go and use chan to keep CDP msg order #524
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,9 @@ package common | |
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
"github.com/grafana/xk6-browser/log" | ||
) | ||
|
||
// Ensure BaseEventEmitter implements the EventEmitter interface. | ||
|
@@ -76,6 +79,10 @@ const ( | |
// Worker | ||
|
||
EventWorkerClose string = "close" | ||
|
||
// Event listener. | ||
|
||
EventListenerDefaultChanBufferSize int64 = 10 | ||
) | ||
|
||
// Event as emitted by an EventEmiter. | ||
|
@@ -103,7 +110,7 @@ type eventHandler struct { | |
|
||
// EventEmitter that all event emitters need to implement. | ||
type EventEmitter interface { | ||
emit(event string, data interface{}) | ||
emit(logger *log.Logger, event string, data interface{}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's not change the Instead, I think it would be cleaner if we add a |
||
on(ctx context.Context, events []string, ch chan Event) | ||
onAll(ctx context.Context, ch chan Event) | ||
} | ||
|
@@ -164,12 +171,22 @@ func (e *BaseEventEmitter) sync(fn func()) { | |
<-done | ||
} | ||
|
||
func (e *BaseEventEmitter) emit(event string, data interface{}) { | ||
func (e *BaseEventEmitter) emit(logger *log.Logger, event string, data interface{}) { | ||
emitEvent := func(eh eventHandler) { | ||
select { | ||
case eh.ch <- Event{event, data}: | ||
case <-eh.ctx.Done(): | ||
// TODO: handle the error | ||
for { | ||
select { | ||
case eh.ch <- Event{event, data}: | ||
return | ||
case <-eh.ctx.Done(): | ||
// TODO: handle the error | ||
return | ||
case <-time.After(time.Second): | ||
// If this is printed then a handler is deadlocked on something | ||
// and the channel (which should be buffered) is full. It might | ||
// be that by increasing the buffer size on the channel will help | ||
// alleviate the problem. | ||
logger.Error("emit timed out waiting for handler to read message") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we then cut this short here ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, i'll add a |
||
} | ||
} | ||
} | ||
emitTo := func(handlers []eventHandler) (updated []eventHandler) { | ||
|
@@ -180,7 +197,7 @@ func (e *BaseEventEmitter) emit(event string, data interface{}) { | |
handlers = append(handlers[:i], handlers[i+1:]...) | ||
continue | ||
default: | ||
go emitEvent(handler) | ||
emitEvent(handler) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bye bye goroutine -- this helps keep the order of incoming events. |
||
i++ | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer not have to work with buffered channels, but the issue is with handlers which not only listen and handle incoming events, they can also
emit
events too. Without the buffered channel this would deadlock 😭Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it
10
?I'm asking this because, technically, a buffered channel is the same as an unbuffered channel—Only the prior will deadlock when it's full.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
10
was a just a arbitrary number.I was thinking about this, and it might be better to look at trying to prevent the handler(s) from emitting and receiving event(s), so that we don't need the buffered channels (and leave it as unbuffered). IMO, it doesn't feel right for a handler to be doing two jobs, and should concentrate on handling the events and not emitting new ones, but I need to look into this a bit more (which could take some time to make sense of).
If it's too much work for the handler to not emit, then maybe we need to allow for async emitting (i.e. another buffered channel on the receiving end of the emit).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Inanc. If we're relying on a buffered channel to avoid the deadlock issue, then this change merely alleviates the problem during low activity. On complex sites with many concurrent events we would probably run into it again once the buffer is full.
Have you tested with a complex script like the Vistaprint one from #381? It will need adjusting to the recent breaking changes.