-
Notifications
You must be signed in to change notification settings - Fork 42
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
Feature/auto pruning #105
Feature/auto pruning #105
Conversation
Skipping CI for Draft Pull Request. |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
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.
first round. A few nits, a couple of typos, and a question about ErrUnprunable.
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 start, I like the file organization. Would love to see some tests also, even if they're not passing yet.
Pull Request Test Coverage Report for Build 2265466586
💛 - Coveralls |
dacd18e
to
3bba9d7
Compare
improve the existing prune package fixes operator-framework#101 Signed-off-by: Bryce Palmer <[email protected]>
3bba9d7
to
3e98659
Compare
Mentioning @fgiloux due to involvement in the review of the EP for this feature. |
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.
I think we need to discuss the Pruner
struct. Using functional arguments AND exposing fields kind of strikes me as an anti-pattern because you could have something like this:
func main() {
pruner := NewPruner(client.New())
doEvilThings(p)
p.Prune(ctx) // this will blow up calling a nil client
}
func doEvilThings(p *Pruner) {
p.Client = nil
}
When a struct has publicly modifiable fields, the methods cannot trust the fields to be valid so much validate them before using them. Look at [this line][https://cs.opensource.google/go/go/+/refs/tags/go1.18.1:src/net/http/request.go;l=573] in net/http
. Since request.URL
is publicly modifiable, it must nil
-check it. Typically, the point of the constructor is to force an instance to be in a good state when its created by having two things:
- Sane defaults
- Validation for user overrides.
That way we know that the fields are all either defaults the library chose or overrides the user chose that are valid. I think we should un-export most if not all fields on the Pruner
and funnel all configuration into the pruner. A rule of thumb I use is if the point of the struct is to hold structured data like a Kubernetes type then export the fields, but if the point of the struct is to do work, then it should have a constructor that enforces a good state.
Generally speaking, I'm happy with how this is shaping up. I will review the tests once we get the main library to a good state. Great work.
Signed-off-by: Bryce Palmer <[email protected]>
As of now 1 test is expected to fail due to an issue with the controller-runtime |
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.
lots of good things
Signed-off-by: Bryce Palmer <[email protected]>
Signed-off-by: Bryce Palmer <[email protected]>
I made some changes in commit 6768874 Let me know what you think @ryantking @fgiloux |
@everettraven it looks good to me. One question: would it make sense to provide a couple of most common strategies? What I have in mind:
|
I think if we wanted to do something like this it would require more discussion as to what some sensible defaults are. My thoughts on it: As an example - if we took the idea of keeping at least the latest X resources and created a common strategy for it, we would have to explicitly define what X is within the logic of that common strategy. If a user wanted to use that common strategy but wanted to change X they wouldn't be able to. func KeepLatestXStrategy(ctx context.Context, objs []client.Object) ([]client.Object, error) {
// in this case we would want to keep the 10 latest resources
// there isn't currently a way to pass something like the number of resources you would like to keep in.
x := 10
// Just for an example return the first 10
if len(objs) < x {
return objs, nil
}
return objs[:x], nil
} One thing I think we could try is to create some kind of helper function that returns a common strategy with a configurable value kind of like this: func GetKeepLatestXStrategy(x int) StrategyFunc {
return func(ctx context.Context, objs []client.Object) ([]client.Object, error) {
// Just for an example return the first 10
if len(objs) < x {
return objs, nil
}
return objs[:x], nil
}
} What do you think @fgiloux @ryantking ? |
@everettraven I like:
It allows the users for simple use cases to have pruning implemented with ~4 lines of code. The alternative would be to provide examples but that is not the same UX even when it is just a copy/paste away |
Signed-off-by: Bryce Palmer <[email protected]>
Signed-off-by: Bryce Palmer <[email protected]>
Signed-off-by: Bryce Palmer <[email protected]>
Signed-off-by: Bryce Palmer <[email protected]>
@fgiloux @ryantking Some common strategy functions should be added with commit 3bf051a Let me know what you think! |
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.
This looks good to me. I am just wondering whether we could save a few CPU cycles by not doing stable sorting.
Signed-off-by: Bryce Palmer <[email protected]>
It looks good to me. Let see what @ryantking wants to add |
@ryantking how does it look? Anything holding this PR? |
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.
Fantastic work, @everettraven!
Few changes, the big one to call out is removing all the logging logic that's currently built-in. Users should use custom strategy and is-prunable functions with their own loggers as desired. We should not couple to a specific logging implementation.
@fgiloux Can you approve the EP? operator-framework/enhancements#109 We need that merged to move forward with this. I have updated it to match the implementation here.
Signed-off-by: Bryce Palmer <[email protected]>
Signed-off-by: Bryce Palmer <[email protected]>
Signed-off-by: Bryce Palmer <[email protected]>
done (as much as I can) |
@fgiloux @jmrodri @ryantking if you could re-review the most up to date changes we can try to have this ready to go right after the EP merges. |
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.
/lgtm
/hold
Want signoff from @fgiloux then I'll unhold (or you can if you have the permissions)
/approved |
@fgiloux When you have some time would you mind reviewing the latest changes? |
@everettraven sorry I am very busy these days. I am fine with the approach and what I have seen but I would like to trial the library to make sure I am not missing something in terms of UX. This requires unfortunately a bit of time. |
@fgiloux Then let's move forward with merging this and we can open followup tickets for issues that you find while working with it. /unhold CC: @everettraven |
Description of the change:
Update the pre-existing pruning functionality
Motivation for the change:
resolves #101