Skip to content

Only update the feed in one place#308

Merged
google-prow-robot merged 3 commits into
knative:masterfrom
grantr:update-once
Aug 2, 2018
Merged

Only update the feed in one place#308
google-prow-robot merged 3 commits into
knative:masterfrom
grantr:update-once

Conversation

@grantr
Copy link
Copy Markdown
Contributor

@grantr grantr commented Aug 1, 2018

When there are multiple places a Feed can be updated, resourceVersion conflicts become more likely. This PR splits Reconcile into two functions:

  • an inner function reconcile that reconciles the state of a Feed without updating it
  • an outer function Reconcile that loads the Feed, calls the inner function if the
    Feed exists, then updates the Feed.

This separation of responsibilities reduces the likelihood that a Feed will be updated more than once per reconcile.

@adamharwayne this might fix the problem you were having yesterday with Feeds not getting a status when EventSource and/or EventType were missing.

@google-prow-robot google-prow-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Aug 1, 2018
@evankanderson
Copy link
Copy Markdown
Member

/assign @adamharwayne

For initial review.

/assign evankanderson

For approve.

When there are multiple places a feed can be updated, resourceVersion
conflicts become more likely. This splits Reconcile into two functions:
- an inner function that reconciles the state of a feed
- an outer function that loads the feed, calls the inner function if the
  feed exists, then updates the feed.

This separation of responsibilities reduces the likelihood that a feed
will be updated more than once per reconcile.

if err = r.reconcile(feed); err != nil {
glog.Errorf("error reconciling Feed: %v", err)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the feed being updated even if the reconcile failed? And, then after updating the feed, returning this error anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the reconcile is a sequence of steps, earlier steps may complete successfully but later steps may fail. The feed is updated on failure to preserve any useful status or metadata changes the non-failing steps made. Partial status is more useful than no status at all.

It could be argued that we should update status after every step as a checkpoint rather than at the end of reconcile. I believe conventional wisdom advises against that, but I don't have all the evidence at hand to make a complete argument. I'll create an issue in docs about writing that evidence down. 😄

Returning the error causes the feed to be requeued for another reconcile immediately (subject to backoff). Since we know the reconcile didn't complete successfully, we want to try again asap.

I'll add a version of this as a comment.

Reason: t.Reason,
Message: t.Message,
})
default:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default case was dropped. Was that intended?

Although, looking at r.getFeedSource(feed), it can only return these two types of errors. Is it proper golang style to rely on that? Or should we have a default in case the implementation of getFeedSource changes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An earlier version of this had return err at https://github.com/knative/eventing/pull/308/files#diff-aadf2ebf3523fdeb1c45a8f0ae1ae27eR100 instead of return nil, so the default case did the same thing as the statement immediately after the switch. Now the default case would do something different, so it's probably worth putting it back in.

return reconcile.Result{}, err
}

if feed.GetDeletionTimestamp() == nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this starts jobs that will act on the feed. Because we have delayed the updateFeed call until after this, is there a chance we are introducing a race condition (albeit a rare one, because this function and its caller should return long, long before the job is scheduled and actually starts running)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's a race condition because the Job and its children don't depend on the status of the feed (currently). The Job pod gets all the information it needs through env vars.

If we later come up with a feedlet that depends on Feed status existing before the feedlet starts, then we may have to revisit.

grantr added 2 commits August 2, 2018 14:08
Reconcile error handling is subtle and perhaps nonintuitive, so make it
clear to new contributors.
This default case is currently unreachable, but future changes may start
returning different error types from getFeedSource, so this is defensive
programming.
@knative-metrics-robot
Copy link
Copy Markdown

The following is the coverage report on pkg/.
Say /test pull-knative-eventing-go-coverage to run the coverage report again

File Old Coverage New Coverage Delta
pkg/controller/feed/reconcile.go 60.4% 61.0% 0.6

@grantr
Copy link
Copy Markdown
Contributor Author

grantr commented Aug 2, 2018

@adamharwayne RFAL.

@adamharwayne
Copy link
Copy Markdown
Contributor

/lgtm

@google-prow-robot google-prow-robot added the lgtm Indicates that a PR is ready to be merged. label Aug 2, 2018
Copy link
Copy Markdown
Member

@evankanderson evankanderson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/approve

@google-prow-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: evankanderson, grantr

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@google-prow-robot google-prow-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 2, 2018
@google-prow-robot google-prow-robot merged commit 267a2a9 into knative:master Aug 2, 2018
@grantr grantr deleted the update-once branch August 2, 2018 22:37
n3wscott pushed a commit to n3wscott/eventing that referenced this pull request Aug 3, 2018
* Only update the feed in one place

When there are multiple places a feed can be updated, resourceVersion
conflicts become more likely. This splits Reconcile into two functions:
- an inner function that reconciles the state of a feed
- an outer function that loads the feed, calls the inner function if the
  feed exists, then updates the feed.

This separation of responsibilities reduces the likelihood that a feed
will be updated more than once per reconcile.

* Document Reconcile flow

Reconcile error handling is subtle and perhaps nonintuitive, so make it
clear to new contributors.

* Add a default case for feed source errors

This default case is currently unreachable, but future changes may start
returning different error types from getFeedSource, so this is defensive
programming.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants