Skip to content
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

Guidance/suggestions on Iterators and Stop() #130

Open
wittekm opened this issue Oct 18, 2023 · 4 comments
Open

Guidance/suggestions on Iterators and Stop() #130

wittekm opened this issue Oct 18, 2023 · 4 comments

Comments

@wittekm
Copy link

wittekm commented Oct 18, 2023

  1. If I never call it.Stop() on an Iterator, what happens, does that possibly cause a memory leak? If so, I'd love to have that explicitly called out in documentation.
  2. Is it preferred to do an explicit it.Stop() in a for-loop, or is it usually good enough to just defer it upon iterator creation + use break ?
@deckarep
Copy link
Owner

Hello,

I think you’re right we could use some clarity around how iterators work and any potential pitfalls.

So in an effort to preserve long-standing backwards compatibility there are actually three ways of doing iteration.

  1. Iter - original method but can leak if the contents of the channel are not fully consumed. ie, an early break or return - at one point this was marked as deprecated and somewhere along the lines it’s been no longer marked that way.
  2. Each - this is just a callback executed per each element to use. You can safely early return, no leaks and no need to close/stop anything.
  3. Iterator - the most recent way - this is an implementation that is more similar to Iterators in the stdlib but does require to call Stop.

I personally recommend Each as I’ve always thought it solves all problems of iterations and doesn’t require messy cleanup at all.

To answer your questions:

  1. When using Iterator you should always call Stop to avoid leaking resources and also provide deterministic cleanup.
  2. Stop should generally be called out of your loop and deferring the call is fine. Remember that defer has function scope, not block scope.

@wittekm
Copy link
Author

wittekm commented Oct 19, 2023

Cool, thanks for the speedy response. I'd be happy to submit a PR with these recommendations if you'd like (assuming my company is MIT-friendly, pretty sure but gotta double check)

One last question: if you've fully exhausted an Iterator(), do you still need to .Stop() it? If so that's not shown in the iterator example test.

@deckarep
Copy link
Owner

Calling Stop closes the channel. It’s best practice to do a proper shutdown with things. In the event that the channel is not fully drained Stop will ensure the remaining items are drained.

So at an absolute minimum it closes the channel. It’s not the end of the world as the channel would be garbage collected but you would be future proofing the code if for example someone came back in 3 months and changed the code to early return (or break).

@deckarep
Copy link
Owner

Also, I’d love a PR that clears up docs. =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants