-
Notifications
You must be signed in to change notification settings - Fork 959
Conversation
0d4604e
to
9067982
Compare
Oh, this is embarrassing, I totally missed #1741 when searching for previous work 😕 This implementation is considerably different though, so I'll leave the PR open for now. |
Looks cool but what I am missing from my PR (#1741) is the ability to 1. somehow allow the pagination to abort on some criteria and 2. the ability to immediately process each result. Both are a bit of edge cases but can come in handy in a few situations. |
I guess the iterator approach basically solves both your points? |
Ah true, I misread that. Seems that the iterator approach could really do those things. That would be fantastic and way less clunky than my previous version. |
Just for the record: note that the iterator doesn't technically require the If go1.23 turns out to break the |
It took me at least 5min to understand this line |
Just 5min? Then you were faster than me! 😅 Seriously though, I think renaming the type parameters to something more verbose may help? And I think as long as the usage is straightforward (which IMHO it still is), then the implementation is allowed to look a bit gnarly. As a side-note, I'm personally still a bit torn on the rangefunc stuff. Powerful and elegant (at least from a runtime perspective) but twists my brain in ways I'm not yet comfortable with. |
Yep ! For me, that feeling started with the introduction of generics. As a "user"/consumer, they are a joy to use. As a code author/maintainer, they are a pain. Some functions take an additional func XXYYY[O, T any](pid interface{}, f func(interface{}, *O, ...gitlab.RequestOptionFunc) ([]*T, *gitlab.Response, error)) Paginatable[O, T] {
return func(opt *O, optionFunc ...gitlab.RequestOptionFunc) ([]*T, *gitlab.Response, error) {
return f(pid, opt, optionFunc...)
}
} It's a function that returns a closure, whose signature matches Would that make sense to include such function in that |
iterator.go
Outdated
return func(yield func(*T, error) bool) { | ||
nextLink := "" | ||
for { | ||
page, resp, err := f(opt, WithKeysetPaginationParameters(nextLink)) |
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 function f
accepts a variable number of RequestOptionFunc
arguments, but in this call here, it passes a single one.
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.
Maybe something like that
// for user, err := range gitlab.PageIterator(gl.Users.List, nil, gitlab.WithContext(ctx)) {
// if err != nil {
// // handle error
// }
// // process individual user
// }
func PageIterator[O, T any](f Paginatable[O, T], opt *O, optionFunc ...gitlab.RequestOptionFunc) iter.Seq2[*T, error] {
return func(yield func(*T, error) bool) {
nextLink := ""
for {
page, resp, err := f(opt, append(optionFunc, gitlab.WithKeysetPaginationParameters(nextLink))...)
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 yes, good point! Thankfully a quick fix. PTAL
cb6dd4c
to
fb83965
Compare
Also a good point. However, I'm not sure about the closure approach. It's elegant, but I fear it may not be directly clear for consumers. The two versions unfortunately only cover around 60% of list-like methods: if my grep-foo is correct, there are currently 187 list-like methods in total, 25 of the "simple" opt+optFunc type and 85 of the id+opt+optFunc type. |
Friendly reminder 😇 Now that the |
And now 1.23 is out with Any feedback here? 😇 |
If we can clean this PR up a little (mainly the comments I think) I'm good with merging this one... |
@svanharmelen I see only this open thread, which has been addressed. Am I missing something? 🤔 Also: should we keep the non-rangefunc variant, or should we now go "all-in" and just provide the a |
I must admit that maybe I was a bit too quick yesterday, as I now realize that choosing this solution would actually make this package require at least Go 1.23.x which might cause issues for some of the people using this package. |
Well, not necessarily? I'd keep the As for the comments: gotcha! I'll clean them up 👍 |
f2608d2
to
944529b
Compare
@svanharmelen cleaned the comments and removed the non-rangefunc variant. Now this PR focus only on the iterator support. Also added some basic tests. PTAL 🙏 Reminder: as mentioned above, the two variants introduced in this PR cover only about 60% of the list-like methods in the API. There's probably some room to refactor the other methods and make them all a bit more similar, so that in the future more lists can be paginated with the same iterator. |
@svanharmelen friendly ping 😇 |
Thanks for the ping and sorry for taking so long with this one... This just falls outside of "standard" fixes and enhancements and I want to take some time to play with it myself. Yet I'm not using GitLab myself anymore (for a long long time by now 🙈) so sitting myself down to actually do that in between "work" turns out to be something that doesn't happen by itself 😏 I will try to make some time for it in the coming week(end)-ish 😉 And again sorry for all the delays and thank you for your patience! |
One more thing I noticed with this variant: Things like |
@costela we've migrated the repository over to GitLab.com. Please see #2060 (comment) for more context. |
This small PR finally addresses #1320, picking up where the discussion left off.
Naming is - of course - up for discussion! :)
Update: the PR now also includes an experimental iterator based on the
rangefunc
experiment.