19 Using the Coherence .NET Client Library
doc
directory of the Coherence for .NET distribution.
This chapter includes the following sections:
- Setting Up the Coherence .NET Client Library
To use the Coherence for .NET library in your .NET applications, you must add a reference to theCoherence.dll
library in your project and create the necessary configuration files. - Using the Coherence .NET APIs
The Coherence .NET API includes many classes that are used to interact with Coherence caches within a .NET application. - Configuring .NET Clients Programmatically
Clients can load Coherence configuration files programmatically at runtime.
Parent topic: Creating .NET Extend Clients
Setting Up the Coherence .NET Client Library
Coherence.dll
library in your project and create the necessary configuration files.To create a reference to the Coherence.dll
:
-
In your project go to Project->Add Reference... or right click References in the Solution Explorer and choose Add Reference.... The Add Reference Window displays.
-
From the Add Reference window, choose the Browse tab and find the
Coherence.dll
library on your file system as shown in Figure 19-1. -
Click OK.
-
Create the necessary configuration files and specify their paths in the application configuration settings. This is done by adding an application configuration file to your project (if one does not exist) and adding a Coherence for .NET configuration section (that is,
<coherence/>
) to it.
Note:
If these configuration files are not specified in the app.config
/web.config
, Coherence looks for them in both the folder where the application is deployed or, for Web applications, in the root of the Web application. You can also specify the cache configuration file programmatically. See Configuring .NET Clients Programmatically.
<?xml version="1.0"?> <configuration> <configSections> <section name="coherence" type="Tangosol.Config.CoherenceConfigHandler, Coherence"/> </configSections> <coherence> <cache-factory-config>my-coherence.xml</cache-factory-config> <cache-config>my-cache-config.xml</cache-config> <pof-config>my-pof-config.xml</pof-config> </coherence> </configuration>
Elements within the Coherence for .NET configuration section are:
-
cache-factory-config
—contains the path to a operational configuration descriptor used by theCacheFactory
to configureIConfigurableCacheFactory
andLogger
. -
cache-config
—contains the path to a cache configuration file which contains the cache configuration. The cache configuration descriptor is used byDefaultConfigurableCacheFactory
. -
pof-config
—contains the path to the configuration descriptor used by theConfigurablePofContext
to register custom types used by the application. See Using the Coherence .NET Client Library.
Figure 19-2 illustrates what the solution should look like after adding the configuration files:
Figure 19-2 File System Displaying the Configuration Files
Description of "Figure 19-2 File System Displaying the Configuration Files"
Parent topic: Using the Coherence .NET Client Library
Using the Coherence .NET APIs
This section includes the following topics:
- CacheFactory
- IConfigurableCacheFactory
- DefaultConfigurableCacheFactory
- Logger
- Using the Common.Logging Library
- INamedCache
- IQueryCache
- QueryRecorder
- IObservableCache
- IInvocableCache
- Filters
- Value Extractors
- Entry Processors
- Entry Aggregators
Parent topic: Using the Coherence .NET Client Library
CacheFactory
The CacheFactory
is the entry point for Coherence for .NET client applications. The CacheFactory
is a factory for INamedCache
instances and provides various methods for logging. If not configured explicitly, it uses the default configuration file coherence.xml
which is an assembly embedded resource. It is possible to override the default configuration file by adding a cache-factory-config
element to the Coherence for .NET configuration section in the application configuration file and setting its value to the path of the desired configuration file. You can also specify the cache configuration file programmatically. See Configuring .NET Clients Programmatically.
<?xml version="1.0"?> <configuration> <configSections> <section name="coherence" type="Tangosol.Config.CoherenceConfigHandler, Coherence"/> </configSections> <coherence> <cache-factory-config>my-coherence.xml</cache-factory-config> ... </coherence> </configuration>
This file contains the configuration of two components exposed by the CacheFactory
by using static properties:
-
CacheFactory.ConfigurableCacheFactory
—theIConfigurableCacheFactory
implementation used by theCacheFactory
to retrieve, release, and destroyINamedCache
instances. -
CacheFactory.Logger
—theLogger
instance used to log messages and exceptions.
When you are finished using the CacheFactory
(for example, during application shutdown), the CacheFactory
should be shutdown by using the Shutdown()
method. This method terminates all services and the Logger
instance.
Parent topic: Using the Coherence .NET APIs
IConfigurableCacheFactory
The IConfigurableCacheFactory
implementation is specified by the contents of the <configurable-cache-factory-config>
element:
-
class-name
—specifies the implementation type by it's assembly qualified name. -
init-params
—defines parameters used to instantiate theIConfigurableCacheFactory
. Each parameter is specified by using a correspondingparam-type
andparam-value
child element.
<coherence> <configurable-cache-factory-config> <class-name>Tangosol.Net.DefaultConfigurableCacheFactory, Coherence</class-name> <init-params> <init-param> <param-type>string</param-type> <param-value>simple-cache-config.xml</param-value> </init-param> </init-params> </configurable-cache-factory-config> </coherence>
If an IConfigurableCacheFactory
implementation is not defined in the configuration, the default implementation is used (DefaultConfigurableCacheFactory
).
Parent topic: Using the Coherence .NET APIs
DefaultConfigurableCacheFactory
The DefaultConfigurableCacheFactory
provides a facility to access caches declared in the cache configuration descriptor. The default configuration file used by the DefaultConfigurableCacheFactory
is $AppRoot/coherence-cache-config.xml
, where $AppRoot
is the working directory (for a Windows Forms application) or the root of the application (for a Web application).
If you want to specify another cache configuration descriptor file, you can do so by adding a cache-config
element to the Coherence for .NET configuration section in the application configuration file with its value set to the path of the configuration file. You can also specify the cache configuration file programmatically. See Configuring .NET Clients Programmatically.
<?xml version="1.0"?> <configuration> <configSections> <section name="coherence" type="Tangosol.Config.CoherenceConfigHandler, Coherence"/> </configSections> <coherence> <cache-config>my-cache-config.xml</cache-config> ... </coherence> </configuration>
Parent topic: Using the Coherence .NET APIs
Logger
The Logger
is configured using the logging-config
element:
-
destination
—determines the type ofLogOutput
used by the Logger. Valid values are:-
common-logger
forCommon.Logging
-
stderr
forConsole.Error
-
stdout
forConsole.Out
-
file path if messages should be directed to a file
-
-
severity-level
—specifies the log level that a message must meet or exceed to be logged. -
logger-name
—specifies the name of the logger. The default value isCoherence
. -
message-format
—determines the log message format. -
character-limit
—determines the maximum number of characters that the logger daemon processes from the message queue before discarding all remaining messages in the queue.
... <logging-config> <destination>common-logger</destination> <logger-name>Coherence</logger-name> <severity-level>5</severity-level> <message-format>(thread={thread}): {text}</message-format> <character-limit>8192</character-limit> </logging-config> ...
The CacheFactory
provides several static methods for retrieving and releasing INamedCache
instances:
-
GetCache(String cacheName)
—retrieves anINamedCache
implementation that corresponds to theNamedCache
with the specifiedcacheName
running within the remote Coherence cluster. -
ReleaseCache(INamedCache cache)
—releases all local resources associated with the specified instance of the cache. After a cache is release, it can no longer be used. -
DestroyCache(INamedCache cache)
—destroys the specified cache across the Coherence cluster.
Methods used to log messages and exceptions are:
-
IsLogEnabled(int level)
—determines if the Logger would log a message with the given severity level. -
Log(Exception e, int severity)
—logs an exception with the specified severity level. -
Log(String message, int severity)
—logs a text message with the specified severity level. -
Log(String message, Exception e, int severity)
—logs a text message and an exception with the specified severity level.
Logging levels are defined by the values of the CacheFactory.LogLevel
enum
values (in ascending order):
-
Always
-
Error
-
Warn
-
Info
-
Debug
—(default log level) -
Quiet
-
Max
Parent topic: Using the Coherence .NET APIs
Using the Common.Logging Library
Common.Logging
is an open source library that enables you to plug in various popular open source logging libraries behind a well-defined set of interfaces. The libraries currently supported are Log4Net (versions 1.2.9 and 1.2.10) and NLog.
Common.Logging
is currently used by the Spring.NET framework and are likely to be used in the future releases of IBatis.NET and NHibernate, so you might want to consider it if you are using one or more of these frameworks in combination with Coherence for .NET, as it allows logging to be consistently configured throughout the application layers.
Coherence for .NET does not include the Common.Logging
library. To use the common-logger
Logger configuration, download the Common.Logging
assembly and include a reference to it in your project. You can download the Common.Logging
assembly for .NET from the following location:
http://netcommon.sourceforge.net/
The Coherence for .NET Common.Logging Logger implementation was compiled against the signed release version of these assemblies.
Parent topic: Using the Coherence .NET APIs
INamedCache
The INamedCache
interface extends IDictionary
, so it can be manipulated in ways similar to a dictionary. When obtained, INamedCache
instances expose several properties:
-
CacheName
—the cache name. -
Count
—the cache size. -
IsActive
—determines if the cache is active (that is, it has not been released or destroyed). -
Keys
—collection of all keys in the cache mappings. -
Values
—collection of all values in the cache mappings.
The value for the specified key can be retrieved by using cache[key]
. Similarly, a new value can be added, or an old value can be modified by setting this property to the new value: cache[key]
=
value
.
The collection of cache entries can be accessed by using GetEnumerator()
which iterates over the mappings in the cache.
The INamedCache
interface provides several methods used to manipulate the contents of the cache:
-
Clear()
—removes all the mappings from the cache. -
Contains(Object key)
—determines if the cache has a mapping for the specified key. -
GetAll(ICollection keys)
—returns all values mapped to the specified keys collection. -
Insert(Object key, Object value)
—places a new mapping into the cache. If a mapping for the specified key exists, its value is overwritten by the specified value and the old value is returned. -
Insert(Object key, Object value, long millis)
—places a new mapping into the cache, but with an expiry period specified by several milliseconds. -
InsertAll(IDictionary dictionary)
—copies all the mappings from the specified dictionary to the cache. -
Remove(Object key)
—Removes the mapping for the specified key if it is present and returns the value it was mapped to.
INamedCache
interface also extends the following three interfaces: IQueryCache, IObservableCache, and IInvocableCache.
Parent topic: Using the Coherence .NET APIs
IQueryCache
The IQueryCache
interface exposes the ability to query a cache using various filters.
-
GetKeys(IFilter filter)
—returns a collection of the keys contained in this cache for entries that satisfy the criteria expressed by the filter. -
GetEntries(IFilter filter)
—returns a collection of the entries contained in this cache that satisfy the criteria expressed by the filter. -
GetEntries(IFilter filter, IComparer comparer)
—returns a collection of the entries contained in this cache that satisfy the criteria expressed by the filter. It is guaranteed that the enumerator traverses the collection in the order of ascending entry values, sorted by the specified comparer or according to the natural ordering if the "comparer" is null.
Additionally, the IQueryCache
interface includes the ability to add and remove indexes. Indexes are used to correlate values stored in the cache to their corresponding keys and can dramatically increase the performance of the GetKeys
and GetEntries
methods.
-
AddIndex(IValueExtractor extractor, bool isOrdered, IComparer comparator)
—adds an index to this cache that correlates the values extracted by the givenIValueExtractor
to the keys to the corresponding entries. Additionally, the index information can be optionally ordered. -
RemoveIndex(IValueExtractor extractor)
—removes an index from this cache.
The following example performs an efficient query of the keys of all entries that have an age property value greater or equal to 55.
IValueExtractor extractor = new ReflectionExtractor("getAge"); cache.AddIndex(extractor, true, null); ICollection keys = cache.GetKeys(new GreaterEqualsFilter(extractor, 55));
Parent topic: Using the Coherence .NET APIs
QueryRecorder
The QueryRecorder
class produces an explain or trace record for a given filter. The class is an implementation of a parallel aggregator that is capable querying all nodes in a cluster and aggregating the results. The class supports two record types: an Explain
record that provides the estimated cost of evaluating a filter as part of a query operation and a Trace
record that provides the actual cost of evaluating a filter as part of a query operation. Both query records take into account whether or not an index can be used by a filter. See Interpreting Query Records in Developing Applications with Oracle Coherence.
To create a query record, create a new QueryRecorder
instance that specifies a RecordType
parameter. Include the instance and the filter to be tested as parameters of the Aggregate
method. The following example creates an explain record:
INamedCache cache = CacheFactory.GetCache(MyCache); IFilter filter = new OrFilter( new GreaterFilter(IdentityExtractor.Instance, 100), new LessFilter(IdentityExtractor.Instance, 30)); QueryRecorder aggregator = new QueryRecorder(QueryRecorder.RecordType.Explain); IQueryRecord record = (IQueryRecord) cache.Aggregate(filter, aggregator); Console.WriteLine(record.ToString());
To create a trace record, change the RecordType
parameter to Trace
:
QueryRecorder aggregator = new QueryRecorder(QueryRecorder.RecordType.Trace);
Parent topic: Using the Coherence .NET APIs
IObservableCache
IObservableCache
interface enables an application to receive events when the contents of a cache changes. To register interest in change events, an application adds a Listener
implementation to the cache that receives events that include information about the event type (inserted, updated, deleted), the key of the modified entry, and the old and new values of the entry.
-
AddCacheListener(ICacheListener listener)
—adds a standard cache listener that receives all events (inserts, updates, deletes) emitted from the cache, including their keys, old, and new values. -
RemoveCacheListener(ICacheListener listener)
—removes a standard cache listener that was previously registered. -
AddCacheListener(ICacheListener listener, object key, bool isLite)
—adds a cache listener for a specific key. IfisLite
istrue
, the events may not contain the old and new values. -
RemoveCacheListener(ICacheListener listener, object key)
—removes a cache listener that was previously registered using the specified key. -
AddCacheListener(ICacheListener listener, IFilter filter, bool isLite)
—adds a cache listener that receive events based on a filter evaluation. If isLite is true, the events may not contain the old and new values. -
RemoveCacheListener(ICacheListener listener, IFilter filter)
—removes a cache listener that previously registered using the specified filter.
Listeners that are registered using the filter-based method receives all event types (inserted, updated, and deleted). To further filter the events, wrap the filter in a CacheEventFilter
using a CacheEventMask
enumeration value to specify which type of events should be monitored.
The following example filter evaluates to true
if an Employee
object is inserted into a cache with an IsMarried
property value set to true
.
new CacheEventFilter(CacheEventMask.Inserted, new EqualsFilter("IsMarried", true));
The following example filter evaluates to true
if any object is removed from a cache.
new CacheEventFilter(CacheEventMask.Deleted);
The following example filter evaluates to true
when an Employee
object LastName
property is changed from Smith
.
new CacheEventFilter(CacheEventMask.UpdatedLeft, new EqualsFilter("LastName", "Smith"));
This section includes the following topic:
Parent topic: Using the Coherence .NET APIs
Responding to Cache Events
A feature of the INamedCache
interface is the ability to add cache listeners that receive events emitted by a cache as its contents change. These events are sent from the server and dispatched to registered listeners by a background thread.
The .NET Single-Threaded Apartment model prohibits windows form controls created by one thread from being updated by another thread. If one or more controls should be updated because of an event notification, you must ensure that any event handling code that must run as a response to a cache event is executed on the UI thread. The WindowsFormsCacheListener
helper class allows end users to ignore this fact and to handle Coherence cache events (which are always raised by a background thread) as if they were raised by the UI thread. This class ensures that the call is properly marshalled and executed on the UI thread.
Here is the sample of using this class:
public partial class ContactInfoForm : Form { ... listener = new WindowsFormsCacheListener(this); listener.EntryInserted += new CacheEventHandler(AddRow); listener.EntryUpdated += new CacheEventHandler(UpdateRow); listener.EntryDeleted += new CacheEventHandler(DeleteRow); ... cache.AddCacheListener(listener); ... }
The AddRow
, UpdateRow
and DeleteRow
methods are called in response to a cache event:
private void AddRow(object sender, CacheEventArgs args) { ... } private void UpdateRow(object sender, CacheEventArgs args) { ... } private void DeleteRow(object sender, CacheEventArgs args) { ... }
The CacheEventArgs
parameter encapsulates the IObservableCache
instance that raised the cache event; the CacheEventType
that occurred; and the Key
, NewValue
and OldValue
of the cached entry.
Parent topic: IObservableCache
IInvocableCache
An IInvocableCache
is a cache against which both entry-targeted processing and aggregating operations can be invoked. The operations against the cache contents are executed by (and thus within the localized context of) a cache. This is particularly useful in a distributed environment, because it enables the processing to be moved to the location at which the entries-to-be-processed are being managed, thus providing efficiency by localization of processing.
-
Invoke(object key, IEntryProcessor agent)
—invokes the passed processor against the entry specified by the passed key, returning the result of the invocation. -
InvokeAll(ICollection keys, IEntryProcessor agent)
—invokes the passed processor against the entries specified by the passed keys, returning the result of the invocation for each. -
InvokeAll(IFilter filter, IEntryProcessor agent)
—invokes the passed processor against the entries that are selected by the given filter, returning the result of the invocation for each. -
Aggregate(ICollection keys, IEntryAggregator agent)
—performs an aggregating operation against the entries specified by the passed keys. -
Aggregate(IFilter filter, IEntryAggregator agent)
—performs an aggregating operation against the entries that are selected by the given filter.
Parent topic: Using the Coherence .NET APIs
Filters
The IQueryCache
interface provides the ability to search for cache entries that meet a given set of criteria, expressed using a IFilter
implementation.
All filters must implement the IFilter interface:
-
Evaluate(object o)
—apply a test to the specified object and returntrue
if the test passes,false
otherwise.
Coherence for .NET includes several IFilter
implementations in the Tangosol.Util.Filter
namespace.
The following example retrieves the keys of all entries that have a value equal to 5.
EqualsFilter equalsFilter = new EqualsFilter(IdentityExtractor.Instance, 5); ICollection keys = cache.GetKeys(equalsFilter);
The following example retrieves all keys that have a value greater or equal to 55.
GreaterEqualsFilter greaterEquals = new GreaterEqualsFilter(IdentityExtractor.Instance, 55); ICollection keys = cache.GetKeys(greaterEquals);
The following example retrieves all cache entries that have a value that begins with Belg
.
LikeFilter likeFilter = new LikeFilter(IdentityExtractor.Instance, "Belg%", '\\', true); ICollection entries = cache.GetEntries(likeFilter);
The following example retrieves all cache entries that have a value that ends with an
(case sensitive) or begins with An
(case insensitive).
OrFilter orFilter = new OrFilter(new LikeFilter(IdentityExtractor.Instance, "%an", '\\', false), new LikeFilter(IdentityExtractor.Instance, "An%", '\\', true)); ICollection entries = cache.GetEntries(orFilter);
Parent topic: Using the Coherence .NET APIs
Value Extractors
Extractors are used to extract values from an object. All extractors must implement the IValueExtractor
interface:
-
Extract(object target)
—extract the value from the passed object.
Coherence for .NET includes the following extractors:
-
IdentityExtractor
is a trivial implementation that does not actually extract anything from the passed value, but returns the value itself. -
KeyExtractor
is a special purpose implementation that serves as an indicator that a query should be run against the key objects rather than the values. -
ReflectionExtractor
extracts a value from a specified object property. -
MultiExtractor
is compositeIValueExtractor
implementation based on an array of extractors. All extractors in the array are applied to the same target object and the result of the extraction is aIList
of extracted values. -
ChainedExtractor
is compositeIValueExtractor
implementation based on an array of extractors. The extractors in the array are applied sequentially left-to-right, so a result of a previous extractor serves as a target object for a next one.POF extractors and POF updaters offer the same functionality as
ChainedExtractors
through the use of theSimplePofPath
class. See Using POF Extractors and POF Updaters in Developing Applications with Oracle Coherence.
The following example retrieves all cache entries with keys greater than 5:
IValueExtractor extractor = new KeyExtractor(IdentityExtractor.Instance); IFilter filter = new GreaterFilter(extractor, 5); ICollection entries = cache.GetEntries(filter);
The following example retrieves all cache entries with values containing a City
property equal to city1
:
IValueExtractor extractor = new ReflectionExtractor("City"); IFilter filter = new EqualsFilter(extractor, "city1"); ICollection entries = cache.GetEntries(filter);
Parent topic: Using the Coherence .NET APIs
Entry Processors
An entry processor is an agent that operates against the entry objects within a cache. All entry processors must implement the IEntryProcessor
interface:
-
Process(IInvocableCacheEntry entry)
—process the specified entry. -
ProcessAll(ICollection entries)
—process a collection of entries.
Coherence for .NET includes several IEntryProcessor
implementations in the Tangosol.Util.Processor
namespace.
The following example demonstrates a conditional put. The value mapped to key1
is set to 680
only if the current mapped value is greater than 600
.
IFilter greaterThen600 = new GreaterFilter(IdentityExtractor.Instance, 600); IEntryProcessor processor = new ConditionalPut(greaterThen600, 680); cache.Invoke("key1", processor);
The following example uses the UpdaterProcessor
to update the value of the Degree
property on a Temperature
object with key BGD
to the new value 26
.
cache.Insert("BGD", new Temperature(25, 'c', 12)); IValueUpdater updater = new ReflectionUpdater("setDegree"); IEntryProcessor processor = new UpdaterProcessor(updater, 26); object result = cache.Invoke("BGD", processor);
Parent topic: Using the Coherence .NET APIs
Entry Aggregators
An entry aggregator represents processing that can be directed to occur against some subset of the entries in an IInvocableCache
, resulting in an aggregated result. Common examples of aggregation include functions such as minimum, maximum, sum and average. However, the concept of aggregation applies to any process that must evaluate a group of entries to come up with a single answer. Aggregation is explicitly capable of being run in parallel, for example in a distributed environment.
All aggregators must implement the IEntryAggregator
interface:
-
Aggregate(ICollection entries)
—process a collection of entries to produce an aggregate result.
Coherence for .NET includes several IEntryAggregator
implementations in the Tangosol.Util.Aggregator
namespace.
The following example returns the size of the cache:
IEntryAggregator aggregator = new Count(); object result = cache.Aggregate(cache.Keys, aggregator);
The following example returns an IDictionary
with keys equal to the unique values in the cache and values equal to the number of instances of the corresponding value in the cache:
IEntryAggregator aggregator = GroupAggregator.CreateInstance(IdentityExtractor.Instance, new Count()); object result = cache.Aggregate(cache.Keys, aggregator);
Note:
The above examples are simple examples and not practical for passing a large amount of keys or keys that are themselves very large. In such scenarios, use the GroupAggregator.CreateInstance(String, IEntryAggregator, IFilter)
method and pass an AlwaysFilter
object.
Like cached value objects, all custom IFilter
, IExtractor
, IProcessor
and IAggregator
implementation classes must be correctly registered in the POF context of the .NET application and cluster-side node to which the client is connected. As such, corresponding Java implementations of the custom .NET types must be created, compiled, and deployed on the cluster-side node. Note that the actual execution of these custom types is performed by the Java implementation and not the .NET implementation. See Building Integration Objects (.NET).
Parent topic: Using the Coherence .NET APIs
Configuring .NET Clients Programmatically
The following example loads the pofConfig.xml
, cacheConfig.xml
, and coherenceConfig.xml
files.
using System; using System.IO; using Tangosol.IO.Pof; using Tangosol.Net; using Tangosol.Run.Xml; namespace configExample { internal class TestPofContext : ConfigurablePofContext { public TestPofContext() : base("config/pofConfig.xml") { } } internal class TestClient { private static void Main(string[] args) { try { CacheFactory.Configure("config/cacheConfig.xml", "config/coherenceConfig.xml"); var cache = CacheFactory.GetCache("dist-test"); cache["key"] = new TestValue(1, "Test"); Console.Out.WriteLine("key=" + cache["key"]); } catch (Exception e) { Console.WriteLine(e); } Console.ReadLine(); } } }
Parent topic: Using the Coherence .NET Client Library