Skip to content

Instantly share code, notes, and snippets.

@ctigeek
Created March 30, 2020 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctigeek/76dabcc7901fdf1eebad7c7f6338221a to your computer and use it in GitHub Desktop.
Save ctigeek/76dabcc7901fdf1eebad7c7f6338221a to your computer and use it in GitHub Desktop.
public interface IGenericCache<T>
{
TimeSpan CacheTtl { get; set; }
Func<T> LoadCache { get; set; }
T ReturnCache();
T ForceRefresh();
}
public class GenericCache<T> : IGenericCache<T>
{
private readonly object lockobject = new object();
private T cache = default(T);
private DateTime cacheRefresh = DateTime.MinValue;
public TimeSpan CacheTtl { get; set; } = TimeSpan.FromMinutes(1);
public Func<T> LoadCache { get; set; }
public T ForceRefresh()
{
lock (lockobject)
{
if (DateTime.Now.Subtract(cacheRefresh) > CacheTtl)
{
var tempCache = LoadCache();
if (tempCache != null)
{
cacheRefresh = DateTime.Now;
cache = tempCache;
}
}
}
return cache;
}
public T ReturnCache()
{
if (cache == null || DateTime.Now.Subtract(cacheRefresh) > CacheTtl)
{
ForceRefresh();
}
return cache;
}
}
[TestFixture, Explicit("These tests have intentional delays in them.")]
public class GenericCacheTests
{
private GenericCache<string[]> cache;
private bool loadCacheCalled;
[SetUp]
public void Setup()
{
cache = new GenericCache<string[]>();
cache.CacheTtl = TimeSpan.FromSeconds(5);
cache.LoadCache = this.LoadCache;
cache.ForceRefresh();
loadCacheCalled = false;
}
private string[] LoadCache()
{
loadCacheCalled = true;
return new[] {"hi", "there", "you", "amazing", "canteloupe"};
}
[Test]
public void ItReturnsValuesFromCacheAndThenReloadsAfterTtlAndThenReturnsFromCacheAgain()
{
var values = cache.ReturnCache();
Assert.That(values.Length, Is.EqualTo(5));
Assert.That(loadCacheCalled, Is.False);
Thread.Sleep(6000);
values = cache.ReturnCache();
Assert.That(values.Length, Is.EqualTo(5));
Assert.That(loadCacheCalled, Is.True);
loadCacheCalled = false;
values = cache.ReturnCache();
Assert.That(values.Length, Is.EqualTo(5));
Assert.That(loadCacheCalled, Is.False);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment