diff --git a/pkg/master/ip_cache.go b/pkg/master/ip_cache.go index 35621384d71..05a59c647c2 100644 --- a/pkg/master/ip_cache.go +++ b/pkg/master/ip_cache.go @@ -36,16 +36,21 @@ type ipCache struct { cloudProvider cloudprovider.Interface cache map[string]ipCacheEntry lock sync.Mutex + ttl time.Duration } // NewIPCache makes a new ip caching layer, which will get IP addresses from cp, // and use clock for deciding when to re-get an IP address. // Thread-safe. -func NewIPCache(cp cloudprovider.Interface, clock util.Clock) *ipCache { +// +// TODO: when we switch to go1.4, this class would be a good candidate for something +// that could be produced from a template and a type via `go generate`. +func NewIPCache(cp cloudprovider.Interface, clock util.Clock, ttl time.Duration) *ipCache { return &ipCache{ clock: clock, cloudProvider: cp, cache: map[string]ipCacheEntry{}, + ttl: ttl, } } @@ -57,7 +62,7 @@ func (c *ipCache) GetInstanceIP(host string) string { data, ok := c.cache[host] now := c.clock.Now() - if !ok || now.Sub(data.lastUpdate) > (30*time.Second) { + if !ok || now.Sub(data.lastUpdate) > c.ttl { ip := getInstanceIPFromCloud(c.cloudProvider, host) data = ipCacheEntry{ ip: ip, diff --git a/pkg/master/ip_cache_test.go b/pkg/master/ip_cache_test.go index 9b3cd487707..6e8139b88e8 100644 --- a/pkg/master/ip_cache_test.go +++ b/pkg/master/ip_cache_test.go @@ -28,16 +28,32 @@ func TestCacheExpire(t *testing.T) { fakeCloud := &fake_cloud.FakeCloud{} clock := &util.FakeClock{time.Now()} - c := NewIPCache(fakeCloud, clock) + c := NewIPCache(fakeCloud, clock, 60*time.Second) _ = c.GetInstanceIP("foo") // This call should hit the cache, so we expect no additional calls to the cloud _ = c.GetInstanceIP("foo") // Advance the clock, this call should miss the cache, so expect one more call. - clock.Time = clock.Time.Add(60 * time.Second) + clock.Time = clock.Time.Add(61 * time.Second) _ = c.GetInstanceIP("foo") if len(fakeCloud.Calls) != 2 || fakeCloud.Calls[1] != "ip-address" || fakeCloud.Calls[0] != "ip-address" { t.Errorf("Unexpected calls: %+v", fakeCloud.Calls) } } + +func TestCacheNotExpire(t *testing.T) { + fakeCloud := &fake_cloud.FakeCloud{} + clock := &util.FakeClock{time.Now()} + + c := NewIPCache(fakeCloud, clock, 60*time.Second) + + _ = c.GetInstanceIP("foo") + // This call should hit the cache, so we expect no additional calls to the cloud + clock.Time = clock.Time.Add(60 * time.Second) + _ = c.GetInstanceIP("foo") + + if len(fakeCloud.Calls) != 1 || fakeCloud.Calls[0] != "ip-address" { + t.Errorf("Unexpected calls: %+v", fakeCloud.Calls) + } +} diff --git a/pkg/master/master.go b/pkg/master/master.go index b8c55b57248..ca489f9a84d 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -323,7 +323,7 @@ func (m *Master) init(c *Config) { var authenticator = c.Authenticator nodeRESTStorage := minion.NewREST(m.minionRegistry) - ipCache := NewIPCache(c.Cloud, util.RealClock{}) + ipCache := NewIPCache(c.Cloud, util.RealClock{}, 30*time.Second) podCache := NewPodCache( ipCache, c.KubeletClient,