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

com.fnklabs.draenei.orm.CacheableDataProvider Maven / Gradle / Ivy

package com.fnklabs.draenei.orm;

import com.codahale.metrics.Timer;
import com.fnklabs.draenei.MetricsFactory;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.CacheEntryProcessor;
import org.apache.ignite.configuration.CacheConfiguration;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.concurrent.ExecutorService;

public class CacheableDataProvider extends DataProvider {

    public static final Logger LOGGER = LoggerFactory.getLogger(CacheableDataProvider.class);

    private final IgniteCache cache;

    public CacheableDataProvider(@NotNull Class clazz,
                                 @NotNull CassandraClientFactory cassandraClient,
                                 @NotNull Ignite ignite,
                                 @NotNull ExecutorService executorService,
                                 @NotNull MetricsFactory metricsFactory) {

        super(clazz, cassandraClient, executorService, metricsFactory);

        cache = ignite.getOrCreateCache(getCacheConfiguration());
    }

    public CacheableDataProvider(@NotNull Class clazz, @NotNull CassandraClientFactory cassandraClient, @NotNull Ignite ignite, @NotNull MetricsFactory metricsFactory) {
        super(clazz, cassandraClient, metricsFactory);

        cache = ignite.getOrCreateCache(getCacheConfiguration());
    }

    @Override
    public ListenableFuture findOneAsync(Object... keys) {
        Timer.Context time = getMetricsFactory().getTimer(MetricsType.CACHEABLE_DATA_PROVIDER_FIND).time();

        long cacheKey = buildHashCode(keys);

        Entry entry = cache.get(cacheKey);

        if (entry != null) {
            getMetricsFactory().getCounter(MetricsType.CACHEABLE_DATA_PROVIDER_HITS).inc();

            return Futures.immediateFuture(entry);
        }

        // try to load entity from DB
        ListenableFuture findFuture = super.findOneAsync(keys);

        Futures.addCallback(findFuture, new FutureCallback() {
            @Override
            public void onSuccess(Entry result) {
                if (result != null) {
                    cache.put(cacheKey, result);
                }
            }

            @Override
            public void onFailure(Throwable t) {
                LOGGER.warn("Can't get entry from DB", t);
            }
        });

        monitorFuture(time, findFuture);

        return findFuture;
    }

    /**
     * Execute on entry cache
     *
     * @param entry          Entry on which will be executed entry processor
     * @param entryProcessor Entry processor that must be executed
     * @param   ClassType
     *
     * @return Return value from entry processor
     */
    public  ReturnValue execute(@NotNull Entry entry, @NotNull CacheEntryProcessor entryProcessor) {
        return cache.invoke(buildHashCode(entry), entryProcessor);
    }

    @Override
    public ListenableFuture saveAsync(@NotNull Entry entity) {
        Timer.Context time = getMetricsFactory().getTimer(MetricsType.CACHEABLE_DATA_PROVIDER_PUT_TO_CACHE).time();

        long cacheKey = buildHashCode(entity);

        return Futures.transform(super.saveAsync(entity), (Boolean result) -> {
            time.stop();
            if (result) {
                cache.put(cacheKey, entity);
            }

            return result;
        });
    }

    public ListenableFuture removeAsync(@NotNull Entry entity) {

        Timer.Context timer = getMetricsFactory().getTimer(MetricsType.CACHEABLE_DATA_PROVIDER_REMOVE_FROM_CACHE).time();

        long key = buildHashCode(entity);

        return Futures.transform(super.removeAsync(entity), (Boolean result) -> {
            timer.stop();

            return result && cache.remove(key);
        });
    }

    /**
     * Return ignite cache configuration
     *
     * @return CacheConfiguration instance
     */
    @NotNull
    public CacheConfiguration getCacheConfiguration() {
        return CacheUtils.getDefaultCacheConfiguration(getEntityClass());

    }

    protected IgniteCache getCache() {
        return cache;
    }

    @NotNull
    protected String getMapName() {
        return cache.getName();
    }

    @NotNull
    private String getMapName(Class clazz) {
        return CacheUtils.getCacheName(clazz);
    }

    protected enum MetricsType implements MetricsFactory.Type {
        CACHEABLE_DATA_PROVIDER_FIND,
        CACHEABLE_DATA_PROVIDER_PUT_TO_CACHE,
        CACHEABLE_DATA_PROVIDER_CREATE_KEY,
        CACHEABLE_DATA_PROVIDER_HITS,
        CACHEABLE_DATA_PROVIDER_REMOVE_FROM_CACHE,
        CACHEABLE_DATA_GET_FROM_DATA_GRID,
        CACHEABLE_DATA_PROVIDER_PUT_ASYNC;

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy