@@ -102,6 +102,8 @@ type SnapshotCache interface {
102102 DeleteResources (ctx context.Context , node string , typ string , resourcesToDeleted []string ) error
103103
104104 DrainResources (ctx context.Context , node string , typ string , resourcesToDeleted []string ) error
105+
106+ UpdateVirtualHosts (ctx context.Context , node string , typ string , resources map [string ]map [string ]* types.ResourceWithTTL ) error
105107}
106108
107109type snapshotCache struct {
@@ -390,55 +392,142 @@ func (cache *snapshotCache) UpsertResources(ctx context.Context, node string, ty
390392 return nil
391393}
392394
393- func (cache * snapshotCache ) DeleteResources (ctx context.Context , _ string , typ string , resourcesToDeleted []string ) error {
394- cache .mu .Lock ()
395- defer cache .mu .Unlock ()
395+ func (cache * snapshotCache ) UpdateVirtualHosts (ctx context.Context , _ string , typ string , resources map [string ]map [string ]* types.ResourceWithTTL ) error {
396+ index := GetResponseType (typ )
396397
397- fmt .Printf ("local DeleteResources %v" , resourcesToDeleted )
398+ var wg sync.WaitGroup
399+ for node , r := range resources {
400+ wg .Add (1 )
401+ go func (node string , resourcesUpserted map [string ]* types.ResourceWithTTL ) {
402+ cache .mu .Lock ()
403+ defer cache .mu .Unlock ()
404+ defer wg .Done ()
398405
399- resourceToDelete := resourcesToDeleted [0 ]
400- resourceToDeleteParts := strings .Split (resourcesToDeleted [0 ], "/" )
401- serviceName := resourceToDeleteParts [4 ]
402- zone := resourceToDeleteParts [5 ]
403- portString := strings .Split (resourcesToDeleted [0 ], "_" )[1 ]
404- claName := fmt .Sprintf ("xdstp://nexus/%s/%s/%s" , strings .Split (resource .EndpointType , "/" )[1 ], serviceName , portString )
406+ snapshot , ok := cache .snapshots [node ]
407+ if ! ok {
408+ return
409+ }
410+ prevResources := snapshot .(* Snapshot ).Resources [index ]
411+ newResources := false
412+ if prevResources .Items == nil {
413+ newResources = true
414+ prevResources .Items = make (map [string ]types.ResourceWithTTL )
415+ }
416+ currentVersion := cache .ParseSystemVersionInfo (prevResources .Version )
417+
418+ for k , v := range prevResources .Items {
419+ _ , ok := resourcesUpserted [k ]
420+ if newResources && ! ok {
421+ prevResources .Items [k ] = v
422+ } else if ! newResources && ! ok {
423+ delete (prevResources .Items , k )
424+ }
425+ }
426+ for k , v := range resourcesUpserted {
427+ _ , ok := prevResources .Items [k ]
428+ if ! ok {
429+ prevResources .Items [k ] = * v
430+ }
431+ }
432+ currentVersion ++
433+ prevResources .Version = fmt .Sprintf ("%d" , currentVersion )
405434
406- for node_ , snapshot := range cache .snapshots {
407- currentResources := snapshot .(* Snapshot ).Resources [types .Endpoint ]
408- if rsc , found := currentResources .Items [claName ]; found {
409- cla := rsc .Resource .(* endpoint.ClusterLoadAssignment )
410- for i , _ := range cla .Endpoints {
411- if cla .Endpoints [i ].Locality .Zone == zone {
412- newEndpoints := make ([]* endpoint.LbEndpoint , 0 )
413- for _ , lbEndpoint := range cla .Endpoints [i ].LbEndpoints {
414- if resourceToDelete == GetResourceName (lbEndpoint ) {
415- continue
416- }
417- newEndpoints = append (newEndpoints , lbEndpoint )
418- }
435+ // Update
436+ snapshot .(* Snapshot ).Resources [index ] = prevResources
437+ cache .snapshots [node ] = snapshot
419438
420- cla .Endpoints [i ].LbEndpoints = newEndpoints
439+ // Respond deltas
440+ if info , ok := cache .status [node ]; ok {
441+ info .mu .Lock ()
442+ defer info .mu .Unlock ()
443+
444+ // Respond to delta watches for the node.
445+ err := cache .respondDeltaWatches (ctx , info , snapshot )
446+ if err != nil {
447+ return
421448 }
422449 }
450+ }(node , r )
451+ }
452+ wg .Wait ()
423453
424- currentResources .Items [claName ] = types.ResourceWithTTL {
425- Resource : cla ,
426- }
454+ return nil
455+ }
456+
457+ func (cache * snapshotCache ) DeleteResources (ctx context.Context , node string , typ string , resourcesToDeleted []string ) error {
458+ cache .mu .Lock ()
459+ defer cache .mu .Unlock ()
460+
461+ if typ == resource .ClusterType {
462+ index := GetResponseType (typ )
463+ snapshot := cache .snapshots [node ]
464+ prevResources := snapshot .(* Snapshot ).Resources [index ]
465+ currentVersion := cache .ParseSystemVersionInfo (prevResources .Version )
466+
467+ for _ , k := range resourcesToDeleted {
468+ delete (prevResources .Items , k )
427469 }
428470
429- // Update
430- currentVersion := cache .ParseSystemVersionInfo (currentResources .Version )
431471 currentVersion ++
432- currentResources .Version = fmt .Sprintf ("%d" , currentVersion )
433-
434- snapshot .(* Snapshot ).Resources [types . Endpoint ] = currentResources
435- cache .snapshots [node_ ] = snapshot
472+ prevResources .Version = fmt .Sprintf ("%d" , currentVersion )
473+ // Update
474+ snapshot .(* Snapshot ).Resources [index ] = prevResources
475+ cache .snapshots [node ] = snapshot
436476
437477 // Respond deltas
438- if info , ok := cache .status [node_ ]; ok {
478+ if info , ok := cache .status [node ]; ok {
439479 info .mu .Lock ()
440- _ = cache .respondDeltaWatches (ctx , info , snapshot )
441- info .mu .Unlock ()
480+ defer info .mu .Unlock ()
481+
482+ // Respond to delta watches for the node.
483+ return cache .respondDeltaWatches (ctx , info , snapshot )
484+ }
485+
486+ } else if typ == resource .EndpointType {
487+ resourceToDelete := resourcesToDeleted [0 ]
488+ resourceToDeleteParts := strings .Split (resourcesToDeleted [0 ], "/" )
489+ serviceName := resourceToDeleteParts [4 ]
490+ zone := resourceToDeleteParts [5 ]
491+ portString := strings .Split (resourcesToDeleted [0 ], "_" )[1 ]
492+ claName := fmt .Sprintf ("xdstp://nexus/%s/%s/%s" , strings .Split (resource .EndpointType , "/" )[1 ], serviceName , portString )
493+
494+ for node_ , snapshot := range cache .snapshots {
495+ currentResources := snapshot .(* Snapshot ).Resources [types .Endpoint ]
496+ if rsc , found := currentResources .Items [claName ]; found {
497+ cla := rsc .Resource .(* endpoint.ClusterLoadAssignment )
498+ for i , _ := range cla .Endpoints {
499+ if cla .Endpoints [i ].Locality .Zone == zone {
500+ newEndpoints := make ([]* endpoint.LbEndpoint , 0 )
501+ for _ , lbEndpoint := range cla .Endpoints [i ].LbEndpoints {
502+ if resourceToDelete == GetResourceName (lbEndpoint ) {
503+ continue
504+ }
505+ newEndpoints = append (newEndpoints , lbEndpoint )
506+ }
507+
508+ cla .Endpoints [i ].LbEndpoints = newEndpoints
509+ }
510+ }
511+
512+ currentResources .Items [claName ] = types.ResourceWithTTL {
513+ Resource : cla ,
514+ }
515+ }
516+
517+ // Update
518+ currentVersion := cache .ParseSystemVersionInfo (currentResources .Version )
519+ currentVersion ++
520+ currentResources .Version = fmt .Sprintf ("%d" , currentVersion )
521+
522+ snapshot .(* Snapshot ).Resources [types .Endpoint ] = currentResources
523+ cache .snapshots [node_ ] = snapshot
524+
525+ // Respond deltas
526+ if info , ok := cache .status [node_ ]; ok {
527+ info .mu .Lock ()
528+ _ = cache .respondDeltaWatches (ctx , info , snapshot )
529+ info .mu .Unlock ()
530+ }
442531 }
443532 }
444533
0 commit comments