-
Notifications
You must be signed in to change notification settings - Fork 16
Conversation
Also restructures some code to favor early returns over nested blocks, adds some comments, etc.
When a resource is removed out-of-band, such as via the Consul API, the in-memory store is unaware of it. Since the store still contains the deleted resource, the background sync will always early-out and thus we lose the self-healing benefit that the background sync provides.
@@ -222,7 +198,7 @@ func (s *Store) UpsertRoute(ctx context.Context, route store.Route, updateCondit | |||
|
|||
// bind to gateways | |||
for _, gateway := range s.gateways { | |||
gateway.TryBind(ctx, route) | |||
gateway.Bind(ctx, route) | |||
} | |||
|
|||
// sync the gateways to consul and route statuses to k8s |
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.
Just for posterity sake, the optimization of only syncing based off of ingress gateway changes comes from trying to ensure the Sync
call below this doesn't hammer Consul every time any resource is reconciled. In the last part of the refactor we do some smarter dirty checking to make sure we're only updating gateways whose state values have actually changed from their last stored state, so even if we temporarily un-gate the syncs an over-sync to Consul right now, it should be fixed soon enough.
@nathancoleman and I talked about that offline.
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.
Personal review
) | ||
|
||
type syncState struct { | ||
ingress *api.IngressGatewayConfigEntry |
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.
The changes in this file are mostly around storing the ingress in our in-memory state store
} | ||
|
||
return nil | ||
return true, nil |
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.
Return whether the sync actually completed or not, matches the changes to the interface in core/interfaces.go
@@ -85,7 +86,12 @@ func (r *RequestHandler) OnStreamRequest(streamID int64, req *discovery.Discover | |||
resources := req.GetResourceNames() | |||
|
|||
// check to make sure we're actually authorized to do this | |||
allowed, err := r.registry.CanFetchSecrets(ctx, GatewayFromContext(ctx), resources) | |||
gateway, err := r.store.GetGateway(ctx, GatewayFromContext(ctx)) |
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.
This aligns with our store transitioning to just handling CRUD operations and nothing more
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.
💯
} | ||
|
||
return listeners | ||
return newBinder(g.client, g.Gateway, g.GatewayState).Bind(ctx, k8sRoute) |
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.
Here's where we consume the new Binder
to bind the route to the gateway
@@ -197,32 +190,16 @@ func (r *K8sRoute) Validate(ctx context.Context) error { | |||
return r.validator.Validate(ctx, r.RouteState, r.Route) | |||
} | |||
|
|||
func (r *K8sRoute) OnBindFailed(err error, gateway store.Gateway) { |
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.
These moved onto the RouteState
at internal/k8s/reconciler/state/route.go
@@ -58,22 +57,6 @@ func (s *Store) GatewayExists(ctx context.Context, id core.GatewayID) (bool, err | |||
return found, nil | |||
} | |||
|
|||
func (s *Store) CanFetchSecrets(ctx context.Context, id core.GatewayID, secrets []string) (bool, error) { |
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.
This moved onto the store.Gateway
interface to limit the amount of logic the store has that isn't related to storing things
if err := syncGroup.Wait().ErrorOrNil(); err != nil { | ||
return err | ||
} | ||
return nil | ||
|
||
return syncGroup.Wait().ErrorOrNil() |
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.
Just an opportunity for simplification that I noticed
// Force each gateway to sync its state even though listeners | ||
// on the gateway may not be marked as needing a sync right now | ||
for _, gateway := range s.gateways { | ||
gateway.needsSync = true | ||
} | ||
|
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.
The sync is not gated the way it was before, so there's no need to "force the sync gate open" as this was doing before. The loop just needs to call sync
. As Andrew mentions in a comment below in this file, we'll be adding some dirty checking logic in a followup PR to prevent an endless loop of reconciliation.
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.
This is awesome that we're starting to get quite a bit closer, enough to actually drop some of the store implementation and old interfaces at this point. I can kind of see the end in sight 😅
Feel free to drop the Listener*
stuff at this point in the store package, or you can in a subsequent PR 🤷
@@ -85,7 +86,12 @@ func (r *RequestHandler) OnStreamRequest(streamID int64, req *discovery.Discover | |||
resources := req.GetResourceNames() | |||
|
|||
// check to make sure we're actually authorized to do this | |||
allowed, err := r.registry.CanFetchSecrets(ctx, GatewayFromContext(ctx), resources) | |||
gateway, err := r.store.GetGateway(ctx, GatewayFromContext(ctx)) |
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.
💯
// Bind will attempt to bind the provided route to all listeners on the Gateway and | ||
// remove the route from any listeners that the route should no longer be bound to. | ||
// The latter is important for scenarios such as the route's parent changing. | ||
func (b *binder) Bind(ctx context.Context, route *K8sRoute) []string { |
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.
I like this simplification 👍
ShouldBind(route Route) bool | ||
Bind(ctx context.Context, route Route) []string | ||
Remove(ctx context.Context, id string) error | ||
Resolve() core.ResolvedGateway |
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.
This is great that we're getting a lot closer
OnGatewayRemoved(gateway Gateway) | ||
} | ||
|
||
// Route should be implemented by all route | ||
// source integrations | ||
type Route interface { | ||
ID() string | ||
Resolve(listener Listener) core.ResolvedRoute |
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.
💯
@@ -1,153 +0,0 @@ | |||
package memory |
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.
🎤 💧
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.
🤣 🤣 🤣
Changes proposed in this PR:
This is a portion of the refactor changes from #163. The end result of this PR is that the logic for binding
xRoutes
toGateways
is abstracted out intoBinder
. You create aBinder
usingbinder.NewBinder( <Gateway> )
and then use it to bind routes by calling<Binder>.Bind( <Route> )
. Similar to other recent changes,K8sGateway.Bind( )
will proxy through toBinder.Bind()
.How I've tested this PR:
🤖 tests pass
How I expect reviewers to test this PR:
Checklist: