Skip to content

Commit

Permalink
Merge pull request #104 from sebslsch/master
Browse files Browse the repository at this point in the history
Fixed concurrency errors in MemoryCache when using dotnetcore
  • Loading branch information
gautema committed Jul 24, 2020
2 parents 0d6bb8a + ed67ad7 commit b1ad794
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using CQRSlite.Caching;
using CQRSlite.Domain;
using CQRSlite.Tests.Substitutes;
using Xunit;

namespace CQRSlite.Tests.Caching
{
public class When_creating_and_using_repositories_in_parallel
{
private readonly TestInMemoryEventStore _testStore;

private readonly ICache _cache;

private Exception _exception;

public When_creating_and_using_repositories_in_parallel()
{
_testStore = new TestInMemoryEventStore();
_cache = new CQRSlite.Caching.MemoryCache();

int numberOfAggregates = 10;
int numberOfIterations = 200;

Task[] tasks = Enumerable.Range(0, numberOfAggregates).Select(_ => Task.Run(async () =>
{
var aggregateId = Guid.NewGuid();
for (int iteration = 0; iteration < numberOfIterations; iteration++)
{
var cacheRepository = new CacheRepository(new Repository(_testStore), _testStore, _cache);
await cacheRepository.Save(new TestAggregate(aggregateId));
}
})).ToArray();

_exception = Record.Exception(() => Task.WaitAll(tasks));
}

[Fact]
public void Should_not_cause_concurrency_issues()
{
Assert.Null(_exception);
}
}
}
23 changes: 16 additions & 7 deletions Framework/CQRSlite/Caching/MemoryCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Runtime.Caching;
#else
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
#endif

namespace CQRSlite.Caching
Expand All @@ -18,7 +19,7 @@ public class MemoryCache : ICache
private readonly System.Runtime.Caching.MemoryCache _cache;
private Func<CacheItemPolicy> _policyFactory;
#else
private readonly MemoryCacheEntryOptions _cacheOptions;
private Func<MemoryCacheEntryOptions> _optionsFactory;
private readonly IMemoryCache _cache;
#endif

Expand All @@ -31,7 +32,7 @@ public MemoryCache()
SlidingExpiration = TimeSpan.FromMinutes(15)
};
#else
_cacheOptions = new MemoryCacheEntryOptions
_optionsFactory = () => new MemoryCacheEntryOptions
{
SlidingExpiration = TimeSpan.FromMinutes(15)
};
Expand All @@ -54,7 +55,7 @@ public Task Set(Guid id, AggregateRoot aggregate)
#if NET452
_cache.Add(id.ToString(), aggregate, _policyFactory.Invoke());
#else
_cache.Set(id, aggregate, _cacheOptions);
_cache.Set(id, aggregate, _optionsFactory.Invoke());
#endif
return Task.FromResult(0);
}
Expand All @@ -64,7 +65,7 @@ public Task<AggregateRoot> Get(Guid id)
#if NET452
return Task.FromResult((AggregateRoot)_cache.Get(id.ToString()));
#else
return Task.FromResult((AggregateRoot) _cache.Get(id));
return Task.FromResult((AggregateRoot)_cache.Get(id));
#endif
}

Expand All @@ -90,10 +91,18 @@ public void RegisterEvictionCallback(Action<Guid> action)
}
};
#else
_cacheOptions.RegisterPostEvictionCallback((key, value, reason, state) =>
_optionsFactory = _optionsFactory = () =>
{
action.Invoke((Guid) key);
});
var options = new MemoryCacheEntryOptions
{
SlidingExpiration = TimeSpan.FromMinutes(15)
};
options.RegisterPostEvictionCallback((key, value, reason, state) =>
{
action.Invoke((Guid)key);
});
return options;
};
#endif
}
}
Expand Down

0 comments on commit b1ad794

Please sign in to comment.