-
Notifications
You must be signed in to change notification settings - Fork 786
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add alternative PollEvents() impl to prevent goroutine leaking #273
base: master
Are you sure you want to change the base?
Conversation
…ollEvents() which prevents goroutine leaking
default: | ||
ch <- convertTermboxEvent(tb.PollEvent()) |
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.
default: | |
ch <- convertTermboxEvent(tb.PollEvent()) | |
case ch <- convertTermboxEvent(tb.PollEvent()): |
is better, otherwise while you are waiting for ch
input, cancelling the context is not efective.
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.
@maxatome The core problem is that tb.PollEvent()
is blocking.
This suggestion would not fix that what you claim as it would just handle a cancel during the write on ch
after an event has been blockingly read.
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.
@maxatome The core problem is that
tb.PollEvent()
is blocking.
This suggestion would not fix that what you claim as it would just handle a cancel during the write onch
after an event has been blockingly read.
Yes, I had this in mind.
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.
Do you have any suggestions how to make it better?
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.
Good point @dolmen :)
What about a specific goroutine to handle this blocking function?
Something like that (not tested in termui context):
func PollEventsWithContext(ctx context.Context) <-chan Event {
// tb.PollEvent() is a blocking function, so dedicate a goroutine for it
tbEvent := make(chan Event)
go func() {
defer close(tbEvent)
for {
ev := tb.PollEvent()
if ev.Type == tb.EventInterrupt {
return
}
tbEvent <- convertTermboxEvent(ev)
}
}()
ch := make(chan Event)
go func() {
defer close(ch)
ctxDone := ctx.Done()
for {
select {
case ctxDone:
// interrupt tb.PollEvent(), this call blocks until the
// PollEvent function has successfully been interrupted
tb.Interrupt()
ctxDone = nil
case ev, ok := <-tbEvent:
// Successfully interrupted
if !ok {
return
}
ch <- ev
}
}
}()
return ch
}
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.
Should works, however it looks like over usage of go-routines to me. I would like to suggest a simpler way to do it:
func PollEventsWithCancel() (<-chan Event, func()) {
ch := make(chan Event)
go func() {
defer close(ch)
for {
ev := tb.PollEvent()
if ev.Type == tb.EventInterrupt {
return
}
ch <- convertTermboxEvent(ev)
}
}()
return ch, func(){tb.Interrupt()}
}
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.
Another concern is that the method should be a singleton. In other way behavior is unpredictable and doesn't really make sense.
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.
Let me back to my pet proj after a while and see what can be done, any suggestions are welcome.
Add PollEventsWithContext(ctx context.Context) as an alternative to PollEvents() which prevents goroutine leaking