Continuous Query
Note
This feature is only available in NCache Enterprise edition.
Distributed caching is the main need in this technological era where large scale multi-tier applications are built to cater millions of clients for high performance and scalability. But applications that require rapid changes in data demand synchronization of caches and client with the same pace. With synchronization of cache it is also essential that all clients are able to share information related to some specific data set whenever any change occurs in it.
Continuous Query is provided by NCache for runtime monitoring and tracking of data related to observable data set. For example, you have a web application regarding stock exchange where stock values will change very frequently for any company. Your client will be interested in the companies they have shares in. Here, we have criteria for clients having shares in some companies and the data related to only those companies should be updated on each client’s view. NCache allows you to specify any query criteria for indexed classes.
Changes in result set of a query can be triggered by:
Add: Adding an item in cache or updating any existing item can add the item in any query.
Update: Updating any existing cache item but it remains in query result set.
Remove: Removing item from cache or updating any existing cached item cause that item removal from query result set.
You can also specify filters for notifications that your cache client will receive. Filters are basically for the amount of modified cached item related data that you will receive in your query notifications.
NCache provides 3 types of filters mentioned below:
None
(minimum data that is only key)Metadata
(key with metadata related to cached item)Data with metadata
(key with complete cached and related data)
If any cached item related to the result set of any registered query is removed due to expiration, eviction or dependencies, then its notification will be sent to interested cache clients.
Important
GROUP BY
and Tags
are not supported in this feature.
You may have an application that has .NET and Java clients. By enabling the data sharing feature on your cluster cache, you can index the same objects for both clients even with the same query. Notifications will be sent to each client irrespective of Java or .NET for cached items added, updated or removed by both clients in any registered query result set.
For this feature, extra processing is included for monitoring and notifying clients which consume resources. So for efficiently using this feature you should take care of its usage too. If all your applications don't require tracking of any query result set, then you should not only unregister notifications but also unregister the query from your cache.
Using Continuous Query
Assuming that you have indexed the required searchable attributes, you are now required to implement continuous query in your application. Keeping in mind the purpose of continuous queries, the first thing you need to do is to define all the callbacks that need to be executed once the result set of your query is in any way changed. Then, we need to register the continuous query with the cache server.
Following are the main methods that are provided by NCache and are associated with the implementation of continuous queries.
To utilize the API, include the following namespace in your application:
Alachisoft.NCache.Web.Caching
Alachisoft.NCache.Runtime.Events
Methods | Description |
---|---|
registerCQ |
The main purpose of this method is to activate your continuous query with the cache server. You can use this method multiple times in your application depending on its need to receive the notifications for a change in the dataset of your query. This method takes as argument an object of ContinuousQuery which has the query and the callbacks registered to it. |
unregisterCQ |
unregisterCQ is used by your application after you have registered a continuous query to deactivate it on the cache server. Like RegisterCQ , it takes as argument an object of ContinuousQuery to unregister the callbacks which are no more fired after this call. This method is used when the user is no more interested in receiving notifications for changes in a query result set. |
ExecuteReaderCQ |
ExecuteReaderCQ() opens DataReader on server node(s), executes the query and returns the first chunk of data to the client. At the same time, it also registers the continuous query for call backs in case of changes in data fulfilling the query’s criteria. The result set generated is then read at client side, chunk by chunk, using Read() of ICacheReader . |
searchCQ |
[Obsolete] Only returns list of keys in result set which fulfill the query criteria. |
searchEntriesCQ |
[Obsolete] Returns list of key-value pairs in result set which fulfills the query criteria. |
public class CQ
{
static void Main(string[] args)
{
Cache cache = NCache.InitializeCache("mycache");
string queryString = "Select Product WHERE this.supplier=?";
Hashtable values = new Hashtable();
values.Add("supplier", "Carlos Diaz");
ContinuousQuery continuousQuery = new ContinuousQuery(queryString, values);
//register notification for add operation
continuousQuery.RegisterNotification(new QueryDataNotificationCallback(ItemAddedCallBack), EventType.ItemAdded, EventDataFilter.None);
//register notification for update and remove operation
continuousQuery.RegisterNotification(new QueryDataNotificationCallback(QueryItemCallBack), EventType.ItemUpdated | EventType.ItemRemoved, EventDataFilter.None);
//register cache clear notification
continuousQuery.RegisterClearNotification(new ContinuousQueryClearCallback(CacheClear));
cache.RegisterCQ(continuousQuery);
try
{
//SearchCQ to get keys from the result set
ICollection result = cache.SearchCQ(continuousQuery);
//SearchEntriesCQ to get keys from the result set
IDictionary res = cache.SearchEntriesCQ(continuousQuery);
//perform operations
}
catch (Exception ex)
{
// handle exception
}
Product product = new Product();
product.ProductName = " Chai";
product.Supplier = "Carlos Diaz";
product.Category = 4;
//trigger add notification.
cache.Add("key", new CacheItem(product));
product.Supplier = "Elio Rossi";
//trigger remove notification to remove key from
//the query result set by changing supplier name.
cache.Insert("key", new CacheItem(product));
//trigger cache clear notification
cache.Clear();
cache.Dispose();
}
// Create target methods
static void CacheClear()
{
Cache cache = null;
cache.Clear();
}
static void ItemAddedCallBack(string key, CQEventArg arg)
{
EventCacheItem item = arg.Item; //perform operations
}
static void QueryItemCallBack(string key, CQEventArg arg)
{
switch (arg.EventType)
{
case EventType.ItemRemoved:
//perform operations
break;
case EventType.ItemUpdated:
//perform operations
break;
}
}
}