AppFabric and CachingPolicy/ChangeMonitors - caching

We're investigating moving to a distributed cache using Windows AppFabric. Our ASP.NET 4.0 application currently has a cache implementation that uses MemoryCache.
One key feature is that when items are added to the cache, a CacheItemPolicy is included that contains a ChangeMonitor:
CacheItemPolicy policy = new CacheItemPolicy();
policy.Priority = CacheItemPriority.Default;
policy.ChangeMonitors.Add(new LastPublishDateChangeMonitor(key, item, GetLastPublishDateCallBack));
The change monitor internally uses a timer to periodically trigger the delegate passed into it - which is usually a method to get a value from a DB for comparison.
The policy and its change monitor are then included when an item is added to the cache:
Cache.Add(key, item, policy);
An early look at AppFabric's DataCache class seem to indicate whilst a Timespan can be included when adding items to cache, a CacheItemPolicy itself can't be.
Is there an another way to implement the same ChangeMonitor-type functionality in AppFabric. Notifications perhaps?
Cheers
Neil

There are only two hard problems in computer science: cache
invalidation, naming things and off-by-one errors.
Phil Karlton
Unfortunately AppFabric has no support for this sort of monitoring to invalidate a cached item, and similarly no support for things like SqlCacheDependency.
However, AppFabric 1.1 brought in support for read-through and write-behind. Write-behind means that your application updates the cached data first rather than the underlying database, so that the cache always holds the latest version (and therefore the underlying data doesn't need to be monitored); the cache then updates the underlying database asynchronously. To implement read-through/write-behind, you'll need to create an object that inherits from DataCacheStoreProvider (MSDN) and write Read, Write and Delete methods that understand the structure of your database and how to update it.

Related

In-memory cache in ASP.NET Core emptied immediately

I am trying to implement temporary ip blocking for my ASP.NET Core application and everything I have read on how to do this uses caching.
I have followed this article to learn about in-memory caching in asp.net core:
https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory
The code is running okay, but the cache is emptied immediately after an action is completed.
If a put a break-point on this line:
_cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
I can see that _cache indeed has the proper value. However, that value is gone the next time I reload the page. Regardless of how long I set the expiration time to or even if I set
CacheItemPriority.NeverRemove
in the cacheEntryOptions.
I have also tried registering a callback for the eviction of the item from the cache to see if it was being evicted immediately due to memory pressure. However, the callback is never called.
Is there some server options I need to enable to allow caching?
I met the similar issue today. And found that the cache only save the reference of the value. So if you save a List in to the cache and Clear the List later. The cached List will also be cleared, but key is still there.
Source code is here:https://source.dot.net/#Microsoft.Extensions.Caching.Abstractions/MemoryCacheExtensions.cs,bc5684b7eae179d4

Ehcache to refresh when an update take place in a database

I am new to Ehcache, My Rest API cache works
<cache name="com.a.b.c.model.Act"
maxElementsInMemory="10000" overflowToDisk="false" statistics="true" />
If I do any update in Database through query, the cache won't update those changes.
If I do update through REST API the cache will get refreshed.
What change I have to make if I have to get cache refresh when a change happens in Database
Is it good to go with timeToLiveSeconds or any other configurations can be done?
Updating the cache when the underlying system of record changes, and not through the service methods on which caching is performed, is the classical problem with caching.
Ehcache does not provide an out of the box solution there as it would mean supporting ALL the technologies that can act as a system of record. Not only databases but also web services and really anything a programmer can come up with.
However, if your application can live with having outdated data in cache for a small period of time, then expiry can be helpful. It effectively mark cache entries as valid for a period of time - time to live.
If your application cannot support stale data in cache, you will have to make sure the process to update the system of record takes care of invalidating the cache as well.
If the code that is upadating the database can access Ehcache manager (same VM or distributed persistence) the best solution is to break the cache
CacheManager.getInstance().getEhcache("mycache").remove(key);
and let the cache refresh autonomously.
If you already dispose of the updated object you could also skip one step with put
CacheManager.getInstance().getEhcache("mycache").put(key, updatedObject);
If your code has CacheEntryFactories I would let the factory do the business (entry creation is centralized, you can add more logic there)

Difference between in-memory-store and managed-store in mule cache

What are the main differences between in-memory-store and managed-store in mule cache scope and which gives a best performance.
What is the best way to configure caching in global scope?
We are currently using in-memory-store caching. We are always getting issues with memory outage as we are using a server with less HW configurations. We are using mule 3.7v.
Please provide your suggestions to configure cache in optimized way.
We are facing issue with cache expiration with in-memory-store. cache date is not being expunged after expiration time also. But when we use "managed-store" its working as expected.
Below is my configuration:
In-memory:
This store the data inside system memory. The data stored with In-memory is non-persistent which means in case of API restart or crash, the data been cached will be lost.
Managed-store:
This stores the data in a place defined by ListableObjectStore. The data stored with Managed-store is persistent which means in case of API restart or crash, the data been cached will no be lost.
Source (explained in detail with configuration difference):
http://www.tutorialsatoz.com/caching-in-mule-cache-scope/
One of my friend clearly explained me this difference as follows:
in-memory cache--> It is a temperoy memory storage area where it will store the data. for example: Consider using a VM component in Mule, the data will be stored in VM in the form of in-memory queue
in the case of Managed store--> we can store the data and use it in later stages. example: object store
mainly cache will store the frequently used data. It will reduce the db or http calls by saving the frequently used data or results in cache scope.
But both are for temporary storage only, means they are valid for that particular session alone.

SalesForce integration - notify external system on SF object definition change

We have a software that is integrated with SalesForce using SF SOAP API. As we are sending/receiving data to/from SF on user level, we must know which SF objects and object fields is user allowed to access (based on SF visibility rules). Therefore, we first invoke describeSObject(objName) and store it to our cache to speed up integration.
What happens is, when our clients change visibility rules or rename object fields on SF side, they must invalidate cache in our application. If they forget to do that (and they usually do), we are not aware that our cache is invalid.
Question: is there a way to invoke our web service from SF when visibility rules changes, or object field is added/deleted/renamed? If that is possible, as visibility rules in SF are quite complex, how can we differ which users are affected by change (so we do not invalidate cache for everyone)?
I suspect you can't currently.
As an alternative, catch the exceptions that occur due to the metadata mismatch and flush the local cache for that user. Then retry the original request with the updated metadata.

windows azure: shared cache - delete all?

I'm using Windows Azure Shared Caching. I encountered a few problems:
How to know what keys are present in the cache? Is there something like a GetAllKeys() method?
Is it possible to call clearAll()?
Why can't I use regions?
Thanks.
This section applies to Windows Azure Caching
Windows Azure provides two types of cache modes:
Dedicated Role caching - The role instances are used exclusively for
caching (there is no other code running in that instance).
Co-located Role caching - The cache shares the VM resources
(bandwidth, CPU, and memory) with the application.
How to know what is in the cache? Is there something like "GetAllKeys()" method?
Do you need that information for your application of more for reporting / auditing?
I think, Microsoft did not provide that method for one good reason: the information it returned could be obsolete shortly after. See, cache items may expire any time (depends on expiration time and time of adding item to cache) so information you would receive from GetAllKeys() method could be invalid seconds or even milliseconds later.
Cache usage standard pattern would be
Get item from cache by a key
If cache return Null then create that item and put / add into the cache
Perform operation on the item (either taken from cache or recreated)
Co-located Role caching
Is it possible to clearAll()?
I do not think you should worry about purging your cache. If you set the cache eviction policy to LRU (Last Recently Used) then the least recently used items are discarded first. So you will never get anything like "no space in cache".
Why can't I use regoins?
You can but only with cache locate on the same instance. Dedicated Role caching does not support it.
This section applies to Windows Azure Shared Caching
Windows Azure Shared Caching is very similar to Windows Azure Caching (described above) from client side point of view and all of the explanations applies to Shared Caching too.
There is a small change to items eviction:
In Shared Caching, items without a specific expiration time will expire after 48 hours. However, you can add items to the cache (via various overloads of the Add and Put methods) with an explicit expiration time, such as X minutes or Y days.
When you exceed the size of your cache (cache sizes you chose during creation), the caching service will start "evict items" in the cache until the memory issue is resolved (you have enough memory to add new cache items). During "eviction" LRU mechanism is used - the least recently used items in the cache are removed.
Get, check, and recreate approach (described above) of dealing with cache items will work for Shared Caching too.
I hope that will help you to better understand Azure Caching and Shared Caching.
Following method clears all the data in a cache.
public static void InvalidateCache(string cacheName)
{
DataCache desiredCache = new DataCache(cacheName);
foreach (string regionName in desiredCache.GetSystemRegions())
{
desiredCache.ClearRegion(regionName);
}
}

Resources