Closed Amberg closed 2 months ago
Hi @Amberg , I think you may have a point here... let me do some checks, will get back to you as soon as possible.
Hi @Amberg , I think you may have a point here... let me do some checks, will get back to you as soon as possible.
Thank you It seems to set the Size in the DefaultOptions does not help.
If i can support you somehow, let me know.
Hi @Amberg , thanks! I'm working on this, will update during the weekend.
Hi @Amberg , I've added support for this.
Here's the test that verify this:
[Theory]
[ClassData(typeof(SerializerTypesClassData))]
public async Task CanUseMultiNodeCachesWithSizeLimitAsync(SerializerType serializerType)
{
var backplaneConnectionId = Guid.NewGuid().ToString("N");
var key1 = Guid.NewGuid().ToString("N");
var key2 = Guid.NewGuid().ToString("N");
var distributedCache = CreateDistributedCache();
using var memoryCache1 = new MemoryCache(new MemoryCacheOptions()
{
SizeLimit = 10
});
using var memoryCache2 = new MemoryCache(new MemoryCacheOptions()
{
SizeLimit = 10
});
using var memoryCache3 = new MemoryCache(new MemoryCacheOptions()
{
//SizeLimit = 10
});
using var cache1 = CreateFusionCache(null, serializerType, distributedCache, CreateBackplane(backplaneConnectionId), memoryCache: memoryCache1);
using var cache2 = CreateFusionCache(null, serializerType, distributedCache, CreateBackplane(backplaneConnectionId), memoryCache: memoryCache2);
using var cache3 = CreateFusionCache(null, serializerType, distributedCache, CreateBackplane(backplaneConnectionId), memoryCache: memoryCache3);
// SET THE ENTRY (WITH SIZE) ON CACHE 1 (WITH SIZE LIMIT)
await cache1.SetAsync(key1, 1, options => options.SetSize(1));
await Task.Delay(1_000);
// GET THE ENTRY (WITH SIZE) ON CACHE 2 (WITH SIZE LIMIT)
var maybe2 = await cache2.TryGetAsync<int>(key1);
Assert.True(maybe2.HasValue);
Assert.Equal(1, maybe2.Value);
// SET THE ENTRY (WITH NO SIZE) ON CACHE 3 (WITH NO SIZE LIMIT)
await cache3.SetAsync(key2, 2);
await Task.Delay(1_000);
// GET THE ENTRY (WITH NO SIZE) ON CACHE 1 (WITH SIZE LIMIT)
// -> FALLBACK TO THE SIZE IN THE ENTRY OPTIONS
var maybe1 = await cache1.TryGetAsync<int>(key2, options => options.SetSize(1));
Assert.True(maybe1.HasValue);
Assert.Equal(2, maybe1.Value);
}
The first part (first 2 Assert
s) verifies that setting an entry WITH a specific size on a cache WITH size limit, and then getting the same entry from another cache (WITH size limit, too) works, meaning it restores the entry with its size.
This is the "normal" situation.
The second part (second 2 Assert
s) verifies that setting an entry WITHOUT a specific size on a cache WITHOUT a size limit, and then getting the same entry from another cache (but WITH size limit) works if there's at least a Size
specified in the entry options (either for the specific method call or in the DefaultEntryOptions
).
This is more of an edge case, since usually what is logically the same cache should be configured the same for every instance (a.k.a. on every node).
Let me know what you think.
Will include in the next version, releasing probably tomorrow.
That looks rock solid and really promising
Thanks for the great work
Hi, v1.4.0 has been released 🥳
Problem
The entry size is not stored in Distributed cache.
Solution
Store the calculated cache entry size in the distributed cache.
Alternatives
A callback function to recalculate the entry size whenever it is loaded from the distributed cache.
Additional context
I am attempting to use the Distributed Cache with a defined SizeLimit to manage memory usage effectively. However, this results in the following exception:
System.InvalidOperationException: Cache entry must specify a value for Size when SizeLimit is set
Because theSizeLimit
calculated during entry creation (adaptive caching) is not stored in the distributed cache.Workaround
The only workaround I've found is setting an approximate size in the DefaultOptions. Unfortunately, this approach leads to imprecise memory limits, especially when the sizes of cached objects vary significantly.
Is there another way or best practice to manage different cache entry sizes while using a MemoryCache with SizeLimit set?