All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alachisoft.ncache.client.internal.caching.FailSafeClientCache Maven / Gradle / Ivy

package com.alachisoft.ncache.client.internal.caching;

import Alachisoft.NCache.Common.AppUtil;
import Alachisoft.NCache.Common.Enum.EventType;
import Alachisoft.NCache.Common.EventCategories;
import Alachisoft.NCache.Common.EventID;
import Alachisoft.NCache.Common.Locking.LockAccessType;
import Alachisoft.NCache.Common.Logger.EventLogger;
import Alachisoft.NCache.Common.Monitoring.EventLogEntryType;
import com.alachisoft.ncache.client.*;
import com.alachisoft.ncache.client.services.SearchService;

import Alachisoft.NCache.Caching.TagComparisonType;
import com.alachisoft.ncache.client.internal.util.ConversionUtil;
import com.alachisoft.ncache.client.services.SearchService;
import com.alachisoft.ncache.runtime.CacheItemPriority;
import com.alachisoft.ncache.runtime.caching.*;
import com.alachisoft.ncache.runtime.dependencies.CacheDependency;
import com.alachisoft.ncache.runtime.events.EventDataFilter;
import com.alachisoft.ncache.runtime.exceptions.*;
import com.alachisoft.ncache.runtime.exceptions.SecurityException;
import com.alachisoft.ncache.runtime.util.TimeSpan;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.FutureTask;

public class FailSafeClientCache extends DisconnectedClientCache
{
    private CacheConnectionOptions _cacheConnectionOption;
    private String _clientCacheId;
    private boolean _isClientCacheEnable;
    private boolean _isConnectivityThreadRunning;
    private Thread _clientCacheConnectivityThread;
    private int _clientCacheConnectionRetryInterval;

    public FailSafeClientCache(CacheImpl l2, CacheImpl l1, String userid, String pswd, boolean isPessimistic, int retryL1connectionInterval) throws Exception {
        super(l2, l1, userid, pswd, isPessimistic);
        _isClientCacheEnable = true;
        _clientCacheConnectionRetryInterval = retryL1connectionInterval;
        if (super._nearCache == null)
        {
            switchToClusteredCache();
        }
    }

    public FailSafeClientCache(CacheImpl l2, CacheImpl l1, String userid, String pswd, boolean isPessimistic, CacheConnectionOptions cacheConnectionOption, String clientCacheId, int retryL1connectionInterval) throws Exception {
        super(l2, l1, userid, pswd, isPessimistic);
        this._cacheConnectionOption = cacheConnectionOption;
        this._clientCacheId = clientCacheId;
        _isClientCacheEnable = true;
        _clientCacheConnectionRetryInterval = retryL1connectionInterval;
        if (super._nearCache == null)
        {
            switchToClusteredCache();
        }
    }

    private FailSafeClientCacheSearchService privateFailSafeSearchService;
    public final FailSafeClientCacheSearchService getFailSafeSearchService()
    {
        return privateFailSafeSearchService;
    }
    public final void setFailSafeSearchService(FailSafeClientCacheSearchService value)
    {
        privateFailSafeSearchService = value;
    }
    @Override
    public SearchService getSearchService()
    {
        if (!getFailSafeSearchService().getIsClientCacheActive())
        {
            switchToClusteredCache();
        }
        return getFailSafeSearchService();
    }

    @Override
    public void setSearchService(SearchService value)
    {
        setFailSafeSearchService((FailSafeClientCacheSearchService)((value instanceof FailSafeClientCacheSearchService) ? value : null));
    }

    @Override
    public CacheImpl getNearCacheInstance()
    {
        if (_isClientCacheEnable)
        {
            _clientCacheUsed = true;
            return _nearCache;
        }
        _clientCacheUsed = false;
        return _farCache;
    }

    @Override
    public void setNearCacheProperties() throws Exception {
        if (_nearCache != null)
        {
            InitializeEncryption();
            _nearCache.setQueryTypeInfoMap(_farCache.getQueryTypeMap());
            _nearCache.setSerializationContext(_farCache.getSerializationContext());
            _nearCache.setSerializationFormat(_farCache.getSerializationFormat());
        }
        this.setFailSafeSearchService(new FailSafeClientCacheSearchService(_farCache, _nearCache));
        super.setSearchService(new ClientCacheSearchService(_farCache, _nearCache));
    }


    @Override
    protected boolean getThrowError() {
        return true;
    }

    @Override
    public CacheSyncDependency getCacheSyncDependency(String key)
    {
        if (_isClientCacheEnable)
        {
            return super.getCacheSyncDependency(key);
        }
        return null;
    }

    ///#region //------------------------Add Operation-------------------//

    @Override
    public CacheItemVersion addOperation(String key, Object value, CacheDependency dependency,
                                         CacheSyncDependency syncDependency, java.util.Date absoluteExpiration,
                                         TimeSpan slidingExpiration, CacheItemPriority priority,
                                         WriteMode writeOption, DataSourceModifiedListener dataSourceModifiedCallback,
                                         EventTypeInternal eventTypeInternal ,
                                         boolean isResyncExpiredItems, String group,
                                         Tag[] tags, String providerName, String resyncProviderName, NamedTagsDictionary namedTags,
                                         CacheDataModificationListener cacheItemUdpatedCallback,
                                         CacheDataModificationListener cacheItemRemovedCallaback,
                                         EventDataFilter itemUpdateDataFilter, EventDataFilter itemRemovedDataFilter,
                                         tangible.RefObject size,
                                         boolean allowQueryTags, String clientId, short updateCallbackID,
                                         short removeCallbackID, short dsItemAddedCallbackID) throws CacheException {

        try
        {
            return super.addOperation(key, value, dependency, null, absoluteExpiration, slidingExpiration,
                    priority, writeOption, dataSourceModifiedCallback,
                    eventTypeInternal, isResyncExpiredItems, group,
                    tags, providerName, resyncProviderName, namedTags, cacheItemUdpatedCallback, cacheItemRemovedCallaback,
                    itemUpdateDataFilter, itemRemovedDataFilter, size, allowQueryTags, clientId, updateCallbackID, removeCallbackID, dsItemAddedCallbackID);
        }
        catch (RuntimeException | CacheException e)
        {
            if (isConnectivityErrorFromClientCache(e.getMessage()))
            {
                switchToClusteredCache();

                // perform add operation
                return super.addOperation(key, value, dependency, null, absoluteExpiration, slidingExpiration,
                        priority, writeOption, dataSourceModifiedCallback,
                        eventTypeInternal, isResyncExpiredItems, group,
                        tags, providerName, resyncProviderName, namedTags, cacheItemUdpatedCallback, cacheItemRemovedCallaback,
                        itemUpdateDataFilter, itemRemovedDataFilter, size, allowQueryTags, clientId, updateCallbackID, removeCallbackID, dsItemAddedCallbackID);
            }
            if (isExceptionsEnabled())
            {
                throw e;
            }
        }
        return null;
    }


    @Override
    public java.util.Map addBulk(java.util.Map items, WriteThruOptions writeThruOptions) throws OperationFailedException, StreamNotFoundException, StreamException, ConfigurationException, CommandException, AggregateException, GeneralFailureException, OperationNotSupportedException, StreamAlreadyLockedException, LicensingException, SecurityException {
        try
        {
            return super.addBulk(items, writeThruOptions);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                return super.addBulk(items, writeThruOptions);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

        ///#endregion

    ///#region //------------------------Insert Operation-------------------//

    @Override
    public CacheItemVersion insertOperation(String key, Object value, CacheDependency dependency, CacheSyncDependency syncDependency, java.util.Date absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, WriteMode WriteMode, DataSourceModifiedListener dataSourceModifiedCallback, EventTypeInternal eventType, boolean isResyncExpiredItems, String group, LockHandle lockHandle, CacheItemVersion version, LockAccessType accessType, Tag[] tags, String providerName, String resyncProviderName, NamedTagsDictionary namedTags, CacheDataModificationListener cacheItemUdpatedCallback, CacheDataModificationListener onRemoveCallback, EventDataFilter itemUpdateDataFilter, EventDataFilter itemRemovedDataFilter, boolean allowQueryTags, String clientId, short updateCallbackId, short removeCallbackId, short dataSourceUpdatedCallbackId) throws CacheException {
        try
            {
                return super.insertOperation(key, value, dependency, syncDependency, absoluteExpiration, slidingExpiration, priority, WriteMode, dataSourceModifiedCallback, eventType, isResyncExpiredItems, group, lockHandle, version, accessType, tags, providerName,  resyncProviderName,  namedTags, cacheItemUdpatedCallback,  onRemoveCallback,  itemUpdateDataFilter,  itemRemovedDataFilter, allowQueryTags, clientId, updateCallbackId, removeCallbackId, dataSourceUpdatedCallbackId);
            }
            catch (RuntimeException | CacheException ex)
            {
                if (isConnectivityErrorFromClientCache(ex.getMessage()))
                {
                    switchToClusteredCache();
                    // perform add operation
                    return super.insertOperation(key, value, dependency, syncDependency, absoluteExpiration, slidingExpiration, priority, WriteMode, dataSourceModifiedCallback, eventType, isResyncExpiredItems, group, lockHandle, version, accessType, tags, providerName,  resyncProviderName,  namedTags, cacheItemUdpatedCallback,  onRemoveCallback,  itemUpdateDataFilter,  itemRemovedDataFilter, allowQueryTags, clientId, updateCallbackId, removeCallbackId, dataSourceUpdatedCallbackId);
                }
                if (isExceptionsEnabled())
                {
                    throw ex;
                }
            }
        return null;
    }

    @Override
    public java.util.Map insertBulk(java.util.Map items, WriteThruOptions writeThruOptions) throws CacheException {
        try
        {
            return super.insertBulk(items, writeThruOptions);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.insertBulk(items, writeThruOptions);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public boolean updateAttributes(String key, CacheItemAttributes attributes) throws CacheException {
        try
        {
            return super.updateAttributes(key, attributes);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.updateAttributes(key, attributes);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return false;
    }

        ///#endregion

        ///#region //---------------------Remove Operation----------------------//

     @Override
     public  T remove(String key,  LockHandle lockHandle, CacheItemVersion version, WriteThruOptions writeThruOptions,Class cls) throws CacheException {
        try
        {
            return super.remove(key,lockHandle, version, writeThruOptions, cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                return super.remove(key,lockHandle, version, writeThruOptions, cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public  void delete(String key,  LockHandle lockHandle, CacheItemVersion version, WriteThruOptions writeThruOptions) throws CacheException {
        try
        {
            super.delete(key,  lockHandle, version, writeThruOptions);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                super.delete(key,  lockHandle, version, writeThruOptions);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
    }

    @Override
    public  Map removeBulk(Iterable keys, WriteThruOptions writeThruOption, Class cls) throws CacheException {
        try
        {
          return super.removeBulk(keys, writeThruOption,cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                return super.removeBulk(keys, writeThruOption,cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public void deleteBulk(Iterable keys, WriteThruOptions writeThruOptions) throws CacheException {
        getNearCacheInstance().deleteBulk(keys, writeThruOptions);
        try
        {
            super.deleteBulk(keys,writeThruOptions);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                super.deleteBulk(keys,writeThruOptions);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
    }

    @Override
    public  FutureTask removeAsync(String key, WriteThruOptions writeThruOptions, Class cls)
    {
        try
        {
            return super.removeAsync(key, writeThruOptions,cls);
        }
        catch (Exception ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                return super.removeAsync(key, writeThruOptions,cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }
    ///#endregion

    ///#region Get Operations

    @Override
    public  T get(String key, ReadThruOptions readThruOptions, Class cls) throws CacheException {
        try
        {
            return super.get(key, readThruOptions, cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                return super.get(key, readThruOptions, cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public  T get(String key, CacheItemVersion version, ReadThruOptions readThruOptions, Class cls) throws CacheException
    {
        try
        {
            return super.get(key, version, readThruOptions, cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.get(key, version, readThruOptions, cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }


    @Override
    public  T get(String key, boolean acquireLock, TimeSpan lockTimeout, LockHandle lockHandle, Class cls) throws CacheException {
        try
        {
            return super.get(key, acquireLock, lockTimeout, lockHandle,cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.get(key, acquireLock, lockTimeout, lockHandle, cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public  T getInternal(String key, CacheItemVersion version,LockAccessType accessType, TimeSpan lockTimeout, LockHandle lockHandle, ReadThruOptions readOptions, Class cls) throws CacheException {
        try
        {
            return super.getInternal(key, version, accessType, lockTimeout, lockHandle, readOptions, cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();
                return super.getInternal(key, version, accessType, lockTimeout, lockHandle, readOptions, cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public  java.util.Map getBulk(Iterable keys, ReadThruOptions readThruOptions, Class cls) throws CacheException {
        try
        {
            return super.getBulk(keys, readThruOptions, cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.getBulk(keys, readThruOptions, cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public CacheItem getCacheItem(String key, ReadThruOptions readThruOptions) throws CacheException {
        try
        {
            return super.getCacheItem(key, readThruOptions);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.getCacheItem(key, readThruOptions);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public CacheItem getCacheItem(String key, boolean acquireLock, TimeSpan lockTimeout, LockHandle lockHandle) throws CacheException{

        try
        {
            return super.getCacheItem(key, acquireLock, lockTimeout, lockHandle);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.getCacheItem(key, acquireLock, lockTimeout, lockHandle);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public java.util.Map getCacheItemBulk(Iterable keys, ReadThruOptions readThruOptions) throws CacheException {

        try
        {
            return super.getCacheItemBulk(keys, readThruOptions);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.getCacheItemBulk(keys, readThruOptions);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public CacheItem getCacheItemInternal(String key, CacheItemVersion version, LockAccessType accessType, TimeSpan lockTimeout, LockHandle lockHandle, ReadThruOptions readOptions) throws CacheException {

        try
        {
            return super.getCacheItemInternal(key, version, accessType, lockTimeout, lockHandle, readOptions);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.getCacheItemInternal(key, version, accessType, lockTimeout, lockHandle, readOptions);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

    @Override
    public  T getIfNewer(String key, CacheItemVersion version,Class cls) throws CacheException {

        try
        {
            return super.getIfNewer(key, version,cls);
        }
        catch (RuntimeException | CacheException ex)
        {
            if (isConnectivityErrorFromClientCache(ex.getMessage()))
            {
                switchToClusteredCache();

                return super.getIfNewer(key, version, cls);
            }
            if (isExceptionsEnabled())
            {
                throw ex;
            }
        }
        return null;
    }

        ///#endregion

    @Override
    public void close()
    {
        if (_clientCacheConnectivityThread != null && _clientCacheConnectivityThread.isAlive())
        {
            _clientCacheConnectivityThread.interrupt();
        }
    }


    @Override
    public String toString()
    {
        return "L1 cache=" + _clientCacheId + ", L2 cache=" + _farCache.toString();
    }

    private void switchToClusteredCache() {

        synchronized (this)
        {
            _isClientCacheEnable = false;

            // start thread
            if (!_isConnectivityThreadRunning)
            {
                _isConnectivityThreadRunning = true;
                _clientCacheConnectivityThread = new Thread(new Runnable(){
                    @Override
                    public void run() {
                        try {
                            tryToReConnectL1Cache();
                        } catch (CacheException e) {
                        }
                    }
                });
                _clientCacheConnectivityThread.start();
            }
        }
    }

    private boolean isConnectivityErrorFromClientCache(String message) {
        return message.contains("No server is available") && _clientCacheUsed;
    }


    private void tryToReConnectL1Cache() throws CacheException {

        ArrayList keys = new ArrayList();
        keys.add("key");
        EventLogger.LogEvent("NCache", _clientCacheId + " is not running. All operations will be performed on clustered cache. Please start client cache, otherwise application performance may degrade.",
                EventType.WARNING, EventCategories.Warning, EventID.ClientConnectionAlert);

        while (true)
        {
            try
            {
                if (_nearCache != null)
                {
                    _nearCache.touch(keys);
                }
                else
                {
                    try {
                        _nearCache = CacheManager.initializeClientCache(_clientCacheId, _cacheConnectionOption, _farCache, true);
                         setNearCacheProperties();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                //successfull execution of command means, we are connected
                synchronized (this)
                {
                    _isClientCacheEnable = true;
                    _isConnectivityThreadRunning = false;
                    getFailSafeSearchService().SetClientCacheActive(_nearCache);
                    EventLogger.LogEvent("NCache", "Connectivity with " + _clientCacheId + " is established.",
                            EventType.INFORMATION, EventCategories.Information, EventID.ClientConnectionAlert);
                }
                break;
            }

            catch (RuntimeException | CacheException ex  )
            {
                if (!ex.getMessage().contains("No server is available"))
                {
                    throw ex;
                }
                try {
                    Thread.sleep(TimeSpan.FromSeconds(_clientCacheConnectionRetryInterval).getTotalMiliSeconds());
                } catch (InterruptedException e){}
            }
            catch(Exception ex){}
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy