refactor in-memory channel to support sync and async handlers#708
Conversation
|
/assign @Harwayne |
Harwayne
left a comment
There was a problem hiding this comment.
Looks like a great start.
| return err | ||
| } | ||
| config := multiChannelFanoutConfig(channels) | ||
| // Temporary adding logger |
There was a problem hiding this comment.
Is this intended to be committed?
There was a problem hiding this comment.
This is a temporary, as I am debugging Async e2e case failure, will be removed before the final commit.
| // Configuration for a fanout.Handler. | ||
| type Config struct { | ||
| Subscriptions []eventingduck.ChannelSubscriberSpec `json:"subscriptions"` | ||
| AsyncHandler bool `json:"asyncHandler"` |
There was a problem hiding this comment.
My preference is Async, rather than AsyncHandler.
It should probably omit on empty as well.
Async bool `json:"async,omitempty"`There was a problem hiding this comment.
I can change but just Async sounds a bit too ambiguous, where AsyncHandler clearly states what that is. Please let me know if you still want me to change it.
There was a problem hiding this comment.
I have a minor preference for async, but I can see why you prefer asyncHandler. Unless someone else chimes in, leave it as-is.
| // the `sink` portions of the subscription. | ||
| func (f *Handler) makeFanoutRequest(m provisioners.Message, sub eventingduck.ChannelSubscriberSpec) error { | ||
| if f.config.AsyncHandler { | ||
| f.logger.Info("><SB> Exercising ASYNC path in Fanout Request for", zap.Any("m = ", m), zap.Any("sub = ", sub)) |
There was a problem hiding this comment.
Probably shouldn't be committed. If is committed, should be Debug level.
Also, zap.Any("m", m) is sufficient (as compared to "m = "), because the string is used as a key in the printed JSON log.
There was a problem hiding this comment.
will be removed completely after debugging is concluded
| // Configuration for a fanout.Handler. | ||
| type Config struct { | ||
| Subscriptions []eventingduck.ChannelSubscriberSpec `json:"subscriptions"` | ||
| AsyncHandler bool `json:"asyncHandler"` |
There was a problem hiding this comment.
Add documentation, something like:
// AsyncHandler controls whether the Subscriptions are called synchronous or asynchronously. It is expected to be false when used as a sidecar.| if c.Spec.Subscribable != nil { | ||
| // TODO After in-memory-channel is retired, this logic must be refactored. | ||
| asyncHandler := false | ||
| if c.Spec.Provisioner.Name == asyncProvisionerName { |
There was a problem hiding this comment.
Add a unit test to verify the state of asyncHandler.
| // the `sink` portions of the subscription. | ||
| func (f *Handler) makeFanoutRequest(m provisioners.Message, sub eventingduck.ChannelSubscriberSpec) error { | ||
| if f.config.AsyncHandler { | ||
| go f.dispatcher.DispatchMessage(&m, sub.SubscriberURI, sub.ReplyURI, provisioners.DispatchDefaults{}) |
There was a problem hiding this comment.
we will drop all errors with this. I think you could wrap in an anon function to log the error at least:
go func () {
if err := f.dispatcher....; err != nil {
log err
}
}
|
|
||
| **/zz_generated.*.go linguist-generated=true | ||
| /pkg/client/** linguist-generated=true | ||
| /contrib/*/pkg/client/** linguist-generated=true |
There was a problem hiding this comment.
Please ignore, merging different branches issue. Just resolved now.
|
It looks like this PR needs to be rebased on master, it contains a lot of commits that are not related |
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
Harwayne
left a comment
There was a problem hiding this comment.
Looks good in general, some small comments before I LGTM.
However, we need to make sure to test this manually before submitting it. Our e2e tests should be good enough that we can rely on them, but I don't feel that is true right now.
| echo "========== Collecting logs for pod: "${pod}" in $namespace =================" | ||
| for container in $(kubectl get pod "${pod}" -n $namespace -ojsonpath='{.spec.containers[*].name}'); do | ||
| echo "----------------------------------------------------------" | ||
| echo "Container: "${container} |
There was a problem hiding this comment.
My preference is to include all the pieces on one line (preferably in an easily searchable way). Something like:
echo "Namespace, Pod, Container: ${namespace}, ${pod}, ${container}"| echo "----------------------------------------------------------" | ||
| echo "Container: "${container} | ||
| kubectl logs -n $namespace "${pod}" -c "${container}" || true | ||
| echo "----------------------------------------------------------" |
There was a problem hiding this comment.
Also write out that this is a previous incarnation of a Pod. Something like:
echo "Namespace, Pod, Container -- Previous Instance: ${namespace}, ${pod}, ${container}"|
|
||
| func createReceiverFunction(f *Handler) func(provisioners.ChannelReference, *provisioners.Message) error { | ||
| return func(_ provisioners.ChannelReference, m *provisioners.Message) error { | ||
| if f.config.AsyncHandler { |
There was a problem hiding this comment.
Modified existing unit test by adding one test case where AsyncHandler is set true. Let me know if you think it is sufficient.
There was a problem hiding this comment.
I don't think anything has been pushed.
| logger.Info("Error creating the Virtual Service for the Channel", zap.Error(err)) | ||
| r.recorder.Eventf(c, corev1.EventTypeWarning, virtualServiceCreateFailed, "Failed to reconcile Virtual Service for the Channel: %v", err) | ||
| return err | ||
| if c.Spec.Provisioner.Name == asyncProvisionerName { |
There was a problem hiding this comment.
Are both paths of this 'if' statement unit tested? If not, do so.
There was a problem hiding this comment.
I think this still isn't unit tested.
There was a problem hiding this comment.
Right, but when I look at the code, in both cases, both branches of if, we create exactly the same virtual service (unless I was reading code incorrectly), even if a different from in-memory provisioner name is used we overwrite it to in-memory. So I am not sure what to test here, the only I could think of is if with a different than in-memory provisioner name, but that would test only golang's if. WDYT?
There was a problem hiding this comment.
I want the unit test to test that the created VirtualService has the same destination regardless of whether or not in-memory or in-memory-channel are used.
As it is, I don't think we have any unit tests for the new in-memory behavior. As that is the provisioner we want going forward, I would like it tested. And once that is tested, I want to also test that in-memory-channel behaves correctly, namely that the created VirtualService points at the correct place.
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
|
@Harwayne sorry, family emergency did not have time to push actual change. |
No problem, I've definitely forgotten to push in the past and wanted to let you know why the review wasn't going to move forward. Thanks for pushing, looking now. |
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
| }, | ||
| Mocks: controllertesting.Mocks{}, | ||
| WantPresent: []runtime.Object{ | ||
| makeVirtualService(), |
There was a problem hiding this comment.
Also makeK8sService("in-memory")
| }, | ||
| Mocks: controllertesting.Mocks{}, | ||
| WantPresent: []runtime.Object{ | ||
| makeVirtualService(), |
There was a problem hiding this comment.
Also makeK8sService("in-memory")
There was a problem hiding this comment.
Sorry, I think this should have been makeK8sService("in-memory-channel"). Sorry for the confusion.
|
|
||
| func makeChannel() *eventingv1alpha1.Channel { | ||
| func makeChannel(pn ...string) *eventingv1alpha1.Channel { | ||
| provisionerName := ccpName |
There was a problem hiding this comment.
Clever way to default. Move it to a separate function and add a comment saying what you are doing.
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
| svc, err := util.CreateK8sService(ctx, r.client, c) | ||
| cCopy := c.DeepCopy() | ||
| cCopy.Spec.Provisioner.Name = asyncProvisionerName | ||
| svc, err := util.CreateK8sService(ctx, r.client, cCopy) |
There was a problem hiding this comment.
Why are we always using in-memory here? Is it only because of my comment in the tests?
| }, | ||
| Mocks: controllertesting.Mocks{}, | ||
| WantPresent: []runtime.Object{ | ||
| makeVirtualService(), |
There was a problem hiding this comment.
Sorry, I think this should have been makeK8sService("in-memory-channel"). Sorry for the confusion.
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
There was a problem hiding this comment.
/lgtm
/hold
Please manually test in your cluster to see that both in-memory and in-memory-channel Channels work simultaneously. Once tested, feel free to cancel the hold yourself.
Also test the new in-memory with the e2e test:
export CLUSTER=<entry from ~/.kube/config file>
export NAMESPACE=<something random>
# This creates all the images. Without it, I was either seeing images that couldn't be pulled or stale images.
test/upload-test-images.sh e2e
# Actually running the tests.
go test -v -tags=e2e -count=1 ./test/e2e -dockerrepo=gcr.io/$PROJECT_ID -cluster=$CLUSTER -namespace=$NAMESPACE -clusterChannelProvisioner=in-memory|
/assign @grantr |
| } | ||
|
|
||
| func makeK8sService() *corev1.Service { | ||
| func makeK8sService(pn ...string) *corev1.Service { |
There was a problem hiding this comment.
Suggestion for a different PR: Seems like this could benefit from the builder pattern for making fixtures with varying aspects. That might make it more clear to the reader what these arguments mean. See builder.go and SubscriptionBuilder.
There was a problem hiding this comment.
Thank you for pointing out.
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: grantr, sbezverk 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 |
|
@Harwayne Interesting problem :) VirtualService uses in destination new /hold |
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
|
/hold cancel |
Signed-off-by: Serguei Bezverkhi <sbezverk@cisco.com>
|
The following is the coverage report on pkg/.
|
|
@Harwayne please lgtm, it was lost due to one final tiny change, |
| selector: | ||
| matchLabels: &labels | ||
| clusterChannelProvisioner: in-memory | ||
| clusterChannelProvisioner: in-memory-channel |
There was a problem hiding this comment.
CI was failing e2e test
Signed-off-by: Serguei Bezverkhi sbezverk@cisco.com