@@ -69,8 +69,7 @@ type DrainCallback func(addr net.Addr)
6969// XDSClient wraps the methods on the XDSClient which are required by
7070// the listenerWrapper.
7171type XDSClient interface {
72- WatchListener (string , func (xdsresource.ListenerUpdate , error )) func ()
73- WatchRouteConfig (string , func (xdsresource.RouteConfigUpdate , error )) func ()
72+ WatchResource (rType xdsresource.Type , resourceName string , watcher xdsresource.ResourceWatcher ) (cancel func ())
7473 BootstrapConfig () * bootstrap.Config
7574}
7675
@@ -110,7 +109,6 @@ func NewListenerWrapper(params ListenerWrapperParams) (net.Listener, <-chan stru
110109 mode : connectivity .ServingModeStarting ,
111110 closed : grpcsync .NewEvent (),
112111 goodUpdate : grpcsync .NewEvent (),
113- ldsUpdateCh : make (chan ldsUpdateWithError , 1 ),
114112 rdsUpdateCh : make (chan rdsHandlerUpdate , 1 ),
115113 }
116114 lw .logger = internalgrpclog .NewPrefixLogger (logger , fmt .Sprintf ("[xds-server-listener %p] " , lw ))
@@ -120,17 +118,16 @@ func NewListenerWrapper(params ListenerWrapperParams) (net.Listener, <-chan stru
120118 lisAddr := lw .Listener .Addr ().String ()
121119 lw .addr , lw .port , _ = net .SplitHostPort (lisAddr )
122120
123- lw .rdsHandler = newRDSHandler (lw .xdsC , lw .rdsUpdateCh )
124- lw .cancelWatch = lw .xdsC .WatchListener (lw .name , lw .handleListenerUpdate )
121+ lw .rdsHandler = newRDSHandler (lw .xdsC , lw .logger , lw .rdsUpdateCh )
122+ lw .cancelWatch = xdsresource .WatchListener (lw .xdsC , lw .name , & ldsWatcher {
123+ parent : lw ,
124+ logger : lw .logger ,
125+ name : lw .name ,
126+ })
125127 go lw .run ()
126128 return lw , lw .goodUpdate .Done ()
127129}
128130
129- type ldsUpdateWithError struct {
130- update xdsresource.ListenerUpdate
131- err error
132- }
133-
134131// listenerWrapper wraps the net.Listener associated with the listening address
135132// passed to Serve(). It also contains all other state associated with this
136133// particular invocation of Serve().
@@ -181,8 +178,6 @@ type listenerWrapper struct {
181178 // rdsUpdates are the RDS resources received from the management
182179 // server, keyed on the RouteName of the RDS resource.
183180 rdsUpdates unsafe.Pointer // map[string]xdsclient.RouteConfigUpdate
184- // ldsUpdateCh is a channel for XDSClient LDS updates.
185- ldsUpdateCh chan ldsUpdateWithError
186181 // rdsUpdateCh is a channel for XDSClient RDS updates.
187182 rdsUpdateCh chan rdsHandlerUpdate
188183}
@@ -320,31 +315,12 @@ func (l *listenerWrapper) run() {
320315 select {
321316 case <- l .closed .Done ():
322317 return
323- case u := <- l .ldsUpdateCh :
324- l .handleLDSUpdate (u )
325318 case u := <- l .rdsUpdateCh :
326319 l .handleRDSUpdate (u )
327320 }
328321 }
329322}
330323
331- // handleLDSUpdate is the callback which handles LDS Updates. It writes the
332- // received update to the update channel, which is picked up by the run
333- // goroutine.
334- func (l * listenerWrapper ) handleListenerUpdate (update xdsresource.ListenerUpdate , err error ) {
335- if l .closed .HasFired () {
336- l .logger .Warningf ("Resource %q received update: %v with error: %v, after listener was closed" , l .name , update , err )
337- return
338- }
339- // Remove any existing entry in ldsUpdateCh and replace with the new one, as the only update
340- // listener cares about is most recent update.
341- select {
342- case <- l .ldsUpdateCh :
343- default :
344- }
345- l .ldsUpdateCh <- ldsUpdateWithError {update : update , err : err }
346- }
347-
348324// handleRDSUpdate handles a full rds update from rds handler. On a successful
349325// update, the server will switch to ServingModeServing as the full
350326// configuration (both LDS and RDS) has been received.
@@ -354,7 +330,6 @@ func (l *listenerWrapper) handleRDSUpdate(update rdsHandlerUpdate) {
354330 return
355331 }
356332 if update .err != nil {
357- l .logger .Warningf ("Received error for rds names specified in resource %q: %+v" , l .name , update .err )
358333 if xdsresource .ErrType (update .err ) == xdsresource .ErrorTypeResourceNotFound {
359334 l .switchMode (nil , connectivity .ServingModeNotServing , update .err )
360335 }
@@ -368,17 +343,7 @@ func (l *listenerWrapper) handleRDSUpdate(update rdsHandlerUpdate) {
368343 l .goodUpdate .Fire ()
369344}
370345
371- func (l * listenerWrapper ) handleLDSUpdate (update ldsUpdateWithError ) {
372- if update .err != nil {
373- l .logger .Warningf ("Received error for resource %q: %+v" , l .name , update .err )
374- if xdsresource .ErrType (update .err ) == xdsresource .ErrorTypeResourceNotFound {
375- l .switchMode (nil , connectivity .ServingModeNotServing , update .err )
376- }
377- // For errors which are anything other than "resource-not-found", we
378- // continue to use the old configuration.
379- return
380- }
381-
346+ func (l * listenerWrapper ) handleLDSUpdate (update xdsresource.ListenerUpdate ) {
382347 // Make sure that the socket address on the received Listener resource
383348 // matches the address of the net.Listener passed to us by the user. This
384349 // check is done here instead of at the XDSClient layer because of the
@@ -391,7 +356,7 @@ func (l *listenerWrapper) handleLDSUpdate(update ldsUpdateWithError) {
391356 // What this means is that the XDSClient has ACKed a resource which can push
392357 // the server into a "not serving" mode. This is not ideal, but this is
393358 // what we have decided to do. See gRPC A36 for more details.
394- ilc := update .update . InboundListenerCfg
359+ ilc := update .InboundListenerCfg
395360 if ilc .Address != l .addr || ilc .Port != l .port {
396361 l .switchMode (nil , connectivity .ServingModeNotServing , fmt .Errorf ("address (%s:%s) in Listener update does not match listening address: (%s:%s)" , ilc .Address , ilc .Port , l .addr , l .port ))
397362 return
@@ -440,3 +405,46 @@ func (l *listenerWrapper) switchMode(fcs *xdsresource.FilterChainManager, newMod
440405 l .modeCallback (l .Listener .Addr (), newMode , err )
441406 }
442407}
408+
409+ // ldsWatcher implements the xdsresource.ListenerWatcher interface and is
410+ // passed to the WatchListener API.
411+ type ldsWatcher struct {
412+ parent * listenerWrapper
413+ logger * internalgrpclog.PrefixLogger
414+ name string
415+ }
416+
417+ func (lw * ldsWatcher ) OnUpdate (update * xdsresource.ListenerResourceData ) {
418+ if lw .parent .closed .HasFired () {
419+ lw .logger .Warningf ("Resource %q received update: %#v after listener was closed" , lw .name , update )
420+ return
421+ }
422+ if lw .logger .V (2 ) {
423+ lw .logger .Infof ("LDS watch for resource %q received update: %#v" , lw .name , update .Resource )
424+ }
425+ lw .parent .handleLDSUpdate (update .Resource )
426+ }
427+
428+ func (lw * ldsWatcher ) OnError (err error ) {
429+ if lw .parent .closed .HasFired () {
430+ lw .logger .Warningf ("Resource %q received error: %v after listener was closed" , lw .name , err )
431+ return
432+ }
433+ if lw .logger .V (2 ) {
434+ lw .logger .Infof ("LDS watch for resource %q reported error: %#v" , lw .name , err )
435+ }
436+ // For errors which are anything other than "resource-not-found", we
437+ // continue to use the old configuration.
438+ }
439+
440+ func (lw * ldsWatcher ) OnResourceDoesNotExist () {
441+ if lw .parent .closed .HasFired () {
442+ lw .logger .Warningf ("Resource %q received resource-not-found-error after listener was closed" , lw .name )
443+ return
444+ }
445+ if lw .logger .V (2 ) {
446+ lw .logger .Infof ("LDS watch for resource %q reported resource-does-not-exist error: %v" , lw .name )
447+ }
448+ err := xdsresource .NewErrorf (xdsresource .ErrorTypeResourceNotFound , "resource name %q of type Listener not found in received response" , lw .name )
449+ lw .parent .switchMode (nil , connectivity .ServingModeNotServing , err )
450+ }
0 commit comments