Try Playground
Show / Hide Table of Contents

Read-through Caching Provider Configuration and Implementation

To use Read-through caching, you need to implement the IReadThruProvider interface for .NET and the ReadThruProvider interface for Java. NCache will use this custom implementation to read data from the data source. Please refer to Configuring Read-through in Administrators' Guide for more details.

Warning

If a Read-through caching provider is specified in client.ncconf in the default-readthru-provider tag and also through API, then the provider in API will overwrite the one specified in client.ncconf.

Note

Read-Through is [Deprecated] for NCache Java.

Prerequisites

  • .NET
  • Java
  • Legacy API
  • To learn about the standard prerequisites required to work with all NCache server-side features including Read-through caching please refer to the given page on Server Side API Prerequisites.
  • This should be a class library project using Microsoft Visual Studio.
  • Make sure to Deploy ReadThrough Provider using the NCache Management Center.
  • For API details refer to: IReadThruProvider, LoadFromSource, LoadDataTypeFromSource.
  • To learn about the standard prerequisites required to work with all NCache server-side features please refer to the given page on Server Side API Prerequisites.
  • Make sure to Deploy ReadThrough Provider using the NCache Management Center.
  • For API details refer to: ReadThruProvider, loadFromSource.
  • Create a new Console Application.
  • Make sure that the data being added is serializable.
  • Add NCache References by locating %NCHOME%\NCache\bin\assembly\4.0 and adding Alachisoft.NCache.Web and Alachisoft.NCache.Runtime as appropriate.
  • Include the Alachisoft.NCache.Runtime.DatasourceProviders namespace in your application.
Note

In NCache, Read-through caching providers are configured on the cache level, i.e., for clustered caches all nodes will contain provider configurations and their deployed assemblies.

Sample Implementation for ReadThrough Caching Provider

The following code sample provides a sample implementation to configure a Read-through caching provider using the IReadThruProvider class for .NET and the ReadThruProvider class for Java. The LoadFromSource and LoadDataTypeFromSource methods contain logic to load an object or data type respectively from the configured data source if the object is not found in the cache. Also, the GetConnectionString returns the connection string for the configured data source.

  • .NET
  • Java
  • Legacy API
public class SampleReadThruProvider : IReadThruProvider
{
    private SqlConnection _connection;

    //Perform tasks like allocating resources or acquiring connections
    public void Init(IDictionary parameters, string cacheId)
    {
        object server = parameters["server"];
        object userId = parameters["username"];
        object password = parameters["password"];
        object database = parameters["database"];

        string connString = GetConnectionString(server.ToString(), database.ToString(), userId.ToString(), password.ToString());
        if (connString != "")
            _connection = new SqlConnection(connString);
        try
        {
            _connection.Open();
        }
        catch (Exception ex)
        {
            //handle exception
        }
    }

    // Responsible for loading an item from the external data source
    public ProviderCacheItem LoadFromSource(string key)
    {
        // LoadFromDataSource loads data from data source
        object value = LoadFromDataSource(key);
        var cacheItem = new ProviderCacheItem(value);
        return cacheItem;
    }

    //Responsible for loading bulk of items from the external data source
    public IDictionary<string, ProviderCacheItem> LoadFromSource(ICollection<string> keys)
    {
        var dictionary = new Dictionary<string, ProviderCacheItem>();
        try
        {
            foreach (string key in keys)
            {
                // LoadFromDataSource loads data from data source
                dictionary.Add(key, new ProviderCacheItem(LoadFromDataSource(key)));
            }
            return dictionary;
        }
        catch (Exception exp)
        {
            // Handle exception
        }
        return dictionary;
    }

    // Adds ProviderDataTypeItem with enumerable data type
    public ProviderDataTypeItem<IEnumerable> LoadDataTypeFromSource(string key, DistributedDataType dataType)
    {
        IEnumerable value = null;
        ProviderDataTypeItem<IEnumerable> dataTypeItem = null;

        switch (dataType)
        {
            case DistributedDataType.List:
                value = new List<object>()
                {
                    LoadFromDataSource(key)
                };
                dataTypeItem = new ProviderDataTypeItem<IEnumerable>(value);
                break;
            case DistributedDataType.Dictionary:
                value = new Dictionary<string, object>()
                {
                    { key ,  LoadFromDataSource(key) }
                };
                dataTypeItem = new ProviderDataTypeItem<IEnumerable>(value);
                break;
            case DistributedDataType.Counter:
                dataTypeItem = new ProviderDataTypeItem<IEnumerable>(1000);
                break;
        }
        return dataTypeItem;
    }

    //Perform tasks associated with freeing, releasing, or resetting resources.
    public void Dispose()
    {
        if (_connection != null)
        {
            _connection.Close();
        }
    }

    private object LoadFromDataSource(string key)
    {
        object retrievedObject = null;

        // Load item from your data source and populate retrieved Object
        return retrievedObject;
    }

    private string GetConnectionString(string server, string database, string userName, string password)
    {
        string connectionString = null;
        try
        {
            if (!string.IsNullOrEmpty(server))
            {
                connectionString = "Server=" + server + ";";
            }
            else
            {
                //Server name is empty
            }
            if (!string.IsNullOrEmpty(database))
            {
                connectionString = connectionString + "Database=" + database + ";";
            }
            else
            {
                //Database is empty;
            }
            if (!string.IsNullOrEmpty(userName))
            {
                connectionString = connectionString + "User ID=" + userName + ";";
            }
            else
            {
                connectionString = connectionString + "User ID=" + "" + ";";
            }
            if (!string.IsNullOrEmpty(password))
            {
                connectionString = connectionString + "Password=" + password + ";";
            }
            else
            {
                connectionString = connectionString + "Password=" + "" + ";";
            }
        }
        catch (Exception exp)
        {
            // Handle exception
        }
        return connectionString;
    }
    // Deploy this class on cache
}
public class SampleReadThruProvider implements ReadThruProvider {
    private Connection _connection;

    //Perform tasks like allocating resources or acquiring connections
    public void init(Map<String,String> parameters, String cacheId) throws SQLException {
        String connString = getConnectionString(parameters);

        if (connString.isEmpty()) {
            _connection.prepareStatement(connString);
            _connection.beginRequest();
        }
    }

    // Responsible for loading an item from the external data source
    public ProviderCacheItem loadFromSource(String key) {
        // LoadFromDataSource loads data from data source
        var value = loadFromDataSource(key);
        var cacheItem = new ProviderCacheItem(value);
        return cacheItem;
    }

    //Responsible for loading bulk of items from the external data source
    public Map<String,ProviderCacheItem> loadFromSource(Collection<String> keys) {
       var dictionary = new HashMap<String,ProviderCacheItem>();
        try {
            for (String key: keys) {
                // LoadFromDataSource loads data from data source
                dictionary.put(key,new ProviderCacheItem(loadFromDataSource(key)));
            }
            return dictionary;
        } catch (Exception ex) {
            // Handle exception
        }
        return dictionary;
    }

    // Adds ProviderDataTypeItem with enumerable data type
    public ProviderDataStructureItem<Iterator> loadDataStructureFromSource(String key, DistributedDataStructureType distributedDataStructureType) throws OperationFailedException {
        Iterator value = null;
        ProviderDataStructureItem<Iterator> dataStructureItem = null;

        switch (distributedDataStructureType) {
            case List:
                // provide your own logic here
                 value = (Iterator) new ArrayList<String>();
                dataStructureItem = new ProviderDataStructureItem<Iterator>(value);
                break;
            case Map:
                value = (Iterator) new HashMap<String,Object>();
                // provide your own logic here
                dataStructureItem = new ProviderDataStructureItem<Iterator>(value);
                break;
            case Counter:
                // provide your own logic here
                dataStructureItem = new ProviderDataStructureItem<Iterator>(1000);
                break;
        }
        return dataStructureItem;
    }

    //Perform tasks associated with freeing, releasing, or resetting resources.
    public void close() throws SQLException {
        if (_connection != null) {
            _connection.close();
        }
    }

    private Object loadFromDataSource(String key) {
        Object retrievedObject = null;

        // Load item from your data source and populate retrieved Object
        return retrievedObject;
    }

    public String getConnectionString(Map parameters) {
        String connectionString = null;
        try {
            String server = parameters.get("server").toString();
            String database = parameters.get("database").toString();
            String userName = parameters.get("username").toString();
            String password = parameters.get("password").toString();

            if (!server.isEmpty()) {
                connectionString = "Server=" + server + ";";
            } else {
                // Server name is empty
            }
            if (!database.isEmpty()) {
                connectionString = connectionString + "Database=" + database + ";";
            } else {
                // Database is empty
            }
            if (!userName.isEmpty()) {
                connectionString = connectionString + "User ID=" + userName + ";";
            } else {
                connectionString = connectionString + "User ID=" + "" + ";";
            }
            if (!password.isEmpty()) {
                connectionString = connectionString + "Password=" + password + ";";
            } else {
                connectionString = connectionString + "Password=" + "" + ";";
            }
        } catch (Exception ex) {
            // Handle exception
        }
        return connectionString;
    }
}
public class SampleReadThruProvider : IReadThruProvider
{
    private SqlConnection _connection;
    //Perform tasks like allocating resources or acquiring connections

    public void Init(IDictionary parameters, string cacheId)
    {
        object server = parameters["server"];
        object userId = parameters["username"];
        object password = parameters["password"];
        object database = parameters["database"];
        string connString = GetConnectionString(server.ToString(), database.ToString(), userId.ToString(), password.ToString());
        if (connString != "")
            _connection = new SqlConnection(connString);
        try
        {
            _connection.Open();
        }
        catch (Exception ex)
        {
            //handle exception
        }
    }

    //Responsible for loading an item from the external data source.
    public void LoadFromSource(string key, out ProviderCacheItem cacheItem)
    {
        //where LoadFromDataSource is the dummy method to load data from data source.
        object value = LoadFromDataSource(key);

        cacheItem = new ProviderCacheItem(value);
        cacheItem.ResyncItemOnExpiration = true;
    }

    //Perform tasks associated with freeing, releasing, or resetting resources.
    public void Dispose()
    {
        if (_connection != null)
            _connection.Close();
    }

    //Responsible for loading bulk of items from the external data source.
    public Dictionary<string, ProviderCacheItem> LoadFromSource(string[] keys)
    {
        Dictionary<string, ProviderCacheItem> dictionary = new Dictionary<string, ProviderCacheItem>();
        try
        {
            string key = null;
            for (int index = 0; index < keys.Length; index++)
            {
                key = keys[index];

                //where LoadFromDataSource is the dummy method to load data from data source.
                dictionary.Add(key, new ProviderCacheItem(LoadFromDataSource(key)));
            }
            return dictionary;
        }
        catch (Exception exp)
        {
            //handle exception
        }

        return dictionary;
    }
    private object LoadFromDataSource(string key)
    {
        object retrievedObject = null;
        // load item from your data source and populate retrieved Object
        return retrievedObject;
    }

    private string GetConnectionString (string server, string database, string userName, string password)
    {
        string connectionString = null;
        try
        {
            if (!string.IsNullOrEmpty(server))
                connectionString = "Server=" + server + ";";
            else
                //Server name is empty

            if (!string.IsNullOrEmpty(database))
                connectionString = connectionString + "Database=" + database + ";";
            else
                //Database is empty;

            if (!string.IsNullOrEmpty(userName))
                connectionString = connectionString + "User ID=" + userName + ";";
            else
                connectionString = connectionString+ "User ID=" + "" + ";";

            if (!string.IsNullOrEmpty(password))
                connectionString = connectionString + "Password=" + password + ";";
            else
                connectionString = connectionString + "Password=" + "" + ";";
        }
        catch (Exception exp)
        {
            // handle exception
        }
        return connectionString;
    }
}
Note

To ensure the operation is fail-safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.

Additional Resources

NCache provides a sample application for Read-through on GitHub.

See Also

.NET: Alachisoft.NCache.Runtime namespace.
Java: com.alachisoft.ncache.runtime.datasourceprovider namespace.

In This Article
  • Prerequisites
  • Sample Implementation for ReadThrough Caching Provider
  • Additional Resources
  • See Also

Contact Us

PHONE

+1 (214) 764-6933   (US)

+44 20 7993 8327   (UK)

 
EMAIL

sales@alachisoft.com

support@alachisoft.com

NCache
  • NCache Enterprise
  • NCache Professional
  • Edition Comparison
  • NCache Architecture
  • Benchmarks
Download
Pricing
Try Playground

Deployments
  • Cloud (SaaS & Software)
  • On-Premises
  • Kubernetes
  • Docker
Technical Use Cases
  • ASP.NET Sessions
  • ASP.NET Core Sessions
  • Pub/Sub Messaging
  • Real-Time ASP.NET SignalR
  • Internet of Things (IoT)
  • NoSQL Database
  • Stream Processing
  • Microservices
Resources
  • Magazine Articles
  • Third-Party Articles
  • Articles
  • Videos
  • Whitepapers
  • Shows
  • Talks
  • Blogs
  • Docs
Customer Case Studies
  • Testimonials
  • Customers
Support
  • Schedule a Demo
  • Forum (Google Groups)
  • Tips
Company
  • Leadership
  • Partners
  • News
  • Events
  • Careers
Contact Us

  • EnglishChinese (Simplified)FrenchGermanItalianJapaneseKoreanPortugueseSpanish

  • Contact Us
  •  
  • Sitemap
  •  
  • Terms of Use
  •  
  • Privacy Policy
© Copyright Alachisoft 2002 - 2025. All rights reserved. NCache is a registered trademark of Diyatech Corp.
Back to top