Skip to content

Commit

Permalink
Replaced event queue based watching resources in router with shared i…
Browse files Browse the repository at this point in the history
…nformers

- Custom shared informer is used to leverage namespace, label and field filtering.
  (Auto generated shared informer does not allow this)
- Listing resources by shared informers doesn't order by resource version/creation time.
  So custom lister for routes is used to order the route list by creation time and this
  will allow oldest route to be processed before new route to claim the host name.
- Synchronization with the informer queue and cache is a bit difficult as the cache could
  have newer changes than what was pushed on to the queue. Luckily We only care about the
  first sync to avoid 503 status code for routes.
- Handling first sync: Initially all existing items in the cache are pushed as ADD events,
  so router will get at least one event for the item even if the  cache is new (MODIFIED or
  DELETED event on existing item). Using this info and maintaining consumed count, first
  router sync op is performed.
- Subsequent router syncs rely on informer syncing sate and uses rate limiter to coalesce changes.
  • Loading branch information
Ravi Sankar Penta committed Sep 25, 2017
1 parent 1bec7c1 commit ff000e8
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 713 deletions.
22 changes: 6 additions & 16 deletions pkg/cmd/infra/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"github.com/openshift/origin/pkg/cmd/util/variable"
projectclient "github.com/openshift/origin/pkg/project/generated/internalclientset/typed/project/internalversion"
routeapi "github.com/openshift/origin/pkg/route/apis/route"
routeclient "github.com/openshift/origin/pkg/route/generated/internalclientset/typed/route/internalversion"
routeinternalclientset "github.com/openshift/origin/pkg/route/generated/internalclientset"
"github.com/openshift/origin/pkg/router/controller"
controllerfactory "github.com/openshift/origin/pkg/router/controller/factory"
)
Expand All @@ -33,9 +33,7 @@ type RouterSelection struct {
OverrideHostname bool

LabelSelector string
Labels labels.Selector
FieldSelector string
Fields fields.Selector

Namespace string
NamespaceLabelSelector string
Expand Down Expand Up @@ -165,23 +163,15 @@ func (o *RouterSelection) Complete() error {
return fmt.Errorf("--override-hostname requires that --hostname-template be specified")
}
if len(o.LabelSelector) > 0 {
s, err := labels.Parse(o.LabelSelector)
if err != nil {
if _, err := labels.Parse(o.LabelSelector); err != nil {
return fmt.Errorf("label selector is not valid: %v", err)
}
o.Labels = s
} else {
o.Labels = labels.Everything()
}

if len(o.FieldSelector) > 0 {
s, err := fields.ParseSelector(o.FieldSelector)
if err != nil {
if _, err := fields.ParseSelector(o.FieldSelector); err != nil {
return fmt.Errorf("field selector is not valid: %v", err)
}
o.Fields = s
} else {
o.Fields = fields.Everything()
}

if len(o.ProjectLabelSelector) > 0 {
Expand Down Expand Up @@ -221,10 +211,10 @@ func (o *RouterSelection) Complete() error {
}

// NewFactory initializes a factory that will watch the requested routes
func (o *RouterSelection) NewFactory(routeclient routeclient.RoutesGetter, projectclient projectclient.ProjectResourceInterface, kc kclientset.Interface) *controllerfactory.RouterControllerFactory {
func (o *RouterSelection) NewFactory(routeclient routeinternalclientset.Interface, projectclient projectclient.ProjectResourceInterface, kc kclientset.Interface) *controllerfactory.RouterControllerFactory {
factory := controllerfactory.NewDefaultRouterControllerFactory(routeclient, kc)
factory.Labels = o.Labels
factory.Fields = o.Fields
factory.LabelSelector = o.LabelSelector
factory.FieldSelector = o.FieldSelector
factory.Namespace = o.Namespace
factory.ResyncInterval = o.ResyncInterval
switch {
Expand Down
Loading

0 comments on commit ff000e8

Please sign in to comment.