github.com/imran-kn/cilium-fork@v1.6.9/pkg/envoy/xds/set.go (about)

     1  // Copyright 2018 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package xds
    16  
    17  import (
    18  	"context"
    19  
    20  	"github.com/cilium/cilium/pkg/lock"
    21  
    22  	"github.com/golang/protobuf/proto"
    23  )
    24  
    25  // ResourceSource provides read access to a versioned set of resources.
    26  // A single version is associated to all the contained resources.
    27  // The version is monotonically increased for any change to the set.
    28  type ResourceSource interface {
    29  	// GetResources returns the current version of the resources with the given
    30  	// names.
    31  	// If lastVersion is not nil and the resources with the given names haven't
    32  	// changed since lastVersion, nil is returned.
    33  	// If resourceNames is empty, all resources are returned.
    34  	// Should not be blocking.
    35  	GetResources(ctx context.Context, typeURL string, lastVersion uint64,
    36  		nodeIP string, resourceNames []string) (*VersionedResources, error)
    37  
    38  	// EnsureVersion increases this resource set's version to be at least the
    39  	// given version. If the current version is already higher than the
    40  	// given version, this has no effect.
    41  	EnsureVersion(typeURL string, version uint64)
    42  }
    43  
    44  // VersionedResources is a set of protobuf-encoded resources along with their
    45  // version.
    46  type VersionedResources struct {
    47  	// Version is the version of the resources.
    48  	Version uint64
    49  
    50  	// ResourceNames is the list of names of resources.
    51  	// May be empty.
    52  	ResourceNames []string
    53  
    54  	// Resources is the list of protobuf-encoded resources.
    55  	// May be empty. Must be of the same length as ResourceNames.
    56  	Resources []proto.Message
    57  
    58  	// Canary indicates whether the client should only do a dry run of
    59  	// using  the resources.
    60  	Canary bool
    61  }
    62  
    63  // ResourceMutatorRevertFunc is a function which reverts the effects of an update on a
    64  // ResourceMutator.
    65  // The returned version value is the set's version after update.
    66  type ResourceMutatorRevertFunc func() (version uint64, updated bool)
    67  
    68  // ResourceMutator provides write access to a versioned set of resources.
    69  // A single version is associated to all the contained resources.
    70  // The version is monotonically increased for any change to the set.
    71  type ResourceMutator interface {
    72  	// Upsert inserts or updates a resource from this set by name.
    73  	// If the set is modified (the resource is actually inserted or updated),
    74  	// the set's version number is incremented atomically and the returned
    75  	// updated value is true.
    76  	// Otherwise, the version number is not modified and the returned updated
    77  	// value is false.
    78  	// The returned version value is the set's version after update.
    79  	// A call to the returned revert function reverts the effects of this
    80  	// method call.
    81  	Upsert(typeURL string, resourceName string, resource proto.Message) (version uint64, updated bool, revert ResourceMutatorRevertFunc)
    82  
    83  	// Delete deletes a resource from this set by name.
    84  	// If the set is modified (the resource is actually deleted), the set's
    85  	// version number is incremented atomically and the returned updated value
    86  	// is true.
    87  	// Otherwise, the version number is not modified and the returned updated
    88  	// value is false.
    89  	// The returned version value is the set's version after update.
    90  	// A call to the returned revert function reverts the effects of this
    91  	// method call.
    92  	Delete(typeURL string, resourceName string) (version uint64, updated bool, revert ResourceMutatorRevertFunc)
    93  
    94  	// Clear deletes all the resources of the given type from this set.
    95  	// If the set is modified (at least one resource is actually deleted),
    96  	// the set's version number is incremented atomically and the returned
    97  	// updated value is true.
    98  	// Otherwise, the version number is not modified and the returned updated
    99  	// value is false.
   100  	// The returned version value is the set's version after update.
   101  	// This method call cannot be reverted.
   102  	Clear(typeURL string) (version uint64, updated bool)
   103  }
   104  
   105  // ResourceSet provides read-write access to a versioned set of resources.
   106  // A single version is associated to all the contained resources.
   107  // The version is monotonically increased for any change to the set.
   108  type ResourceSet interface {
   109  	ResourceSource
   110  	ResourceMutator
   111  }
   112  
   113  // ObservableResourceSource is a ResourceSource that allows registering observers of
   114  // new resource versions from this source.
   115  type ObservableResourceSource interface {
   116  	ResourceSource
   117  
   118  	// AddResourceVersionObserver registers an observer of new versions of
   119  	// resources from this source.
   120  	AddResourceVersionObserver(listener ResourceVersionObserver)
   121  
   122  	// RemoveResourceVersionObserver unregisters an observer of new versions of
   123  	// resources from this source.
   124  	RemoveResourceVersionObserver(listener ResourceVersionObserver)
   125  }
   126  
   127  // ObservableResourceSet is a ResourceSet that allows registering observers of
   128  // new resource versions from this source.
   129  type ObservableResourceSet interface {
   130  	ObservableResourceSource
   131  	ResourceMutator
   132  }
   133  
   134  // ResourceVersionObserver defines the HandleNewResourceVersion method which is
   135  // called whenever the version of the resources of a given type has changed.
   136  type ResourceVersionObserver interface {
   137  	// HandleNewResourceVersion notifies of a new version of the resources of
   138  	// the given type.
   139  	HandleNewResourceVersion(typeURL string, version uint64)
   140  }
   141  
   142  // BaseObservableResourceSource implements the AddResourceVersionObserver and
   143  // RemoveResourceVersionObserver methods to handle the notification of new
   144  // resource versions. This is meant to be used as a base to implement
   145  // ObservableResourceSource.
   146  type BaseObservableResourceSource struct {
   147  	// locker is the locker used to synchronize all accesses to this source.
   148  	locker lock.RWMutex
   149  
   150  	// observers is the set of registered observers.
   151  	observers map[ResourceVersionObserver]struct{}
   152  }
   153  
   154  // NewBaseObservableResourceSource initializes the given set.
   155  func NewBaseObservableResourceSource() *BaseObservableResourceSource {
   156  	return &BaseObservableResourceSource{
   157  		observers: make(map[ResourceVersionObserver]struct{}),
   158  	}
   159  }
   160  
   161  // AddResourceVersionObserver registers an observer to be notified of new
   162  // resource version.
   163  func (s *BaseObservableResourceSource) AddResourceVersionObserver(observer ResourceVersionObserver) {
   164  	s.locker.Lock()
   165  	defer s.locker.Unlock()
   166  
   167  	s.observers[observer] = struct{}{}
   168  }
   169  
   170  // RemoveResourceVersionObserver unregisters an observer that was previously
   171  // registered by calling AddResourceVersionObserver.
   172  func (s *BaseObservableResourceSource) RemoveResourceVersionObserver(observer ResourceVersionObserver) {
   173  	s.locker.Lock()
   174  	defer s.locker.Unlock()
   175  
   176  	delete(s.observers, observer)
   177  }
   178  
   179  // NotifyNewResourceVersionRLocked notifies registered observers that a new version of
   180  // the resources of the given type is available.
   181  // This function MUST be called with locker's lock acquired.
   182  func (s *BaseObservableResourceSource) NotifyNewResourceVersionRLocked(typeURL string, version uint64) {
   183  	for o := range s.observers {
   184  		o.HandleNewResourceVersion(typeURL, version)
   185  	}
   186  }