Skip to content

Cache compaction will never start #59875

@mapogolions

Description

@mapogolions

I've noticed that there are cases where cache compaction does not affect the cache size, even if capacity is exceeded.
Let's look at the following test case

        [Fact]
        public async Task CompactionWillNeverStart()
        {
            var cache = new MemoryCache(new MemoryCacheOptions
            {
                ExpirationScanFrequency = TimeSpan.Zero,
                SizeLimit = 10,
                CompactionPercentage = 0.1
            });

            var entryOptions = new MemoryCacheEntryOptions { Size = 6 };
            var sem = new SemaphoreSlim(0, 1);
            entryOptions.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration
            {
                EvictionCallback = (k, v, r, s) => sem.Release(),
                State = null
            });

            Assert.Equal(0, cache.Size);

            cache.Set("key", "value", entryOptions);

            Assert.Equal("value", cache.Get("key"));
            Assert.Equal(6, cache.Size);

            cache.Set("key2", "value2", new MemoryCacheEntryOptions { Size = 6 });

            // Wait for compaction to complete
            Assert.True(await sem.WaitAsync(TimeSpan.FromSeconds(10)));

            Assert.Null(cache.Get("key"));
            Assert.Null(cache.Get("key2"));
            Assert.Equal(0, cache.Size);
        }

This test will fail.
After adding the first entry, the cache size will be equal to 6. Attempting to add a second entry will trigger cache compaction. However, the running process will not free some space for adding entries in the future, because current cache size(6) is less than low water mark value (9) Thus, the cache will have a fixed internal state for some time and will not change it until the records stored in it are deleted in one of the possible ways. (expired or removed).

The same is true for less obvious input data.
Size Limit = 70; Compaction percentage = 0.05; Low water mark = 66.5, Current Size = 66 (11 items (6 conventional units each) have been added )

Could you please share your opinion about it

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions