Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CouchbaseCache modifies meta.expiration value of a document during cache read operation #114

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sonobo
Copy link

@sonobo sonobo commented May 31, 2024

CouchbaseCache class that implements standard IDistributedCache interface overwrites meta.expiration on every cache read.
IMO this is incorrect behavior and it leads to lots of surprises and not consistent with other popular implementation like StackExchange.Redis.

The problem comes from this explicit interface implementation method:

        async Task<byte[]?> IDistributedCache.GetAsync(string key, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var collection = await CollectionProvider.GetCollectionAsync().ConfigureAwait(false);

            try
            {
                var result = await collection.GetAndTouchAsync(key, Options.LifeSpan.GetValueOrDefault(),
                        new GetAndTouchOptions().Transcoder(_transcoder))
                    .ConfigureAwait(false);
                return result.ContentAs<byte[]>();
            }
            catch (DocumentNotFoundException)
            {
                return null;
            }
        }

There's no obvious explanation of why collection.GetAndTouchAsync() is used instead of collection.GetAsync() plus passing Options.LifeSpan.GetValueOrDefault() simply resets the cache lifetime to 20 minutes on every cache read.

In many real use cases cache entry lifetime is selected carefully depending on what data is cached and absolute expiration datetime should be preserved.

Can we just remove explicit interface implementation and just keep GetAsync() insteadl? As far as I can see it also handled DocumentNotFoundException and returns null to indicate that there's no entity in the case which is already inline with expected behavior of IDistributedCache.GetAsync().

@brantburnett
Copy link
Collaborator

There is actually a complete rewrite of this library in progress to properly follow the IDistributedCache specification, especially around sliding expirations. Could you check this working branch and see if it would also address your concerns?

https://github.com/couchbaselabs/Couchbase.Extensions/tree/caching-rewrite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants