Skip to content

Use iter.Seq to iterate over ScanIterator #3348

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

khasanovbi
Copy link
Contributor

@khasanovbi khasanovbi commented Apr 17, 2025

Support for native iterators has been added in go 1.23.
New Vals method added that return keys iterator directly instead of keys through Next, Val pair.
Minimum go version changed to 1.23.

@khasanovbi
Copy link
Contributor Author

#3347

@khasanovbi
Copy link
Contributor Author

Hmm, interesting why json tests failed...

Copy link
Member

@ndyakov ndyakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@khasanovbi thank you for the suggestion, we were looking into updating the go versions but observed that some tests were failing. We didn't have the time to look more into it back then. Since you decided to try, let's directly update to 1.24 and figure out the tests.
I also have some reservation about marking the Next and Val as deprecated. You can see them in my comment. I am curious about what you think.

Comment on lines +20 to 22
//
// Deprecated: support for native iterators has been added in go 1.23. Use Vals instead.
func (it *ScanIterator) Next(ctx context.Context) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Vals itself will be using Next. In general I would vote agains marking those as deprecated since they will continue to be used inside the library and if a developer would prefer to use them instead of the Vals I don't think we should discourage that by marking Next and Val as deprecated.
Let me know what you think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think iterator via Vals is easier and more convenient than the combination Next, Val.

When you use Val, you need to know that Next must be called before it.
When you use Vals, you just iterate through the values.

Also the code of Vals could be much simpler without calls of Next, Val, without pos var handling, without extra cmd.Err check at each Val call.

// Vals returns iterator over key/field at the current cursor position.
func (it *ScanIterator) Vals(ctx context.Context) iter.Seq[string] {
	return func(yield func(string) bool) {
		if it.cmd.Err() != nil {
			return
		}

		for {
			for _, val := range it.cmd.page {
				if !yield(val) {
					return
				}
			}

			// Return if there is no more data to fetch.
			if it.cmd.cursor == 0 {
				return
			}

			// Fetch next page.
			var cursorIndex int
			switch it.cmd.args[0] {
			case "scan", "qscan":
				cursorIndex = 1
			default:
				cursorIndex = 2
			}

			it.cmd.args[cursorIndex] = it.cmd.cursor

			err := it.cmd.process(ctx, it.cmd)
			if err != nil {
				return
			}
		}
	}
}

they will continue to be used inside the library

In PR Next, Val is used only at this place, I left them in for backward compatibility only.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't disagree that an Iterator is more ergonomic. What I wanted to make sure is that we do not deprecate the current way of iterating over the values before version 10 of go-redis. If you feel strongly about deprecating, we can postpone this PR for when go-redis/v10 will be released.

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

Successfully merging this pull request may close these issues.

3 participants