Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

How to remove groups of entries #48

Closed
ghost opened this issue Mar 10, 2015 · 12 comments
Closed

How to remove groups of entries #48

ghost opened this issue Mar 10, 2015 · 12 comments
Labels

Comments

@ghost
Copy link

ghost commented Mar 10, 2015

I look into the test project, How can I get all the keys?

@Tratcher
Copy link
Member

That's not supported in the current design.

@ghost
Copy link
Author

ghost commented Mar 11, 2015

Btw how to solved if i want to delete all the keys that start with "SOMEKEY.*"?

In the current .net 4 memoryobject usually i get allthekey then check the regex then remove the key.

@Tratcher
Copy link
Member

I recommend using shared cache triggers or cache entry links to remove groups of items.

Triggers: Create a trigger and assign it to each item in the group. Fire the trigger when you want to remove all the items.
https://github.com/aspnet/Caching/blob/dev/samples/MemoryCacheSample/Program.cs#L90

Entry links: Create one item that is the root item. Use EntryLink's to make all other items depend on that one. When you want to remove all the items just remove the root item and the rest will be removed automatically.
https://github.com/aspnet/Caching/blob/dev/samples/MemoryCacheSample/Program.cs#L96

@ghost
Copy link
Author

ghost commented Mar 14, 2015

most of the time people store the key is in this format.
ex:

Keys:
[product].[tablename].{whatever}
membersite.language.all
membersite.language.id-{0}
membersite.language.iso-{0}
membersite.language.index-{0}.pagesize-{1}

When we want to perform CRUD operation
READ
//Most of the time we set the key

CREATE, UPDATE, DELETE
//Remove all the keys that startwith membersite.language.

Q1. Can you explain how that the pattern using trigger & entry links for above case.
Q2. Why we do not expose all the keys?

@Tratcher
Copy link
Member

A2: The cache is considered highly unstable where entries could expire or be removed at any time. This would make simple code like the following unreliable.

foreach (var key in cache.Keys)
{
  var value = cache.Get(key);
  // ...
}

A1:

Bulk remove with shared expiration triggers:

// Remove on trigger
var cts = new CancellationTokenSource();
var sharedTrigger = new CancellationTokenTrigger(cts.Token);
cache.Set("key.a", context =>
{
  context.AddExpirationTrigger(sharedTrigger);
  return "value a";
});
cache.Set("key.b", context =>
{
  context.AddExpirationTrigger(sharedTrigger);
  return "value b";
});
// ...
// Remove all entries
cts.Cancel();

Bulk remove with EntryLinks:

cache.Set("Parent Key", "Parent Value");
var link = new EntryLink();
var parentValue = cache.Get("Parent Key", link);
result = cache.Set("Dependent Key", context =>
{
  context.AddEntryLink(link);
  return "Dependent Value";
});
// ...
cache.Remove("Parent Key"); // Also removes linked "Dependent Key"

@ghost
Copy link
Author

ghost commented Mar 17, 2015

Remove on Trigger - Is work fine to delete all keys.

I got error on EntryLinks

        var cache = new MemoryCache(new MemoryCacheOptions() {
            ListenForMemoryPressure = false
        });

        cache.Set("membersite.language.", "Language Pattern");
        var link = new EntryLink();
        var parentValue = cache.Get("membersite.language.", link);
        Assert.Equal("Language Pattern", parentValue);
        var result = cache.Set("membersite.language.id-1", context =>
        {
            context.AddEntryLink(link);
            return "en-US";
        });

        cache.Set("membersite.currency.", "Currency Pattern");
        link = new EntryLink();
        parentValue = cache.Get("membersite.currency.", link);
        Assert.Equal("Currency Pattern", parentValue);
        result = cache.Set("membersite.currency.id-1", context => {
            context.AddEntryLink(link);
            return "RMB";
        });

        var currency = cache.Get<string>("membersite.currency.id-1");
        Assert.Equal("RMB", currency);

        var language = cache.Get<string>("membersite.language.id-1");
        Assert.Equal("en-US", language);

        //Remove all the key start with membersite.currency.
        cache.Remove("membersite.language.");

        parentValue = cache.Get<string>("membersite.language.");
        Assert.Null(parentValue);

        language = cache.Get<string>("membersite.language.id-1");
        Console.WriteLine("Language: " + language);
        //How come the dependent key still there?
        Assert.Null(language);

        currency = cache.Get<string>("membersite.currency.id-1");
        Assert.Equal("RMB",currency);

From k test result
Membersite.Core.Tests.CacheTest.CacheEntryLink [FAIL]
Assert.Null() Failure
Expected: (null)
Actual: en-US

@Tratcher
Copy link
Member

@Praburaj Can you run this and see what I did wrong?

@Praburaj
Copy link
Contributor

@Tratcher I'll give it a try.

@ghost
Copy link
Author

ghost commented Apr 1, 2015

@Tratcher @Praburaj any updated on this one?

@Tratcher Tratcher changed the title GetAllKeys How to remove groups of entries Apr 1, 2015
@Tratcher
Copy link
Member

Tratcher commented Apr 1, 2015

Ok, now I remember how entry links work. They don't create a direct link between keys, they instead copy any existing expiration information (triggers or timers) from the parent key to any sub keys.

            // Remove on trigger
            var cts = new CancellationTokenSource();
            result = cache.GetOrSet("Parent Key", state, context =>
            {
                context.AddExpirationTrigger(new CancellationTokenTrigger(cts.Token));
                return "Parent Value";
            });

            result = cache.Set("Dependent Key", context =>
            {
                // Share the CancellationTokenTrigger via EntryLink
                var link = new EntryLink();
                var parentValue = cache.Get("Parent Key", link);
                context.AddEntryLink(link);
                return "Dependent Value" + parentValue;
            });
            // ...
            Console.WriteLine(cache.Get("Dependent Key"));
            cts.Cancel(); // Also removes linked "Dependent Key"
            Console.WriteLine(cache.Get("Dependent Key"));

@ghost
Copy link
Author

ghost commented Apr 10, 2015

@Tratcher are you able to change the example test that i write?
cause the example of your code it hard to figure it out.

Appreciate your help

@Tratcher
Copy link
Member

            var cache = new MemoryCache(new MemoryCacheOptions()
            {
                ListenForMemoryPressure = false
            });

            var langCts = new CancellationTokenSource();
            cache.Set("membersite.language.", ctx =>
            {
                ctx.AddExpirationTrigger(new CancellationTokenTrigger(langCts.Token));
                return "Language Pattern";
            });

            var link = new EntryLink();
            // Get all of the expiration triggers from the parent key
            var parentValue = cache.Get("membersite.language.", link);
            Assert.Equal("Language Pattern", parentValue);
            var result = cache.Set("membersite.language.id-1", context =>
            {
                // Copy the expiration triggers to this entry
                context.AddEntryLink(link);
                return "en-US";
            });

            var curCts = new CancellationTokenSource();
            cache.Set("membersite.currency.", ctx =>
            {
                ctx.AddExpirationTrigger(new CancellationTokenTrigger(curCts.Token));
                return "Currency Pattern";
            });
            link = new EntryLink();
            parentValue = cache.Get("membersite.currency.", link);
            Assert.Equal("Currency Pattern", parentValue);
            result = cache.Set("membersite.currency.id-1", context => {
                context.AddEntryLink(link);
                return "RMB";
            });

            var currency = cache.Get<string>("membersite.currency.id-1");
            Assert.Equal("RMB", currency);

            var language = cache.Get<string>("membersite.language.id-1");
            Assert.Equal("en-US", language);

            // Remove just the root key
            cache.Remove("membersite.language.");

            parentValue = cache.Get<string>("membersite.language.");
            Assert.Null(parentValue);

            language = cache.Get<string>("membersite.language.id-1");
            Assert.Equal("en-US", language);

            // Remove all the associated lang keys.
            langCts.Cancel();

            language = cache.Get<string>("membersite.language.id-1");
            Console.WriteLine("Language: " + language);
            Assert.Null(language);

            currency = cache.Get<string>("membersite.currency.id-1");
            Assert.Equal("RMB", currency);

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

No branches or pull requests

3 participants