16 Configuration and Usage for .NET Clients

This chapter provides instructions for setting up Coherence for .NET clients.

This chapter includes the following sections:

16.1 General Instructions

Configuring and using Coherence for .NET requires five basic steps:

  1. Configure Coherence*Extend on both the client and on one or more JVMs within the cluster. See "Configuring Coherence*Extend" below.

  2. Configure a POF context on the client and on all of the JVMs within the cluster that run the Coherence*Extend clustered service. See "Overview of Building Integration Objects (.NET)".

  3. Implement the .NET client application using the Coherence for .NET API. See "Using the Coherence .NET APIs".

  4. Make sure the Coherence cluster is up and running. See "Starting a Coherence DefaultCacheServer Process".

  5. Launch the .NET client application.

16.2 Configuring Coherence*Extend

To configure Coherence*Extend, you must add the appropriate configuration elements to both the cluster and client-side cache configuration descriptors. The cluster-side cache configuration elements instruct a Coherence DefaultCacheServer to start a Coherence*Extend clustered service that listens for incoming TCP/IP requests from Coherence*Extend clients. The client-side cache configuration elements are used by the client library to determine the IP address and port of one or more servers in the cluster that run the Coherence*Extend clustered service so that it can connect to the cluster. It also contains various connection-related parameters, such as connection and request timeouts.

16.2.1 Configuring Coherence*Extend in the Cluster

In order for a Coherence*Extend client to connect to a Coherence cluster, one or more DefaultCacheServer JVMs within the cluster must run a TCP/IP Coherence*Extend clustered service. To configure a DefaultCacheServer to run this service, a proxy-scheme element with a child tcp-acceptor element must be added to the cache configuration descriptor used by the DefaultCacheServer. this is illustrated in Example 16-1.

Example 16-1 Configuration of a Default Cache Server for Coherence*Extend

<?xml version="1.0"?>

<cache-config xmlns="http://schemas.tangosol.com/cache"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://schemas.tangosol.com/cache
  assembly://Coherence/Tangosol.Config/cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>dist-*</cache-name>
      <scheme-name>dist-default</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <distributed-scheme>
      <scheme-name>dist-default</scheme-name>
      <lease-granularity>member</lease-granularity>
      <backing-map-scheme>
        <local-scheme/>
      </backing-map-scheme>
      <autostart>true</autostart>
    </distributed-scheme>

    <proxy-scheme>
      <service-name>ExtendTcpProxyService</service-name>
      <acceptor-config>
        <tcp-acceptor>
          <local-address>
            <address>localhost</address>
            <port>9099</port>
          </local-address>
        </tcp-acceptor>
      </acceptor-config>
      <autostart>true</autostart>
    </proxy-scheme>
  </caching-schemes>
</cache-config>

This cache configuration descriptor defines two clustered services, one that allows remote Coherence*Extend clients to connect to the Coherence cluster over TCP/IP and a standard Partitioned cache service. Since this descriptor is used by a DefaultCacheServer, it is important that the autostart configuration element for each service is set to true so that clustered services are automatically restarted upon termination. The proxy-scheme element has a tcp-acceptor child element which includes all TCP/IP-specific information needed to accept client connection requests over TCP/IP.

The Coherence*Extend clustered service configured above listens for incoming requests on the localhost address and port 9099. When, for example, a client attempts to connect to a Coherence cache called dist-extend, the Coherence*Extend clustered service proxies subsequent requests to the NamedCache with the same name which, in this example, is a Partitioned cache.

16.2.2 Configuring Coherence*Extend on the Client

A Coherence*Extend client uses the information within an initiator-config cache configuration descriptor element to connect to and communicate with a Coherence*Extend clustered service running within a Coherence cluster. This is illustrated in Example 16-2.

Example 16-2 Configuration to Connect to a Remote Coherence Cluster

<?xml version='1.0'?>

<cache-config xmlns="http://schemas.tangosol.com/cache"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://schemas.tangosol.com/cache
  assembly://Coherence/Tangosol.Config/cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>dist-extend</cache-name>
      <scheme-name>extend-dist</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <remote-cache-scheme>
      <scheme-name>extend-dist</scheme-name>
      <service-name>ExtendTcpCacheService</service-name>
      <initiator-config>
        <tcp-initiator>
          <remote-addresses>
            <socket-address>
              <address>localhost</address>
              <port>9099</port>
            </socket-address>
          </remote-addresses>
        </tcp-initiator>
        <outgoing-message-handler>
          <request-timeout>5s</request-timeout>
        </outgoing-message-handler>
      </initiator-config>
    </remote-cache-scheme>
  </caching-schemes>
</cache-config>

This cache configuration descriptor defines a caching scheme that connects to a remote Coherence cluster. The remote-cache-scheme element has a tcp-initiator child element which includes all TCP/IP-specific information needed to connect the client with the Coherence*Extend clustered service running within the remote Coherence cluster.

When the client application retrieves a named cache with CacheFactory using, for example, the name dist-extend, the Coherence*Extend client connects to the Coherence cluster by using TCP/IP (using the address localhost and port 9099) and return a INamedCache implementation that routes requests to the NamedCache with the same name running within the remote cluster. Note that the remote-addresses configuration element can contain multiple socket-address child elements. The Coherence*Extend client attempts to connect to the addresses in a random order, until either the list is exhausted or a TCP/IP connection is established.

16.2.2.1 Defining a Local Cache for .NET Clients

A Local Cache is just that: A cache that is local to (completely contained within) a particular .NET application. There are several attributes of the Local Cache that are particularly interesting:

  • The Local Cache implements the same standard cache interfaces that a remote cache implements (ICache, IObservableCache, IConcurrentCache, IQueryCache, and IInvocableCache), meaning that there is no programming difference between using a local and a remote cache.

  • The Local Cache can be size-limited. Size-limited means that the Local Cache can restrict the number of entries that it caches, and automatically evict entries when the cache becomes full. Furthermore, both the sizing of entries and the eviction policies are customizable, for example allowing the cache to be size-limited based on the memory used by the cached entries. The default eviction policy uses a combination of Most Frequently Used (MFU) and Most Recently Used (MRU) information, scaled on a logarithmic curve, to determine what cache items to evict. This algorithm is the best general-purpose eviction algorithm because it works well for short duration and long duration caches, and it balances frequency versus recentness to avoid cache thrashing. The pure LRU and pure LFU algorithms are also supported, and the ability to plug in custom eviction policies.

  • The Local Cache supports automatic expiration of cached entries, meaning that each cache entry can be assigned a time-to-live value in the cache. Furthermore, the entire cache can be configured to flush itself on a periodic basis or at a preset time.

  • The Local Cache is thread safe and highly concurrent.

  • The Local Cache provides cache "get" statistics. It maintains hit and miss statistics. These run-time statistics accurately project the effectiveness of the cache and are used to adjust its size-limiting and auto-expiring settings accordingly while the cache is running.

The Coherence for .NET Local Cache functionality is implemented by the Tangosol.Net.Cache.LocalCache class. As such, it can be programmatically instantiated and configured; however, it is recommended that a LocalCache be configured by using a cache configuration descriptor, just like any other Coherence for .NET cache.

The key element for configuring the Local Cache is <local-scheme>. Local caches are generally nested within other cache schemes, for instance as the front-tier of a near-scheme. Thus, this element can appear as a subelement of any of these elements in the coherence-cache-config file: <caching-schemes>, <distributed-scheme>, <replicated-scheme>, <optimistic-scheme>, <near-scheme>, <overflow-scheme>, and <read-write-backing-map>.

The <local-scheme> provides several optional subelements that let you define the characteristics of the cache. For example, the <low-units> and <high-units> subelements allow you to limit the cache in terms of size. When the cache reaches its maximum allowable size, it prunes itself back to a specified smaller size, choosing which entries to evict according to a specified eviction-policy (<eviction-policy>). The entries and size limitations are measured in terms of units as calculated by the scheme's unit-calculator (<unit-calculator>). A custom class can be defined using the <class-scheme> subelement for both the <eviction-policy> and <unit-calculator> element to specify custom behavior as required.

You can also limit the cache in terms of time. The <expiry-delay> subelement specifies the amount of time from last update that entries are kept by the cache before being marked as expired. Any attempt to read an expired entry results in a reloading of the entry from the configured cache store (<cachestore-scheme>). Expired values are periodically discarded from the cache based on the flush-delay.

If a <cachestore-scheme> is not specified, then the cached data only resides in memory, and only reflects operations performed on the cache itself. See <local-scheme> for a complete description of all of the available subelements.

Example 16-3 demonstrates a near cache configuration.

Example 16-3 Configuring a Local Cache

<?xml version='1.0'?>

<cache-config xmlns="http://schemas.tangosol.com/cache"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://schemas.tangosol.com/cache
  assembly://Coherence/Tangosol.Config/cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>example-local-cache</cache-name>
      <scheme-name>example-local</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <local-scheme>
      <scheme-name>example-local</scheme-name>
      <eviction-policy>LRU</eviction-policy>
      <high-units>32000</high-units>
      <low-units>10</low-units>
      <unit-calculator>FIXED</unit-calculator>
      <expiry-delay>10ms</expiry-delay>
      <cachestore-scheme>
        <class-scheme>
          <class-name>ExampleCacheStore</class-name>
        </class-scheme>
      </cachestore-scheme>
      <pre-load>true</pre-load>
    </local-scheme>
  </caching-schemes>
</cache-config>

16.2.2.2 Defining a Near Cache for .NET Clients

This section describes the Near Cache as it pertains to Coherence for .NET clients. See Developing Applications with Oracle Coherence for a complete discussion of the concepts behind a Near Cache, its configuration, and ways to keep it synchronized with the back tier.

In Coherence for .NET, the Near Cache is an INamedCache implementation that wraps the front cache and the back cache using a read-through/write-through approach. If the back cache implements the IObservableCache interface, then the Near Cache can use either the Listen None, Listen Present, Listen All, or Listen Auto strategy to invalidate any front cache entries that might have been changed in the back cache

The Tangosol.Net.Cache.NearCache class enables you to programmatically instantiate and configure .NET Near Cache functionality. However, it is recommended that you use a cache configuration descriptor to configure the NearCache.

A typical Near Cache is configured to use a local cache (thread safe, highly concurrent, size-limited and possibly auto-expiring) as the front cache and a remote cache as a back cache. A Near Cache is configured by using the near-scheme element which has two child elements: front-scheme for configuring a local (front) cache and back-scheme for defining a remote (back) cache.

A Near Cache is configured by using the <near-scheme> element in the coherence-cache-config file. This element has two required subelements: front-scheme for configuring a local (front-tier) cache and a back-scheme for defining a remote (back-tier) cache. While a local cache (<local-scheme>) is a typical choice for the front-tier, you can also use non-JVM heap based caches, (<external-scheme> or <paged-external-scheme>) or schemes based on Java objects (<class-scheme>).

The remote or back-tier cache is described by the <back-scheme> element. A back-tier cache can be either a distributed cache (<distributed-scheme>) or a remote cache (<remote-cache-scheme>). The <remote-cache-scheme> element enables you to use a clustered cache from outside the current cluster.

Optional subelements of <near-scheme> include <invalidation-strategy> for specifying how the front-tier and back-tier objects are kept synchronized and <listener> for specifying a listener which are notified of events occurring on the cache.

Example 16-4 demonstrates a near cache configuration.

Example 16-4 Near Cache Configuration

<?xml version="1.0"?>

<cache-config xmlns="http://schemas.tangosol.com/cache"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://schemas.tangosol.com/cache
  assembly://Coherence/Tangosol.Config/cache-config.xsd">
   <caching-scheme-mapping>
      <cache-mapping>
         <cache-name>dist-extend-near</cache-name>
         <scheme-name>extend-near</scheme-name>
      </cache-mapping>
   </caching-scheme-mapping>

   <caching-schemes>
      <near-scheme>
         <scheme-name>extend-near</scheme-name>
         <front-scheme>
            <local-scheme>
               <high-units>1000</high-units>
            </local-scheme>
         </front-scheme>
         <back-scheme>
            <remote-cache-scheme>
               <scheme-ref>extend-dist</scheme-ref>
            </remote-cache-scheme>
         </back-scheme>
         <invalidation-strategy>all</invalidation-strategy>
      </near-scheme>

      <remote-cache-scheme>
         <scheme-name>extend-dist</scheme-name>
         <service-name>ExtendTcpCacheService</service-name>
         <initiator-config>
            <tcp-initiator>
               <remote-addresses>
                  <socket-address>
                     <address>localhost</address>
                     <port>9099</port>
                  </socket-address>
               </remote-addresses>
               <connect-timeout>10s</connect-timeout>
            </tcp-initiator>
            <outgoing-message-handler>
               <request-timeout>5s</request-timeout>
            </outgoing-message-handler>
         </initiator-config>
      </remote-cache-scheme>
   </caching-schemes>
</cache-config>

16.2.3 Connection Error Detection and Failover

When a Coherence*Extend client service detects that the connection between the client and cluster has been severed (for example, due to a network, software, or hardware failure), the Coherence*Extend client service implementation (that is, ICacheService or IInvocationService) raises a MemberEventType.Left event (by using the MemberEventHandler delegate) and the service is stopped. If the client application attempts to subsequently use the service, the service automatically restarts itself and attempts to reconnect to the cluster. If the connection is successful, the service raises a MemberEventType.Joined event; otherwise, a irrecoverable error exception is thrown to the client application.

A Coherence*Extend service has several mechanisms for detecting dropped connections. Some mechanisms are inherit to the underlying protocol (such as TCP/IP in Extend-TCP), whereas others are implemented by the service itself. The latter mechanisms are configured by using the <outgoing-message-handler> element. For details on this element, see Developing Applications with Oracle Coherence. In particular, the <request-timeout> value controls the amount of time to wait for a response before abandoning the request. The <heartbeat-interval> and <heartbeat-timeout> values control the amount of time to wait for a response to a ping request before the connection is closed.

16.3 Starting a Coherence DefaultCacheServer Process

To start a DefaultCacheServer that uses the cluster-side Coherence cache configuration described earlier to allow Coherence for .NET clients to connect to the Coherence cluster by using TCP/IP, you must do the following:

  1. Change the current directory to the Oracle Coherence library directory (%COHERENCE_HOME%\lib on Windows and $COHERENCE_HOME/lib on UNIX).

  2. Make sure that the paths are configured so that the Java command runs.

  3. Start the DefaultCacheServer command line application with the -Dtangosol.coherence.cacheconfig system property set to the location of the cluster-side Coherence cache configuration descriptor described earlier.

Example 16-5 illustrates a sample command line.

Example 16-5 Command to Start a Coherence Default Cache Server

java -cp coherence.jar -Dtangosol.coherence.cacheconfig=file://<path to the server-side cache configuration descriptor> com.tangosol.net.DefaultCacheServer

16.4 Obtaining a Cache Reference with .NET

A reference to a configured cache can be obtained by name by using the CacheFactory class:

Example 16-6 Obtaining a Reference to a Cache

INamedCache cache = CacheFactory.GetCache("example-local-cache");

16.5 Cleaning Up Resources Associated with a Cache

Instances of all INamedCache implementations, including LocalCache, should be explicitly released by calling the INamedCache.Release() method when they are no longer needed, to free up any resources they might hold.

If the particular INamedCache is used for the duration of the application, then the resources are cleaned up when the application is shut down or otherwise stops. However, if it is only used for a period, the application should call its Release() method when finished using it.

Alternatively, you can leverage the fact that INamedCache extends IDisposable and that all cache implementations delegate a call to IDisposable.Dispose() to INamedCache.Release(). If you want to obtain and release a cache instance within a single method, you can do so with a using block:

Example 16-7 Obtaining and Releasing a Reference to a Cache

using (INamedCache cache = CacheFactory.GetCache("my-cache"))
{
   // use cache as usual
}

After the using block terminates, IDisposable.Dispose() is called on the INamedCache instance, and all resources associated with it are released.

16.6 Using Network Filters

A network filter is a mechanism that allows transformation of data sent through TCP/IP sockets to be performed in a pluggable, layered fashion. Coherence for .NET supports custom filters, thus enabling users to modify the contents of the network traffic and is commonly used to add compression and encryption to data.

This section includes the following topics:

16.6.1 Custom Filters

To create a filter, create a .NET class that implements the Tangosol.IO.IWrapperStreamFactory interface and optionally implements the Tangosol.Util.IXmlConfigurable interface. The IWrapperStreamFactory interface defines two methods:

Example 16-8 Methods on the IWrapperStreamFactory Interface

Stream GetInputStream(Stream stream);
Stream GetOutputStream(Stream stream);

that provide the I/O stream to be wrapped ("filtered") (on input—received message, or output—sending message) and expects a stream back that wraps the original stream. This method is called for each incoming and outgoing message.

16.6.2 Configuring Filters

There are two steps to configuring a filter. The first is to declare the filter in the <filters> XML element in an operational override file. For more information on configuring filters, see the Developing Applications with Oracle Coherence.

...
<cluster-config>
   <filters>
      <filter>
         <filter-name>gzip</filter-name>
         <filter-class>Tangosol.Net.CompressionFilter, Coherence</filter-class>
      </filter>
   </filters>
</cluster-config>
...

Note:

GZip compression filter is supported in .NET framework version 2.0 or higher.

The second step is to attach the filter to one or more specific services. To specify the filter for a specific service, for example the ExtendTcpCacheService service, add a <filter-name> element to the <use-filters> element of the service declaration in the cache configuration file.

...
<remote-cache-scheme>
   <scheme-name>extend-direct</scheme-name>
   <service-name>ExtendTcpCacheService</service-name>
   <initiator-config>
      ...
      <use-filters>
         <filter-name>gzip</filter-name>
      </use-filters>
      ...
   </initiator-config>
</remote-cache-scheme>
...

If the filter implements IXmlConfigurable, after instantiating the filter, Coherence sets the Config property with the following XML element:

<config>
  <param1>value1</param1>
  <param2>value2</param2>
</config>