You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Denis Magda (JIRA)" <ji...@apache.org> on 2017/04/19 22:57:04 UTC

[jira] [Resolved] (IGNITE-2088) EntryProcessor invoke might not run in CLOCK write order

     [ https://issues.apache.org/jira/browse/IGNITE-2088?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Denis Magda resolved IGNITE-2088.
---------------------------------
       Resolution: Won't Fix
    Fix Version/s:     (was: 2.1)
                   2.0

The clock mode was discontinued on Apache Ignite 2.0. The ticket is no longer relevant.

> EntryProcessor invoke might not run in CLOCK write order
> --------------------------------------------------------
>
>                 Key: IGNITE-2088
>                 URL: https://issues.apache.org/jira/browse/IGNITE-2088
>             Project: Ignite
>          Issue Type: Bug
>    Affects Versions: ignite-1.4
>         Environment: Windows 8.1 64 bit
> java version "1.8.0_51"
> Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
> Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
> Ignite 1.4.0
>            Reporter: Avihai Berkovitz
>              Labels: newbie
>             Fix For: 2.0
>
>
> I have a program that runs several threads at the same time, all of them executing an invoke() on the same cache key to update it. I found that the EntryProcessor is not always executed, and in this case invoke() returns null. This happens when the cache is configured with CLOCK CacheAtomicWriteOrderMode, but not when using PRIMARY.
> After some debugging I found out that it happens when the cache gets the invocations out of order, and dismisses the older ones, returning the result from GridCacheMapEntry line 1855.
> As I understand it, this mechanism is in place to protect against out-of-order updates. Invokes, however, are a special case as they execute client code with unknown side effects that should not be discarded. If you believe the current behavior is correct, it should at least be documented.
> Here is a sample program to illustrate the problem. Notice that "IN INVOKE" is printed less than 10 times (usually):
> {code}
> IgniteConfiguration igniteConfiguration = new IgniteConfiguration()
> 		.setFailoverSpi(new AlwaysFailoverSpi())
> 		.setGridLogger(new Slf4jLogger())
> 		.setPeerClassLoadingEnabled(false)
> 		.setDeploymentMode(DeploymentMode.CONTINUOUS);
> Ignite ignite = Ignition.start(igniteConfiguration);
> CacheConfiguration<String, Long> cacheConfiguration = new CacheConfiguration<String, Long>()
> 		.setName("test")
> 		.setCacheMode(CacheMode.PARTITIONED)
> 		.setAtomicityMode(CacheAtomicityMode.ATOMIC)
> 		.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
> IgniteCache<String, Long> cache = ignite.getOrCreateCache(cacheConfiguration);
> Thread[] threads = new Thread[10];
> for (int i = 0; i < threads.length; i++) {
> 	threads[i] = new Thread() {
> 		@Override
> 		public void run() {
> 			System.out.println(String.format("Thread %s running", getId()));
> 			Long result = cache.invoke("key", (entry, arguments) -> {
> 				Long value = entry.getValue();
> 				System.out.println(String.format("IN INVOKE: thread ID:%s exists:%s value:%s", getId(), entry.exists(), value));
> 				if (!entry.exists()) {
> 					entry.setValue(getId());
> 				}
> 				return value;
> 			});
> 			System.out.println(String.format("Thread %s got invoke result %s", getId(), result));
> 		}
> 	};
> }
> for (Thread thread : threads) {
> 	thread.start();
> }
> Thread.sleep(2_000);
> for (Thread thread : threads) {
> 	thread.interrupt();
> }
> for (Thread thread : threads) {
> 	thread.join();
> }
> System.out.println("Done");
> {code}
> Output sample:
> {noformat}
> [13:51:41]    __________  ________________ 
> [13:51:41]   /  _/ ___/ |/ /  _/_  __/ __/ 
> [13:51:41]  _/ // (7 7    // /  / / / _/   
> [13:51:41] /___/\___/_/|_/___/ /_/ /___/  
> [13:51:41] 
> [13:51:41] ver. 1.4.0#20150924-sha1:c2def5f6
> [13:51:41] 2015 Copyright(C) Apache Software Foundation
> [13:51:41] 
> [13:51:41] Ignite documentation: http://ignite.apache.org
> [13:51:41] 
> [13:51:41] Quiet mode.
> [13:51:41]   ^-- To see **FULL** console log here add -DIGNITE_QUIET=false or "-v" to ignite.{sh|bat}
> [13:51:41] 
> [13:51:41] Initial heap size is 256MB (should be no less than 512MB, use -Xms512m -Xmx512m).
> [13:51:43] Configured plugins:
> [13:51:43]   ^-- None
> [13:51:43] 
> [13:52:04] Security status [authentication=off, communication encryption=off]
> [13:52:10] To start Console Management & Monitoring run ignitevisorcmd.{sh|bat}
> [13:52:10] 
> [13:52:10] Ignite node started OK (id=0ceced67)
> [13:52:10] Topology snapshot [ver=1, servers=1, clients=0, CPUs=8, heap=3.5GB]
> Thread 105 running
> Thread 107 running
> Thread 106 running
> Thread 108 running
> Thread 109 running
> Thread 110 running
> Thread 111 running
> Thread 112 running
> Thread 114 running
> Thread 113 running
> IN INVOKE: thread ID:107 exists:false value:null
> IN INVOKE: thread ID:113 exists:true value:107
> Thread 107 got invoke result null
> IN INVOKE: thread ID:105 exists:true value:107
> Thread 111 got invoke result null
> Thread 113 got invoke result 107
> Thread 105 got invoke result 107
> IN INVOKE: thread ID:110 exists:true value:107
> Thread 110 got invoke result 107
> Thread 106 got invoke result null
> IN INVOKE: thread ID:112 exists:true value:107
> Thread 112 got invoke result 107
> IN INVOKE: thread ID:108 exists:true value:107
> Thread 108 got invoke result 107
> Thread 109 got invoke result null
> Thread 114 got invoke result null
> Done
> {noformat}



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