-
Notifications
You must be signed in to change notification settings - Fork 0
go-eicio: Added channel iterator for reader #35
Conversation
New method Reader.Events() returns <-chan Event to provide simple syntax for ranging over all events in a file/stream. Reader.Err was added to make errors accessible in this scheme.
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.
apologies for the belated review.
This type of API is great and does make sense when reading off a (possibly complicated to decode) stream.
but it may lead to leaking goroutines: what happens if the user exits the for evt := range r.Events()
loop early?
the goroutine started inside the Events()
method will never be collected by the runtime.
I would instead go with a time.NewTicker()
API: have a dedicated type that does the looping and put a Close()
method on it that can be defer
-ed.
That Close()
method will then make sure that the "events" reading goroutine will be stopped and collected.
I usually follow the bufio.NewScanner
function+type for the naming of such a type:
scan := eicio.NewScanner(reader)
defer scan.Close()
for scan.Scan() {
evt := scan.Event()
}
if err = scan.Err(); err != nil {
panic(err)
}
but you could indeed have such an API:
scan := eicio.NewScanner(reader)
defer scan.Close()
for evt := range scan.Events() {
}
if err = scan.Err(); err != nil {
panic(err)
}
for event, _ := rdr.Get(); event != nil; event, _ = rdr.Get() { | ||
events <- event | ||
} | ||
close(events) |
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.
you should rather put it as a defer(close(events))
at the top of the goroutine.
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.
Ah, good call!
Thank you for reviewing this! Indeed, this is an issue that was troublesome for me. In the end I had decided that one should just be aware of this and avoid breaking the loop, but I should have at least put this in the doc comment. However, allowing for such problems is probably bad practice anyway. I like your solution, though I wish I could find a solution that allows the user code to be slightly more succinct. This problem is one of those Go quirks that gets under my skin a little bit, so I need to give it some thought. I wish that |
Perhaps Reader.Events() and Reader.Close() could be modified to clean up any existing event channel? |
yes, that would work. but I am probably just nitpicking :) |
New method Reader.Events() returns <-chan Event to provide simple syntax
for ranging over all events in a file/stream. Reader.Err was added to
make errors accessible in this scheme.
Additionally, the tools
eicio-ls
andeicio-strip
were updated to iterate events in this way.This PR resolves #34