compile-time assert numControllers == len(controllersArray)#1112
Conversation
|
Hi @syedriko. Thanks for your PR. I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
|
/cc @evankanderson |
|
I find this pretty hard to read. We have e2e tests that will catch the error. |
|
/ok-to-test |
grantr
left a comment
There was a problem hiding this comment.
This is clever and I like it. Thanks @syedriko! The var _ line is a bit hard to read but a comment can explain it adequately. I think it's worth having - relying on E2E tests to debug this problem would be extremely frustrating.
I have some minor suggestions to improve the clarity of the other lines.
| // Add new controllers to this array. | ||
| // You also need to modify numControllers above to match this. | ||
| controllers := []*kncontroller.Impl{ | ||
| controllersArray := [...]*kncontroller.Impl{ |
There was a problem hiding this comment.
This might be clearer as [numControllers]*kncontroller.Impl. That will also catch the issue of numControllers < len(controllersArray).
There was a problem hiding this comment.
Thanks, @grantr!
I picked the [...] form to make sure the length of the array comes strictly from the list of initializers. If we specify the length as you're suggesting, there's a risk of 0-valued elements at the end of the array if there are fewer initializers than the specified length inside of [].
The [numControllers - len(controllersArray)] part of the incantation covers the case of numControllers < len(controllersArray), as that makes the difference negative.
There was a problem hiding this comment.
Makes sense, I forgot about the zero value being filled in at the end.
| if len(controllers) != numControllers { | ||
| logger.Fatalf("Number of controllers and QPS settings mismatch: %d != %d", len(controllers), numControllers) | ||
| } | ||
| controllers := controllersArray[:] |
There was a problem hiding this comment.
Since this seems to only be used in the StartAll call below, we could inline this declaration there:
go kncontroller.StartAll(stopCh, controllersArray[:]...)| logger.Fatalf("Number of controllers and QPS settings mismatch: %d != %d", len(controllers), numControllers) | ||
| } | ||
| controllers := controllersArray[:] | ||
| // compile-time assert numControllers == len(controllersArray) |
There was a problem hiding this comment.
This would be clearer as a complete sentence. I suggest something like
// This line asserts at compile time that the length of controllersArray is equal to numControllers.| // Start all of the controllers. | ||
| logger.Info("Starting controllers.") | ||
| go kncontroller.StartAll(stopCh, controllers...) | ||
| go kncontroller.StartAll(stopCh, controllers[:]...) |
There was a problem hiding this comment.
Just FYI this will conflict with #1118 which is also yours :)
There was a problem hiding this comment.
Yep, the cost of separating the two different issues :)
| // var _ [N-M]int | ||
| // asserts at compile time that N >= M, which we can use to establish equality of N and M: | ||
| // (N >= M) && (M >= N) => (N == M) | ||
| var _ [numControllers - len(controllers)][len(controllers) - numControllers]int |
There was a problem hiding this comment.
: This is freaking awesome! <well, slighlty changed>
There was a problem hiding this comment.
I'm wary of relying on something that needs a 5-line comment to explain a 1-liner technique for compile-ish time-ish bounds checking. I don't really understand how this works and I expect that like most folks, I will assume that it works and not notice when if it somehow doesn't.
I'd be more comfortable with runtime checking supported by a test (since Go's type system doesn't idiomatically encode these kinds of restrictions).
There was a problem hiding this comment.
I'm wary of relying on something that needs a 5-line comment
I started with a one-liner comment, but was quickly (and correctly) prompted that an explanation is in order.
I don't really understand how this works and I expect that like most folks, I will assume
that it works and not notice when if it somehow doesn't.
There's no need to assume, I wouldn't want to:
https://golang.org/ref/spec#Array_types
The length is part of the array's type; it must evaluate to a non-negative constant representable by a value of type int.
var _ [N-M]int
(N - M >=0) <=> (N => M) <=> ((N > M) || (N == M))
var _ [M-N]int
(M - N >=0) <=> (M => N) <=> ((M > N) || (M == N))
var _ [N-M][M-N]int
For what N and M
((N > M) || (N == M)) && ((M > N) || (M == N)) == true?
For integers M and N, there're only 3 ordering possibilities:
-
N > M. Substitute:
(true || false) && (false || false) == false -
M > N
(false || false) && (true || false) == false -
N == M
The only alternative left. But still substitute:
(false || true) && (false || true) == true
compile-ish time-ish
I'm not familiar with that program translation phase. At the present this is a compile-time check. Even if somehow in some Go implementation far, far away that line is evaluated at runtime, it will still fail and we're going to be no worse off than we started.
The earlier a problem is detected, the quicker it can be fixed. It'd be much more productive to find a way to make that assert unnecessary in the first place.
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: grantr, syedriko, vaikas-google The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/test pull-knative-eventing-integration-tests |
Remove echo statements, add -x flag for verbosity on jenkins runs
…5 updates (knative#1112) * [release-v1.16][gomod]: Bump the patch group across 1 directory with 5 updates Bumps the patch group with 2 updates in the / directory: [k8s.io/api](https://github.com/kubernetes/api) and [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver). Updates `k8s.io/api` from 0.30.3 to 0.30.10 - [Commits](kubernetes/api@v0.30.3...v0.30.10) Updates `k8s.io/apiextensions-apiserver` from 0.30.3 to 0.30.10 - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](kubernetes/apiextensions-apiserver@v0.30.3...v0.30.10) Updates `k8s.io/apimachinery` from 0.30.3 to 0.30.10 - [Commits](kubernetes/apimachinery@v0.30.3...v0.30.10) Updates `k8s.io/apiserver` from 0.30.3 to 0.30.10 - [Commits](kubernetes/apiserver@v0.30.3...v0.30.10) Updates `k8s.io/client-go` from 0.30.3 to 0.30.10 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](kubernetes/client-go@v0.30.3...v0.30.10) --- updated-dependencies: - dependency-name: k8s.io/api dependency-type: direct:production update-type: version-update:semver-patch dependency-group: patch - dependency-name: k8s.io/apiextensions-apiserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: patch - dependency-name: k8s.io/apimachinery dependency-type: direct:production update-type: version-update:semver-patch dependency-group: patch - dependency-name: k8s.io/apiserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: patch - dependency-name: k8s.io/client-go dependency-type: direct:production update-type: version-update:semver-patch dependency-group: patch ... Signed-off-by: dependabot[bot] <support@github.com> * Run make generate-release --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Replace a runtime check with a compile-time assert in two controller mainlines
Sister PR in serving knative/serving#3923