-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
variable substitution in finally section #2908
Conversation
This PR cannot be merged: expecting exactly one kind/ label Available
|
2 similar comments
This PR cannot be merged: expecting exactly one kind/ label Available
|
This PR cannot be merged: expecting exactly one kind/ label Available
|
how come |
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.
Thanks for the prompt fix.
Just a NIT, but I think we can also merge it as it is.
/approve
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: afrittoli, jlpettersson The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/lgtm |
@pritidesai Unfortunately it looks like the EasyCLA bot might require a kick to wake it up, which means making a null edit (adding an extra space or something to the commit message should work) and then a force-push. Apologies for that. |
Our coverage tool is unreliable :( tektoncd/plumbing#165 I think we should switch to using something like coveralls |
52f4060
to
d898cee
Compare
/lgtm |
/test pull-tekton-pipeline-build-tests |
variables under params section were not substituted with the values for tasks in finally section. Fixing the parameter interpolation for final tasks.
I have bitten myself in the foot a few times using I don't have deep enough understanding about this, there are some articles that may elaborate about this, e.g. https://appliedgo.net/slices/ In general I prefer functional programming languages that never mutate slices in a dangerous way :) |
yup and that's one of the reasons its not directly ranging over
I have been struggling to avoid |
I mean, as you originally wrote:
is safe - because However, the optimization:
may (I am not sure - but I have struggled with this earlier) be problematic, as I don't know - but my Go experience tells me that this may be problematic. |
My understanding of this is that p.Tasks will not be mutated - my understanding of slices comes and goes depending on how recently I've read https://blog.golang.org/slices but my understanding is that append returns a new slice and sometimes allocates new memory to do it, but the slice passed in as the first argument is not changed |
@jlpettersson i didnt see the article you linked above (https://appliedgo.net/slices/) before replying but i think there's an important distinction:
The array afaik is the underlying storage; it might be mutated but that doesn't change the slice that was passed in as an arg. Changes to slices can cause unexpected side effects to other slices, e.g.: https://play.golang.org/p/zY0WJztAt_z but afaik that append function could change the array underlying p.Tasks but wouldn't change the slice. (95% sure? 😅 ) |
I am still trying to understand as well if the original Wrote a sample program with three slices |
d898cee
to
e41a897
Compare
one of the things that makes this hard is that the choice to allocate more memory or not will depend on the specifics of the machine it's being run on, so its hard to be certain about it. afaik the underlying array can be mutated by append but not the slice (which is why append requires you to assign the new slice) For example: https://play.golang.org/p/SmRt2_3eJVG No matter how many times we append to the original slice, it doesn't change. The underlying memory might, because we append to it and the slices that are created as a result have to increase in size and eventually capacity, but the original is the same. |
/lgtm |
Couldn't resist, sorry for commenting on closed PR 🙏, this is interesting article: https://medium.com/@Jarema./golang-slice-append-gotcha-e9020ff37374 The changes in this PR wouldn't be impacted since the original slice is not modified but sharing in general. It causes issues when more than one slices are created using Results in:
All the slices It depends on how the original slice is initialized. |
From the article
This is the pattern I follow, to avoid my earlier mistakes, and therefore suggested
but as written now, probably works in this case - just be careful with that pattern in other situations. |
well that is definitely not what i expected!! it makes sense after staring at it for a while but i think you're both right that there are more gotchas here than I realized!
Specifically it depends on the size of the underlying array - when the slice is initalized in this loop: func create(iterations int) []int {
a := make([]int, 0)
for i := 0; i < iterations; i++ {
a = append(a, i)
}
return a
} The slice is created with size 0 so many of the append calls need to allocate more space in the array - if you look at the len and cap as it runs, in the playground the space is doubled every time more is needed, so when the loop returns, the slice has capacity 16, while len is 11. When the slice is initialized with In the cases where the behavior is as expected, all the slices are pointing at different memory - in the cases where the behavior is not as expected, all the slices are pointing at the same memory. https://play.golang.org/p/woTJPqN8E6Q Also note that printing So appending to |
If you tried to do something like:
Then depending on the capacity of p.Tasks you might see something crazy! i.e. all 3 functions might be operating on a slice with p.Tasks and someOtherThing :O Or if you did something like |
Yup I absolutely agree @bobcatfish @jlpettersson And the way we initialize pipeline/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go Lines 764 to 769 in 568efa4
I am trying to convert our observations here into tests to confirm pipeline is not impacted in general. Wrote two tests with two pipelines:
Without anything in the pipeline (which is not the ideal case), memory allocations of
Also, note the length and capacity of a new slice created using
I don't have any outcome of this research yet but wanted to share (1) the way |
Thanks for doing this research @pritidesai ! I would to be clear that I think the danger of any impact to our controllers in general is minimal - this is something that's worth keeping in mind but I think the circumstances that lead to this gotcha are unlikely. (famous last words haha XD) |
I'd like to add a reassurance to everyone as well: We can all try our best to write bug free code, but it's never going to be perfect. As much as possible we want everyone to feel safe to create contributions without having to agonize over edge cases - we have the test automation to support this. Of course we want to think things through, but we can only do so much. I think being educated about this kind of behavior will be most useful if:
|
pipeline/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go Lines 764 to 769 in 568efa4
@pritidesai I think that might in fact be good news! The problem with the example code above was that make was being used with an initial size of 0:
In the call to make above, we're making the underlying array exactly the size that we need. I'm not sure we can guarantee it, but I think that makes the chances very good that any attempts to append to that memory will require creation of a new array. (Which is what we want, b/c changes to that new array will not impact the original one.) |
Circling back here @jlpettersson you may be interested to hear that THIS VERY LINE DID END UP BITING US: #3244 ( + @jerop @pritidesai ) On the upside 😅 I think we can now express why this is a problem, and it wasn't because of it mutating the underlying memory, it was because:
whew!!! |
Changes
Variables under
params
section were not substituted with the values fortasks in finally section. Fixing the parameter interpolation for final tasks.
Fixes #2906
/cc @bobcatfish @vdemeester
/kind bug
Submitter Checklist
These are the criteria that every PR should meet, please check them off as you
review them:
See the contribution guide for more details.
Double check this list of stuff that's easy to miss:
cmd
dir, please updatethe release Task to build and release this image.
Reviewer Notes
If API changes are included, additive changes must be approved by at least two OWNERS and backwards incompatible changes must be approved by more than 50% of the OWNERS, and they must first be added in a backwards compatible way.
Release Notes