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 }