Skip to content

Commit

Permalink
Merge pull request #76 from davecheney/internal-envoy-cache-cleanup
Browse files Browse the repository at this point in the history
internal/envoy: refactor caches
  • Loading branch information
davecheney authored Dec 4, 2017
2 parents efac4e3 + cec5981 commit a44fab2
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 102 deletions.
110 changes: 36 additions & 74 deletions internal/envoy/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,16 @@ import (
v2 "github.com/envoyproxy/go-control-plane/api"
)

// ClusterCache represents a cache of computed *v2.Cluster objects.
type ClusterCache interface {
// Values returns a copy of the contents of the cache.
Values() []*v2.Cluster

// Add adds an entry to the cache. If a Cluster with the same
// name exists, it is replaced.
Add(*v2.Cluster)

// Remove removes the named entry from the cache. If the entry
// is not present in the cache, the operation is a no-op.
Remove(string)
}

// NewClusterCache returns a new ClusterCache.
func NewClusterCache() ClusterCache {
cc := make(clusterCache, 1)
cc <- nil // prime cache
return cc
}

// clusterCache is a thread safe, atomic, copy on write cache of *v2.Cluster objects.
type clusterCache chan []*v2.Cluster

// init must be called before clusterCache is used for the first time.
func (cc *clusterCache) init() {
*cc = make(clusterCache, 1)
*cc <- nil // prime cache
}

// Values returns a copy of the contents of the cache.
func (cc clusterCache) Values() []*v2.Cluster {
v := <-cc
r := make([]*v2.Cluster, len(v))
Expand All @@ -62,6 +48,8 @@ func (cc clusterCache) with(f func([]*v2.Cluster) []*v2.Cluster) {
cc <- v
}

// Add adds an entry to the cache. If a Cluster with the same
// name exists, it is replaced.
// TODO(dfc) make Add variadic to support atomic addition of several clusters
// also niladic Add can be used as a no-op notify for watchers.
func (cc clusterCache) Add(c *v2.Cluster) {
Expand All @@ -80,6 +68,8 @@ func (cc clusterCache) Add(c *v2.Cluster) {
})
}

// Remove removes the named entry from the cache. If the entry
// is not present in the cache, the operation is a no-op.
func (cc clusterCache) Remove(name string) {
cc.with(func(in []*v2.Cluster) []*v2.Cluster {
sort.Sort(clusterByName(in))
Expand All @@ -94,42 +84,20 @@ func (cc clusterCache) Remove(name string) {

type clusterByName []*v2.Cluster

func (c clusterByName) Len() int {
return len(c)
}

func (c clusterByName) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}

func (c clusterByName) Less(i, j int) bool {
return c[i].Name < c[j].Name
}

// ClusterLoadAssignemntCache represents a cache of computed *v2.ClusterLoadAssignment objects.
type ClusterLoadAssignmentCache interface {
// Values returns a copy of the contents of the cache.
Values() []*v2.ClusterLoadAssignment

// Add adds an entry to the cache. If a ClusterLoadAssignment with the same
// name exists, it is replaced.
Add(*v2.ClusterLoadAssignment)

// Remove removes the named entry from the cache. If the entry
// is not present in the cache, the operation is a no-op.
Remove(string)
}

// NewClusterLoadAssignmentCache returns a new ClusterLoadAssignmentCache.
func NewClusterLoadAssignmentCache() ClusterLoadAssignmentCache {
c := make(clusterLoadAssignmentCache, 1)
c <- nil // prime cache
return c
}
func (c clusterByName) Len() int { return len(c) }
func (c clusterByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c clusterByName) Less(i, j int) bool { return c[i].Name < c[j].Name }

// clusterLoadAssignmentCache is a thread safe, atomic, copy on write cache of v2.ClusterLoadAssignment objects.
type clusterLoadAssignmentCache chan []*v2.ClusterLoadAssignment

// init must be called before clusterCache is used for the first time.
func (c *clusterLoadAssignmentCache) init() {
*c = make(clusterLoadAssignmentCache, 1)
*c <- nil // prime cache
}

// Values returns a copy of the contents of the cache.
func (c clusterLoadAssignmentCache) Values() []*v2.ClusterLoadAssignment {
v := <-c
r := make([]*v2.ClusterLoadAssignment, len(v))
Expand All @@ -149,6 +117,8 @@ func (c clusterLoadAssignmentCache) with(f func([]*v2.ClusterLoadAssignment) []*
c <- v
}

// Add adds an entry to the cache. If a ClusterLoadAssignment with the same
// name exists, it is replaced.
// TODO(dfc) make Add variadic to support atomic addition of several clusters
// also niladic Add can be used as a no-op notify for watchers.
func (c clusterLoadAssignmentCache) Add(e *v2.ClusterLoadAssignment) {
Expand All @@ -165,6 +135,8 @@ func (c clusterLoadAssignmentCache) Add(e *v2.ClusterLoadAssignment) {
})
}

// Remove removes the named entry from the cache. If the entry
// is not present in the cache, the operation is a no-op.
func (c clusterLoadAssignmentCache) Remove(name string) {
c.with(func(in []*v2.ClusterLoadAssignment) []*v2.ClusterLoadAssignment {
sort.Sort(clusterLoadAssignmentsByName(in))
Expand Down Expand Up @@ -194,30 +166,16 @@ func (lc ListenerCache) Values() []*v2.Listener {
return r
}

// VirtualHostCache represents a cache of computed *v2.VirtualHost objects.
type VirtualHostCache interface {
// Values returns a copy of the contents of the cache.
Values() []*v2.VirtualHost

// Add adds an entry to the cache. If a VirtualHost with the same
// name exists, it is replaced.
Add(*v2.VirtualHost)

// Remove removes the named entry from the cache. If the entry
// is not present in the cache, the operation is a no-op.
Remove(string)
}

// NewVirtualHostCache returns a new VirtualHostCache.
func NewVirtualHostCache() VirtualHostCache {
v := make(virtualHostCache, 1)
v <- nil // prime cache
return v
}

// VirtualHostCache is a thread safe, atomic, copy on write cache of v2.VirtualHost objects.
type virtualHostCache chan []*v2.VirtualHost

// init must be called before clusterCache is used for the first time.
func (vc *virtualHostCache) init() {
*vc = make(virtualHostCache, 1)
*vc <- nil // prime cache
}

// Values returns a copy of the contents of the cache.
func (vc virtualHostCache) Values() []*v2.VirtualHost {
v := <-vc
r := make([]*v2.VirtualHost, len(v))
Expand All @@ -237,6 +195,8 @@ func (vc virtualHostCache) with(f func([]*v2.VirtualHost) []*v2.VirtualHost) {
vc <- v
}

// Add adds an entry to the cache. If a VirtualHost with the same
// name exists, it is replaced.
// TODO(dfc) make Add variadic to support atomic addition of several clusters
// also niladic Add can be used as a no-op notify for watchers.
func (vc virtualHostCache) Add(r *v2.VirtualHost) {
Expand All @@ -255,6 +215,8 @@ func (vc virtualHostCache) Add(r *v2.VirtualHost) {
})
}

// Remove removes the named entry from the cache. If the entry
// is not present in the cache, the operation is a no-op.
func (vc virtualHostCache) Remove(name string) {
vc.with(func(in []*v2.VirtualHost) []*v2.VirtualHost {
sort.Sort(virtualHostsByName(in))
Expand Down
63 changes: 42 additions & 21 deletions internal/envoy/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import (
)

func TestNewClusterCacheReturnsAnEmptySlice(t *testing.T) {
cc := NewClusterCache()
var cc clusterCache
cc.init()
got := cc.Values()
want := make([]*v2.Cluster, 0)
if !reflect.DeepEqual(got, want) {
Expand All @@ -31,7 +32,8 @@ func TestNewClusterCacheReturnsAnEmptySlice(t *testing.T) {
}

func TestClusterCacheValuesReturnsACopyOfItsInternalSlice(t *testing.T) {
cc := NewClusterCache()
var cc clusterCache
cc.init()
c := &v2.Cluster{
Name: "alpha",
}
Expand All @@ -48,7 +50,8 @@ func TestClusterCacheValuesReturnsACopyOfItsInternalSlice(t *testing.T) {
}

func TestClusterCacheValuesReturnsTheSameContents(t *testing.T) {
cc := NewClusterCache()
var cc clusterCache
cc.init()
c := &v2.Cluster{
Name: "alpha",
}
Expand All @@ -64,7 +67,8 @@ func TestClusterCacheValuesReturnsTheSameContents(t *testing.T) {
}

func TestClusterCacheAddInsertsTwoElementsInSortOrder(t *testing.T) {
cc := NewClusterCache()
var cc clusterCache
cc.init()
c1 := &v2.Cluster{
Name: "beta",
}
Expand All @@ -85,7 +89,8 @@ func TestClusterCacheAddInsertsTwoElementsInSortOrder(t *testing.T) {
}

func TestClusterCacheAddOverwritesElementsWithTheSameName(t *testing.T) {
cc := NewClusterCache()
var cc clusterCache
cc.init()
c1 := &v2.Cluster{
Name: "alpha",
Type: 1,
Expand All @@ -106,7 +111,8 @@ func TestClusterCacheAddOverwritesElementsWithTheSameName(t *testing.T) {
}

func TestClusterCacheAddIsCopyOnWrite(t *testing.T) {
cc := NewClusterCache()
var cc clusterCache
cc.init()
c1 := &v2.Cluster{
Name: "alpha",
}
Expand All @@ -125,7 +131,8 @@ func TestClusterCacheAddIsCopyOnWrite(t *testing.T) {
}

func TestClusterCacheRemove(t *testing.T) {
cc := NewClusterCache()
var cc clusterCache
cc.init()
c1 := &v2.Cluster{
Name: "alpha",
}
Expand All @@ -139,7 +146,8 @@ func TestClusterCacheRemove(t *testing.T) {
}

func TestNewClusterLoadAssignmentCacheReturnsAnEmptySlice(t *testing.T) {
cc := NewClusterLoadAssignmentCache()
var cc clusterLoadAssignmentCache
cc.init()
got := cc.Values()
want := make([]*v2.ClusterLoadAssignment, 0)
if !reflect.DeepEqual(got, want) {
Expand All @@ -149,7 +157,8 @@ func TestNewClusterLoadAssignmentCacheReturnsAnEmptySlice(t *testing.T) {
}

func TestClusterLoadAssignmentCacheValuesReturnsACopyOfItsInternalSlice(t *testing.T) {
cc := NewClusterLoadAssignmentCache()
var cc clusterLoadAssignmentCache
cc.init()
c := &v2.ClusterLoadAssignment{
ClusterName: "alpha",
}
Expand All @@ -166,7 +175,8 @@ func TestClusterLoadAssignmentCacheValuesReturnsACopyOfItsInternalSlice(t *testi
}

func TestClusterLoadAssignmentCacheValuesReturnsTheSameContents(t *testing.T) {
cc := NewClusterLoadAssignmentCache()
var cc clusterLoadAssignmentCache
cc.init()
c := &v2.ClusterLoadAssignment{
ClusterName: "alpha",
}
Expand All @@ -182,7 +192,8 @@ func TestClusterLoadAssignmentCacheValuesReturnsTheSameContents(t *testing.T) {
}

func TestClusterLoadAssignmentCacheAddInsertsTwoElementsInSortOrder(t *testing.T) {
cc := NewClusterLoadAssignmentCache()
var cc clusterLoadAssignmentCache
cc.init()
c1 := &v2.ClusterLoadAssignment{
ClusterName: "beta",
}
Expand All @@ -203,7 +214,8 @@ func TestClusterLoadAssignmentCacheAddInsertsTwoElementsInSortOrder(t *testing.T
}

func TestClusterLoadAssignmentCacheAddOverwritesElementsWithTheSameName(t *testing.T) {
cc := NewClusterLoadAssignmentCache()
var cc clusterLoadAssignmentCache
cc.init()
c1 := &v2.ClusterLoadAssignment{
ClusterName: "alpha",
Policy: &v2.ClusterLoadAssignment_Policy{
Expand All @@ -228,7 +240,8 @@ func TestClusterLoadAssignmentCacheAddOverwritesElementsWithTheSameName(t *testi
}

func TestClusterLoadAssignmentCacheAddIsCopyOnWrite(t *testing.T) {
cc := NewClusterLoadAssignmentCache()
var cc clusterLoadAssignmentCache
cc.init()
c1 := &v2.ClusterLoadAssignment{
ClusterName: "alpha",
}
Expand All @@ -247,7 +260,8 @@ func TestClusterLoadAssignmentCacheAddIsCopyOnWrite(t *testing.T) {
}

func TestClusterLoadAssignmentCacheRemove(t *testing.T) {
cc := NewClusterLoadAssignmentCache()
var cc clusterLoadAssignmentCache
cc.init()
c1 := &v2.ClusterLoadAssignment{
ClusterName: "alpha",
}
Expand All @@ -261,7 +275,8 @@ func TestClusterLoadAssignmentCacheRemove(t *testing.T) {
}

func TestNewVirtualHostCacheReturnsAnEmptySlice(t *testing.T) {
cc := NewVirtualHostCache()
var cc virtualHostCache
cc.init()
got := cc.Values()
want := make([]*v2.VirtualHost, 0)
if !reflect.DeepEqual(got, want) {
Expand All @@ -271,7 +286,8 @@ func TestNewVirtualHostCacheReturnsAnEmptySlice(t *testing.T) {
}

func TestVirtualHostCacheValuesReturnsACopyOfItsInternalSlice(t *testing.T) {
cc := NewVirtualHostCache()
var cc virtualHostCache
cc.init()
c := &v2.VirtualHost{
Name: "alpha",
}
Expand All @@ -288,7 +304,8 @@ func TestVirtualHostCacheValuesReturnsACopyOfItsInternalSlice(t *testing.T) {
}

func TestVirtualHostCacheValuesReturnsTheSameContents(t *testing.T) {
cc := NewVirtualHostCache()
var cc virtualHostCache
cc.init()
c := &v2.VirtualHost{
Name: "alpha",
}
Expand All @@ -304,7 +321,8 @@ func TestVirtualHostCacheValuesReturnsTheSameContents(t *testing.T) {
}

func TestVirtualHostCacheAddInsertsTwoElementsInSortOrder(t *testing.T) {
cc := NewVirtualHostCache()
var cc virtualHostCache
cc.init()
c1 := &v2.VirtualHost{
Name: "beta",
}
Expand All @@ -325,7 +343,8 @@ func TestVirtualHostCacheAddInsertsTwoElementsInSortOrder(t *testing.T) {
}

func TestVirtualHostCacheAddOverwritesElementsWithTheSameName(t *testing.T) {
cc := NewVirtualHostCache()
var cc virtualHostCache
cc.init()
c1 := &v2.VirtualHost{
Name: "alpha",
Domains: []string{
Expand All @@ -350,7 +369,8 @@ func TestVirtualHostCacheAddOverwritesElementsWithTheSameName(t *testing.T) {
}

func TestVirtualHostCacheAddIsCopyOnWrite(t *testing.T) {
cc := NewVirtualHostCache()
var cc virtualHostCache
cc.init()
c1 := &v2.VirtualHost{
Name: "alpha",
}
Expand All @@ -369,7 +389,8 @@ func TestVirtualHostCacheAddIsCopyOnWrite(t *testing.T) {
}

func TestVirtualHostCacheRemove(t *testing.T) {
cc := NewVirtualHostCache()
var cc virtualHostCache
cc.init()
c1 := &v2.VirtualHost{
Name: "alpha",
}
Expand Down
Loading

0 comments on commit a44fab2

Please sign in to comment.