Skip to content

Using In Memory Cache

scale-tone edited this page Apr 16, 2017 · 3 revisions

To use this feature, it only takes you to provide an instance of cache implementation to DataContext.GetTable<TEntity>() method:

public class ReviewsDataContext : DataContext
{
    private static readonly AmazonDynamoDB DynamoDbClient;
    private static readonly MemcachedClient CacheClient;

    static ReviewsDataContext()
    {
        string accessKey, secretKey;
        GetAwsCredentials(out accessKey, out secretKey);
        DynamoDbClient = new AmazonDynamoDBClient(accessKey, secretKey);

        CacheClient = new MemcachedClient();
    }

    public ReviewsDataContext() 
        : 
        base(DynamoDbClient, GetTableNamePrefixFromConfig())
    {
    }

    public DataTable<Movie> Movies
    {
        get
        {
            return this.GetTable<Movie>
            (
                () => new EnyimTableCache(CacheClient, TimeSpan.FromHours(1))
            );
        }
    }

    public DataTable<Review> Reviews
    {
        get
        {
            return this.GetTable<Review>
            (
                () => new EnyimTableCache(CacheClient, TimeSpan.FromMinutes(10))
            );
        }
    }
}

Starting from version 2.0.0, LINQ2DynamoDB provides two cache implementations - for MemcacheD and Redis (that means, for both AWS ElastiCache options). You can (and encouraged to!) provide your own ITableCache implementation, which might store cached entities and indexes in any other way.

NOTE: ITableCache implementations are again lightweight yet not guaranteed to be thread-safe. There should be a separate instance of it for each table in your context.

The second parameter in any ITableCache impementation's constructor specifies the TTL for the entities stored in cache. Depending on how much static your data is, you might choose different TTL values for different tables. But in general it's still not a good idea to set this value to TimeSpan.MaxValue: in very rare cases temporary network errors still can lead to inconsistencies between cache and DynamoDB.

A short explanation of what is actually cached is here.

NOTE: to see, what happens under the hood, add logging to your ITableCache instance:

public DataTable<Reviewer> Reviewers
{
    get
    {
        return this.GetTable<Reviewer>(() =>
        {
            var cache = new EnyimTableCache(CacheClient, TimeSpan.FromDays(1));
            cache.OnLog += s => Debug.WriteLine("{0} {1}", DateTime.Now, s);
            return cache;
        });
    }
}