Skip to content

Instantly share code, notes, and snippets.

@h09shais
Forked from kocubinski/FileSystemCache.cs
Created February 26, 2020 08:44
Show Gist options
  • Save h09shais/5e547de1113bd9a922caba6ca4d5a523 to your computer and use it in GitHub Desktop.
Save h09shais/5e547de1113bd9a922caba6ca4d5a523 to your computer and use it in GitHub Desktop.
A simple write-invalidated cache for JSON on the file system.
public interface ICache<out T>
{
T Get(string key);
}
public class CacheObject<T>
{
public T Value { get; set; }
public DateTime CachedDate { get; set; }
public CacheObject(T value, DateTime date)
{
Value = value;
CachedDate = date;
}
public CacheObject() { }
}
/// <summary>
/// A write-invalidated cache for JSON on the file system. Should be used in singleton scope per
/// container.
/// </summary>
/// <remarks>
/// Why? To prevent file system locks with concurrent read/write requests to the same file.
/// This way all read requests will route to memory, and that copy is safely invalidatied (lazily)
/// with .NET 4.5.1's thread-safe data stuctures when the file is changed on disk.
///
/// Of course that's why databases exist, but sometimes we don't need a db table.
/// </remarks>
public class FileSystemCache<T> : ICache<T>
{
private readonly ConcurrentDictionary<string, CacheObject<T>> _store =
new ConcurrentDictionary<string, CacheObject<T>>();
public static T FromFile(string f)
{
var config = JsonConvert.DeserializeObject<T>(File.ReadAllText(f));
return config;
}
public T Get(string f)
{
f = f.Replace('\\', '/');
CacheObject<T> config;
if (_store.TryGetValue(f, out config)
&& File.GetLastWriteTime(f) < config.CachedDate)
return config.Value;
var c = FromFile(f);
config = new CacheObject<T>(c, DateTime.Now);
_store[f] = config;
return c;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment