ignite-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Vyacheslav Daradur (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (IGNITE-5030) Support Spring @Cacheable(sync=true) annotation
Date Fri, 21 Apr 2017 08:02:04 GMT

    [ https://issues.apache.org/jira/browse/IGNITE-5030?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15978260#comment-15978260
] 

Vyacheslav Daradur commented on IGNITE-5030:
--------------------------------------------

bq. @Cacheable(sync=true) guarantee that only one thread (across the cluster) will fetch value
for a key on get, even in case of some simultaneous gets.
The main idea is using EntryProcessor to provide such guarantee.
{code}
IgniteCache#invoke(K key, EntryProcessor<K, V, T> entryProcessor, Object... arguments)
{code}
It works well when we call #invoke directly.
But, there is an issue when using @Cachable(sync = true) with a cluster with 2+ nodes.

The main reason of the issue is that "args0" (in the code below) is an instance of CacheAspectSupport$1,

which  can't be deserialized properly at another node after a transfering, because it contains
classes wich are generated runtime by JVM.
{code}
class ValueLoaderEntryProcessor<T> implements CacheEntryProcessor<Object, Object,
T> {
        @Override public T process(MutableEntry<Object, Object> entry, Object... args)
throws EntryProcessorException {
            
             Callable<T> valueLoader = (Callable<T>)args[0];

            // working logic according to the documentations
        }
    }
{code}

Another solutions is using a lock on a key, for example:
{code}
    @Override public <T> T get(Object key, Callable<T> valueLoader) {
        Object val = cache.get(key);

        if (val != null)
            return (T)fromStoreValue(val);

        Lock lock = cache.lock(key);
        try {
            lock.lock();

            try {
                val = valueLoader.call();
            }
            catch (Exception e) {
                throw new ValueRetrievalException(key, valueLoader, e);
            }

            if (val != null)
                cache.put(key, val);
        }
        finally {
            lock.unlock();
        }
}
{code}
But it works only with TRANSACTIONAL atomicity mode.

> Support Spring @Cacheable(sync=true) annotation
> -----------------------------------------------
>
>                 Key: IGNITE-5030
>                 URL: https://issues.apache.org/jira/browse/IGNITE-5030
>             Project: Ignite
>          Issue Type: Task
>            Reporter: Anton Vinogradov
>            Assignee: Vyacheslav Daradur
>
> @Cacheable(sync=true) guarantee that only one thread (across the cluster) will fetch
value for a key on get, even in case of some simultaneous gets.
> So, 
> org.apache.ignite.cache.spring.SpringCache#get(java.lang.Object, java.util.concurrent.Callable<T>)

> should be implemented to provide such guarantee.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Mime
View raw message