You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by yz...@apache.org on 2015/10/28 16:22:50 UTC
[01/23] ignite git commit: IGNITE-1747 Fix code style and Javadoc
issues in MQTT streamer.
Repository: ignite
Updated Branches:
refs/heads/ignite-1.4-slow-server-debug 10956be4e -> aa3de3864
IGNITE-1747 Fix code style and Javadoc issues in MQTT streamer.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/cb0d432f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/cb0d432f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/cb0d432f
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: cb0d432f358615b12a65eb62f4b03b70680b3575
Parents: 43b40f4
Author: Raul Kripalani <ra...@apache.org>
Authored: Tue Oct 20 18:36:52 2015 +0100
Committer: Raul Kripalani <ra...@apache.org>
Committed: Tue Oct 20 18:37:20 2015 +0100
----------------------------------------------------------------------
.../apache/ignite/stream/mqtt/MqttStreamer.java | 252 +++++++++++++------
.../stream/mqtt/IgniteMqttStreamerTest.java | 35 ++-
.../mqtt/IgniteMqttStreamerTestSuite.java | 2 +-
3 files changed, 206 insertions(+), 83 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0d432f/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
index f18ae42..39d8d6e 100644
--- a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
+++ b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
@@ -18,6 +18,7 @@
package org.apache.ignite.stream.mqtt;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
@@ -70,10 +71,10 @@ import org.eclipse.paho.client.mqttv3.MqttMessage;
* </ul>
*
* Note: features like durable subscriptions, last will testament, etc. can be configured via the
- * {@link #connectOptions} property.
+ * {@link #setConnectOptions(MqttConnectOptions)} setter.
*
* @see <a href="https://github.com/rholder/guava-retrying">guava-retrying library</a>
- * @author Raul Kripalani
+ *
*/
public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> implements MqttCallback {
@@ -137,7 +138,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
private volatile boolean connected;
/** Cached log prefix for cache messages. */
- private String cachedLogPrefix;
+ private String cachedLogValues;
/**
* Starts streamer.
@@ -150,9 +151,12 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
// for simplicity, if these are null initialize to empty lists
topics = topics == null ? new ArrayList<String>() : topics;
+
qualitiesOfService = qualitiesOfService == null ? new ArrayList<Integer>() : qualitiesOfService;
try {
+ Map<String, Object> logValues = new HashMap<>();
+
// parameter validations
A.notNull(getStreamer(), "streamer");
A.notNull(getIgnite(), "ignite");
@@ -162,9 +166,8 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
A.notNullOrEmpty(brokerUrl, "broker URL");
// if the client ID is empty, generate one
- if (clientId == null || clientId.length() == 0) {
+ if (clientId == null || clientId.length() == 0)
clientId = MqttClient.generateClientId();
- }
// if we have both a single topic and a list of topics (but the list of topic is not of
// size 1 and == topic, as this would be a case of re-initialization), fail
@@ -174,15 +177,13 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
// same as above but for QoS
if (qualityOfService != null && !qualitiesOfService.isEmpty() && qualitiesOfService.size() != 1 &&
- !qualitiesOfService.get(0).equals(qualityOfService)) {
+ !qualitiesOfService.get(0).equals(qualityOfService))
throw new IllegalArgumentException("Cannot specify both a single QoS and a list at the same time");
- }
// Paho API requires disconnect timeout if providing a quiesce timeout and disconnecting forcibly
- if (disconnectForcibly && disconnectQuiesceTimeout != null) {
+ if (disconnectForcibly && disconnectQuiesceTimeout != null)
A.notNull(disconnectForciblyTimeout, "disconnect timeout cannot be null when disconnecting forcibly " +
"with quiesce");
- }
// if we have multiple topics
if (!topics.isEmpty()) {
@@ -192,7 +193,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
A.ensure(qualitiesOfService.isEmpty() || qualitiesOfService.size() == topics.size(), "qualities of " +
"service must be either empty or have the same size as topics list");
- cachedLogPrefix = "[" + Joiner.on(",").join(topics) + "]";
+ logValues.put("topics", topics);
}
else { // just the single topic
topics.add(topic);
@@ -200,9 +201,16 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
if (qualityOfService != null)
qualitiesOfService.add(qualityOfService);
- cachedLogPrefix = "[" + topic + "]";
+ logValues.put("topic", topic);
}
+ // finish building log values
+ logValues.put("brokerUrl", brokerUrl);
+ logValues.put("clientId", clientId);
+
+ // cache log values
+ cachedLogValues = "[" + Joiner.on(", ").withKeyValueSeparator("=").join(logValues) + "]";
+
// create logger
log = getIgnite().log();
@@ -232,6 +240,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
// create the connection retrier
connectionRetrier = new MqttConnectionRetrier(retrier);
+
+ log.info("Starting MQTT Streamer " + cachedLogValues);
+
+ // connect
connectionRetrier.connect();
}
@@ -286,6 +298,9 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
// -------------------------------
/**
+ * Implements the {@link MqttCallback#connectionLost(Throwable)} callback method for the MQTT client to inform the
+ * streamer that the connection has been lost.
+ *
* {@inheritDoc}
*/
@Override public void connectionLost(Throwable throwable) {
@@ -295,31 +310,41 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
if (stopped)
return;
- log.warning(String.format("MQTT Connection to server %s was lost.", brokerUrl), throwable);
+ log.warning(String.format("MQTT Connection to broker was lost [brokerUrl=%s, type=%s, err=%s]", brokerUrl,
+ throwable.getClass(), throwable.getMessage()));
+
connectionRetrier.connect();
}
/**
+ * Implements the {@link MqttCallback#messageArrived(String, MqttMessage)} to receive an MQTT message.
+ *
* {@inheritDoc}
*/
@Override public void messageArrived(String topic, MqttMessage message) throws Exception {
if (getMultipleTupleExtractor() != null) {
Map<K, V> entries = getMultipleTupleExtractor().extract(message);
- if (log.isTraceEnabled()) {
+
+ if (log.isTraceEnabled())
log.trace("Adding cache entries: " + entries);
- }
+
getStreamer().addData(entries);
}
else {
Map.Entry<K, V> entry = getSingleTupleExtractor().extract(message);
- if (log.isTraceEnabled()) {
+
+ if (log.isTraceEnabled())
log.trace("Adding cache entry: " + entry);
- }
+
getStreamer().addData(entry);
}
}
/**
+ * Empty implementation of {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)}.
+ *
+ * Not required by the streamer as it doesn't produce messages.
+ *
* {@inheritDoc}
*/
@Override public void deliveryComplete(IMqttDeliveryToken token) {
@@ -331,13 +356,8 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
// -------------------------------
/**
- * @return
- */
- public String getBrokerUrl() {
- return brokerUrl;
- }
-
- /**
+ * Sets the broker URL (compulsory).
+ *
* @param brokerUrl The Broker URL (compulsory).
*/
public void setBrokerUrl(String brokerUrl) {
@@ -345,189 +365,262 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
}
/**
- * @return
+ * Gets the broker URL.
+ *
+ * @return The Broker URL.
*/
- public String getTopic() {
- return topic;
+ public String getBrokerUrl() {
+ return brokerUrl;
}
/**
- * @param topic The topic to subscribe to, if a single topic.
+ * Sets the topic to subscribe to, if a single topic.
+ *
+ * @param topic The topic to subscribe to.
*/
public void setTopic(String topic) {
this.topic = topic;
}
/**
- * @return
+ * Gets the subscribed topic.
+ *
+ * @return The subscribed topic.
*/
- public Integer getQualityOfService() {
- return qualityOfService;
+ public String getTopic() {
+ return topic;
}
/**
- * @param qualityOfService The quality of service to use for a single topic subscription (optional).
+ * Sets the quality of service to use for a single topic subscription (optional).
+ *
+ * @param qualityOfService The quality of service.
*/
public void setQualityOfService(Integer qualityOfService) {
this.qualityOfService = qualityOfService;
}
/**
- * @return
+ * Gets the quality of service set by the user for a single topic consumption.
+ *
+ * @return The quality of service.
*/
- public List<String> getTopics() {
- return topics;
+ public Integer getQualityOfService() {
+ return qualityOfService;
}
/**
- * @param topics The topics to subscribe to, if many.
+ * Sets the topics to subscribe to, if many.
+ *
+ * @param topics The topics.
*/
public void setTopics(List<String> topics) {
this.topics = topics;
}
/**
- * @return
+ * Gets the topics subscribed to.
+ *
+ * @return The topics subscribed to.
*/
- public List<Integer> getQualitiesOfService() {
- return qualitiesOfService;
+ public List<String> getTopics() {
+ return topics;
}
/**
- * @param qualitiesOfService The qualities of service to use for multiple topic subscriptions.
- * If specified, the list must contain the same number of elements as {@link #topics}.
+ * Sets the qualities of service to use for multiple topic subscriptions. If specified, the list must contain the
+ * same number of elements as {@link #topics}.
+ *
+ * @param qualitiesOfService The qualities of service.
*/
public void setQualitiesOfService(List<Integer> qualitiesOfService) {
this.qualitiesOfService = qualitiesOfService;
}
/**
- * @return
+ * Gets the qualities of service for multiple topics.
+ *
+ * @return The qualities of service.
*/
- public String getClientId() {
- return clientId;
+ public List<Integer> getQualitiesOfService() {
+ return qualitiesOfService;
}
/**
- * @param clientId The MQTT client ID (optional). If one is not provided, we'll create one for you and maintain
+ * Sets the MQTT client ID (optional). If one is not provided, the streamer will generate one and will maintain
* it througout any reconnection attempts.
+ *
+ * @param clientId The client ID.
*/
public void setClientId(String clientId) {
this.clientId = clientId;
}
/**
- * @return
+ * Gets the client ID, either the one set by the user or the automatically generated one.
+ *
+ * @return The client ID.
+ */
+ public String getClientId() {
+ return clientId;
+ }
+
+ /**
+ * Gets the currently set persistence mechanism.
+ *
+ * @return The persistence mechanism.
*/
public MqttClientPersistence getPersistence() {
return persistence;
}
/**
- * @param persistence A configurable persistence mechanism. If not set, Paho will use its default.
+ * Sets the persistence mechanism. If not set, Paho will use its default.
+ *
+ * @param persistence A configurable persistence mechanism.
*/
public void setPersistence(MqttClientPersistence persistence) {
this.persistence = persistence;
}
/**
- * @return
+ * Gets the currently used MQTT client connect options.
+ *
+ * @return The MQTT client connect options.
*/
public MqttConnectOptions getConnectOptions() {
return connectOptions;
}
/**
- * @param connectOptions The MQTT client connect options, where users can configured the last will and testament, durability, etc.
+ * Sets the MQTT client connect options, where users can configured the last will and testament, durability, etc.
+ *
+ * @param connectOptions The MQTT client connect options.
*/
public void setConnectOptions(MqttConnectOptions connectOptions) {
this.connectOptions = connectOptions;
}
/**
- * @return
+ * Sets whether to disconnect forcibly or not when shutting down. By default, it's <tt>false</tt>.
+ *
+ * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's <tt>false</tt>.
+ */
+ public void setDisconnectForcibly(boolean disconnectForcibly) {
+ this.disconnectForcibly = disconnectForcibly;
+ }
+
+ /**
+ * Gets whether this MQTT client will disconnect forcibly when shutting down.
+ *
+ * @return Whether to disconnect forcibly or not.
*/
public boolean isDisconnectForcibly() {
return disconnectForcibly;
}
/**
- * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's false.
+ * Sets the quiesce timeout on disconnection. If not provided, this streamer won't use any.
+ *
+ * @param disconnectQuiesceTimeout The disconnect quiesce timeout.
*/
- public void setDisconnectForcibly(boolean disconnectForcibly) {
- this.disconnectForcibly = disconnectForcibly;
+ public void setDisconnectQuiesceTimeout(Integer disconnectQuiesceTimeout) {
+ this.disconnectQuiesceTimeout = disconnectQuiesceTimeout;
}
/**
- * @return
+ * Gets the disconnect quiesce timeout.
+ *
+ * @return The disconnect quiesce timeout.
*/
public Integer getDisconnectQuiesceTimeout() {
return disconnectQuiesceTimeout;
}
/**
- * @param disconnectQuiesceTimeout Quiesce timeout on disconnection. If not provided, this streamer won't use any.
+ * Sets the timeout if disconnecting forcibly. Compulsory in that case.
+ *
+ * @param disconnectForciblyTimeout The disconnect forcibly timeout.
*/
- public void setDisconnectQuiesceTimeout(Integer disconnectQuiesceTimeout) {
- this.disconnectQuiesceTimeout = disconnectQuiesceTimeout;
+ public void setDisconnectForciblyTimeout(Integer disconnectForciblyTimeout) {
+ this.disconnectForciblyTimeout = disconnectForciblyTimeout;
}
/**
- * @return
+ * Gets the timeout if disconnecting forcibly.
+ *
+ * @return Timeout.
*/
public Integer getDisconnectForciblyTimeout() {
return disconnectForciblyTimeout;
}
/**
- * @param disconnectForciblyTimeout If disconnecting forcibly, the timeout. Compulsory in that case.
+ * Sets the strategy to determine how long to wait between retry attempts. By default, this streamer uses a
+ * Fibonacci-based strategy.
+ *
+ * @param retryWaitStrategy The retry wait strategy.
*/
- public void setDisconnectForciblyTimeout(Integer disconnectForciblyTimeout) {
- this.disconnectForciblyTimeout = disconnectForciblyTimeout;
+ public void setRetryWaitStrategy(WaitStrategy retryWaitStrategy) {
+ this.retryWaitStrategy = retryWaitStrategy;
}
/**
- * @return
+ * Gets the retry wait strategy.
+ *
+ * @return The retry wait strategy.
*/
public WaitStrategy getRetryWaitStrategy() {
return retryWaitStrategy;
}
/**
- * @param retryWaitStrategy The strategy to determine how long to wait between retry attempts.
- * By default, this streamer uses a Fibonacci-based strategy.
+ * Sets the strategy to determine when to stop retrying to (re-)connect. By default, we never stop.
+ *
+ * @param retryStopStrategy The retry stop strategy.
*/
- public void setRetryWaitStrategy(WaitStrategy retryWaitStrategy) {
- this.retryWaitStrategy = retryWaitStrategy;
+ public void setRetryStopStrategy(StopStrategy retryStopStrategy) {
+ this.retryStopStrategy = retryStopStrategy;
}
/**
- * @return
+ * Gets the retry stop strategy.
+ *
+ * @return The retry stop strategy.
*/
public StopStrategy getRetryStopStrategy() {
return retryStopStrategy;
}
/**
- * @param retryStopStrategy The strategy to determine when to stop retrying to (re-)connect. By default, we never stop.
+ * Sets whether to block the start() method until connected for the first time. By default, it's <tt>false</tt>.
+ *
+ * @param blockUntilConnected Whether to block or not.
*/
- public void setRetryStopStrategy(StopStrategy retryStopStrategy) {
- this.retryStopStrategy = retryStopStrategy;
+ public void setBlockUntilConnected(boolean blockUntilConnected) {
+ this.blockUntilConnected = blockUntilConnected;
}
- /**
- * @return
- */
public boolean isBlockUntilConnected() {
return blockUntilConnected;
}
/**
- * @param blockUntilConnected Whether to block the start() method until connected for the first time. By default,
- * false.
+ * Returns whether this streamer is stopped.
+ *
+ * @return <tt>true</tt> if stopped; <tt>false</tt> if not.
*/
- public void setBlockUntilConnected(boolean blockUntilConnected) {
- this.blockUntilConnected = blockUntilConnected;
+ public boolean isStopped() {
+ return stopped;
+ }
+
+ /**
+ * Returns whether this streamer is connected.
+ *
+ * @return <tt>true</tt> if connected; <tt>false</tt> if not.
+ */
+ public boolean isConnected() {
+ return connected;
}
/**
@@ -551,7 +644,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
}
/**
- * Method that is called by the streamer to ask us to (re-)connect.
+ * Method called by the streamer to ask us to (re-)connect.
*/
public void connect() {
Callable<Boolean> callable = retrier.wrap(new Callable<Boolean>() {
@@ -576,12 +669,15 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
else {
int[] qoses = new int[qualitiesOfService.size()];
+
for (int i = 0; i < qualitiesOfService.size(); i++)
qoses[i] = qualitiesOfService.get(i);
client.subscribe(topics.toArray(new String[0]), qoses);
}
+ log.info("MQTT Streamer (re-)connected and subscribed " + cachedLogValues);
+
connected = true;
return connected;
}
@@ -608,4 +704,4 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0d432f/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
index 5ac7339..76404b8 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
@@ -105,6 +105,10 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
super(true);
}
+ /**
+ *
+ * @throws Exception
+ */
@Before @SuppressWarnings("unchecked")
public void beforeTest() throws Exception {
grid().<Integer, String>getOrCreateCache(defaultCacheConfiguration());
@@ -123,7 +127,9 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
PolicyMap policyMap = new PolicyMap();
PolicyEntry policy = new PolicyEntry();
+
policy.setQueuePrefetch(1);
+
broker.setDestinationPolicy(policyMap);
broker.getDestinationPolicy().setDefaultEntry(policy);
broker.setSchedulerSupport(false);
@@ -138,13 +144,19 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
// create the client and connect
client = new MqttClient(brokerUrl, UUID.randomUUID().toString(), new MemoryPersistence());
+
client.connect();
// create mqtt streamer
dataStreamer = grid().dataStreamer(null);
+
streamer = createMqttStreamer(dataStreamer);
}
+ /**
+ *
+ * @throws Exception
+ */
@After
public void afterTest() throws Exception {
try {
@@ -160,7 +172,6 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
broker.stop();
broker.deleteAllMessages();
-
}
/**
@@ -327,7 +338,9 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
broker.stop();
broker.start(true);
broker.waitUntilStarted();
+
Thread.sleep(2000);
+
client.connect();
// let's ensure we have 2 connections: Ignite and our test
@@ -370,14 +383,17 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
// now shutdown the broker, wait 2 seconds and start it again
broker.stop();
broker.start(true);
+
broker.waitUntilStarted();
+
client.connect();
// lets send messages and ensure they are not received, because our retrier desisted
sendMessages(Arrays.asList(SINGLE_TOPIC_NAME), 50, 50, false);
+
Thread.sleep(3000);
- assertNull(grid().cache(null).get(50));
+ assertNull(grid().cache(null).get(50));
}
/**
@@ -422,8 +438,8 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
catch (Exception e) {
return;
}
- fail("Expected an exception reporting invalid parameters");
+ fail("Expected an exception reporting invalid parameters");
}
/**
@@ -449,28 +465,34 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
private void sendMessages(final List<String> topics, int fromIdx, int count, boolean singleMessage) throws MqttException {
if (singleMessage) {
final List<StringBuilder> sbs = new ArrayList<>(topics.size());
+
// initialize String Builders for each topic
F.forEach(topics, new IgniteInClosure<String>() {
@Override public void apply(String s) {
sbs.add(new StringBuilder());
}
});
+
// fill String Builders for each topic
F.forEach(F.range(fromIdx, fromIdx + count), new IgniteInClosure<Integer>() {
@Override public void apply(Integer integer) {
sbs.get(integer % topics.size()).append(integer.toString() + "," + TEST_DATA.get(integer) + "\n");
}
});
+
// send each buffer out
for (int i = 0; i < topics.size(); i++) {
MqttMessage msg = new MqttMessage(sbs.get(i).toString().getBytes());
+
client.publish(topics.get(i % topics.size()), msg);
}
}
else {
for (int i = fromIdx; i < fromIdx + count; i++) {
byte[] payload = (i + "," + TEST_DATA.get(i)).getBytes();
+
MqttMessage msg = new MqttMessage(payload);
+
client.publish(topics.get(i % topics.size()), msg);
}
}
@@ -487,6 +509,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
@SuppressWarnings("serial") IgniteBiPredicate<UUID, CacheEvent> callback = new IgniteBiPredicate<UUID, CacheEvent>() {
@Override public boolean apply(UUID uuid, CacheEvent evt) {
latch.countDown();
+
return true;
}
};
@@ -522,6 +545,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
return new StreamSingleTupleExtractor<MqttMessage, Integer, String>() {
@Override public Map.Entry<Integer, String> extract(MqttMessage msg) {
List<String> s = Splitter.on(",").splitToList(new String(msg.getPayload()));
+
return new GridMapEntry<>(Integer.parseInt(s.get(0)), s.get(1));
}
};
@@ -539,15 +563,18 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
.omitEmptyStrings()
.withKeyValueSeparator(",")
.split(new String(msg.getPayload()));
+
final Map<Integer, String> answer = new HashMap<>();
+
F.forEach(map.keySet(), new IgniteInClosure<String>() {
@Override public void apply(String s) {
answer.put(Integer.parseInt(s), map.get(s));
}
});
+
return answer;
}
};
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0d432f/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
index ff25145..413eaab 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
@@ -31,4 +31,4 @@ import org.junit.runners.Suite;
})
public class IgniteMqttStreamerTestSuite {
-}
\ No newline at end of file
+}
[13/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
index fe519a7..3c3527a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
@@ -221,34 +221,9 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
return true;
}
- /** {@inheritDoc} */
- @SuppressWarnings({"unchecked", "RedundantCast"})
- @Override public IgniteInternalFuture<Object> readThroughAllAsync(
- Collection<KeyCacheObject> keys,
- boolean reload,
- boolean skipVals,
- IgniteInternalTx tx,
- @Nullable UUID subjId,
- String taskName,
- IgniteBiInClosure<KeyCacheObject, Object> vis
- ) {
- return (IgniteInternalFuture)loadAsync(tx,
- keys,
- reload,
- /*force primary*/false,
- subjId,
- taskName,
- /*deserialize portable*/true,
- /*expiry policy*/null,
- skipVals,
- /*skip store*/false,
- /*can remap*/true);
- }
-
/**
* @param tx Transaction.
* @param keys Keys to load.
- * @param reload Reload flag.
* @param forcePrimary Force primary flag.
* @param subjId Subject ID.
* @param taskName Task name.
@@ -256,11 +231,11 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
* @param expiryPlc Expiry policy.
* @param skipVal Skip value flag.
* @param skipStore Skip store flag.
+ * @param canRemap Can remap flag.
* @return Loaded values.
*/
public IgniteInternalFuture<Map<K, V>> loadAsync(@Nullable IgniteInternalTx tx,
@Nullable Collection<KeyCacheObject> keys,
- boolean reload,
boolean forcePrimary,
@Nullable UUID subjId,
String taskName,
@@ -280,7 +255,6 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
GridNearGetFuture<K, V> fut = new GridNearGetFuture<>(ctx,
keys,
!skipStore,
- reload,
forcePrimary,
txx,
subjId,
@@ -288,7 +262,9 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
deserializePortable,
expiry,
skipVal,
- canRemap);
+ canRemap,
+ false,
+ false);
// init() will register future for responses if future has remote mappings.
fut.init();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
index 2ae03d3..d558cc5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
@@ -46,7 +46,7 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;
@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "TooBroadScope"})
public class GridNearCacheEntry extends GridDistributedCacheEntry {
/** */
- private static final int NEAR_SIZE_OVERHEAD = 36;
+ private static final int NEAR_SIZE_OVERHEAD = 36 + 16;
/** Topology version at the moment when value was initialized from primary node. */
private volatile long topVer = -1L;
@@ -58,6 +58,9 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
/** Partition. */
private int part;
+ /** */
+ private short evictReservations;
+
/**
* @param ctx Cache context.
* @param key Cache key.
@@ -316,15 +319,21 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
primaryNode(primaryNodeId, topVer);
}
- /**
- * This method should be called only when committing optimistic transactions.
- *
+ /*
* @param dhtVer DHT version to record.
+ * @return {@code False} if given version is lower then existing version.
*/
- public synchronized void recordDhtVersion(GridCacheVersion dhtVer) {
- // Version manager must be updated separately, when adding DHT version
- // to transaction entries.
- this.dhtVer = dhtVer;
+ public final boolean recordDhtVersion(GridCacheVersion dhtVer) {
+ assert dhtVer != null;
+ assert Thread.holdsLock(this);
+
+ if (this.dhtVer == null || this.dhtVer.compareTo(dhtVer) <= 0) {
+ this.dhtVer = dhtVer;
+
+ return true;
+ }
+
+ return false;
}
/** {@inheritDoc} */
@@ -332,7 +341,6 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
UUID subjId, String taskName) throws IgniteCheckedException {
return cctx.near().loadAsync(tx,
F.asList(key),
- reload,
/*force primary*/false,
subjId,
taskName,
@@ -350,7 +358,6 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
* @param val New value.
* @param ver Version to use.
* @param dhtVer DHT version received from remote node.
- * @param expVer Optional version to match.
* @param ttl Time to live.
* @param expireTime Expiration time.
* @param evt Event flag.
@@ -366,14 +373,13 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
CacheObject val,
GridCacheVersion ver,
GridCacheVersion dhtVer,
- @Nullable GridCacheVersion expVer,
long ttl,
long expireTime,
boolean evt,
AffinityTopologyVersion topVer,
UUID subjId)
throws IgniteCheckedException, GridCacheEntryRemovedException {
- boolean valid = valid(tx != null ? tx.topologyVersion() : cctx.affinity().affinityTopologyVersion());
+ assert dhtVer != null;
GridCacheVersion enqueueVer = null;
@@ -389,28 +395,25 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
CacheObject old = this.val;
boolean hasVal = hasValueUnlocked();
- if (isNew() || !valid || expVer == null || expVer.equals(this.dhtVer)) {
+ if (this.dhtVer == null || this.dhtVer.compareTo(dhtVer) < 0) {
primaryNode(primaryNodeId, topVer);
- // Change entry only if dht version has changed.
- if (!dhtVer.equals(dhtVersion())) {
- update(val, expireTime, ttl, ver);
+ update(val, expireTime, ttl, ver);
- if (cctx.deferredDelete() && !isInternal()) {
- boolean deleted = val == null;
+ if (cctx.deferredDelete() && !isInternal()) {
+ boolean deleted = val == null;
- if (deleted != deletedUnlocked()) {
- deletedUnlocked(deleted);
+ if (deleted != deletedUnlocked()) {
+ deletedUnlocked(deleted);
- if (deleted)
- enqueueVer = ver;
- }
+ if (deleted)
+ enqueueVer = ver;
}
+ }
- recordDhtVersion(dhtVer);
+ this.dhtVer = dhtVer;
- ret = true;
- }
+ ret = true;
}
if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ))
@@ -647,6 +650,32 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
}
/**
+ * @throws GridCacheEntryRemovedException If entry was removed.
+ */
+ public synchronized void reserveEviction() throws GridCacheEntryRemovedException {
+ checkObsolete();
+
+ evictReservations++;
+ }
+
+ /**
+ *
+ */
+ public synchronized void releaseEviction() {
+ assert evictReservations > 0 : this;
+ assert !obsolete() : this;
+
+ evictReservations--;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected boolean evictionDisabled() {
+ assert Thread.holdsLock(this);
+
+ return evictReservations > 0;
+ }
+
+ /**
* @param nodeId Primary node ID.
* @param topVer Topology version.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index eca2f71..ae1d43c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@ -24,7 +24,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
@@ -38,19 +37,17 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFuture;
import org.apache.ignite.internal.processors.cache.GridCacheMessage;
import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridFutureRemapTimeoutObject;
+import org.apache.ignite.internal.processors.cache.distributed.dht.CacheDistributedGetFutureAdapter;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.GridLeanMap;
-import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -59,6 +56,7 @@ import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.CIX1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -66,83 +64,31 @@ import org.apache.ignite.lang.IgniteClosure;
import org.apache.ignite.lang.IgniteUuid;
import org.jetbrains.annotations.Nullable;
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_NEAR_GET_MAX_REMAPS;
-import static org.apache.ignite.IgniteSystemProperties.getInteger;
import static org.apache.ignite.transactions.TransactionIsolation.READ_COMMITTED;
/**
*
*/
-public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Map<K, V>>
- implements GridCacheFuture<Map<K, V>> {
+public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdapter<K, V> {
/** */
private static final long serialVersionUID = 0L;
- /** Default max remap count value. */
- public static final int DFLT_MAX_REMAP_CNT = 3;
-
/** Logger reference. */
private static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
/** Logger. */
private static IgniteLogger log;
- /** Maximum number of attempts to remap key to the same primary node. */
- private static final int MAX_REMAP_CNT = getInteger(IGNITE_NEAR_GET_MAX_REMAPS, DFLT_MAX_REMAP_CNT);
-
- /** Context. */
- private final GridCacheContext<K, V> cctx;
-
- /** Keys. */
- private Collection<KeyCacheObject> keys;
-
- /** Reload flag. */
- private boolean reload;
-
- /** Read through flag. */
- private boolean readThrough;
-
- /** Force primary flag. */
- private boolean forcePrimary;
-
- /** Future ID. */
- private IgniteUuid futId;
-
- /** Version. */
- private GridCacheVersion ver;
-
/** Transaction. */
private IgniteTxLocalEx tx;
- /** Trackable flag. */
- private boolean trackable;
-
- /** Remap count. */
- private AtomicInteger remapCnt = new AtomicInteger();
-
- /** Subject ID. */
- private UUID subjId;
-
- /** Task name. */
- private String taskName;
-
- /** Whether to deserialize portable objects. */
- private boolean deserializePortable;
-
- /** Skip values flag. */
- private boolean skipVals;
-
- /** Expiry policy. */
- private IgniteCacheExpiryPolicy expiryPlc;
-
- /** Flag indicating that get should be done on a locked topology version. */
- private final boolean canRemap;
+ /** */
+ private GridCacheVersion ver;
/**
* @param cctx Context.
* @param keys Keys.
* @param readThrough Read through flag.
- * @param reload Reload flag.
* @param forcePrimary If {@code true} get will be performed on primary node even if
* called on backup node.
* @param tx Transaction.
@@ -151,12 +97,14 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
* @param deserializePortable Deserialize portable flag.
* @param expiryPlc Expiry policy.
* @param skipVals Skip values flag.
+ * @param canRemap Flag indicating whether future can be remapped on a newer topology version.
+ * @param needVer If {@code true} returns values as tuples containing value and version.
+ * @param keepCacheObjects Keep cache objects flag.
*/
public GridNearGetFuture(
GridCacheContext<K, V> cctx,
Collection<KeyCacheObject> keys,
boolean readThrough,
- boolean reload,
boolean forcePrimary,
@Nullable IgniteTxLocalEx tx,
@Nullable UUID subjId,
@@ -164,24 +112,26 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
boolean deserializePortable,
@Nullable IgniteCacheExpiryPolicy expiryPlc,
boolean skipVals,
- boolean canRemap
+ boolean canRemap,
+ boolean needVer,
+ boolean keepCacheObjects
) {
- super(cctx.kernalContext(), CU.<K, V>mapsReducer(keys.size()));
+ super(cctx,
+ keys,
+ readThrough,
+ forcePrimary,
+ subjId,
+ taskName,
+ deserializePortable,
+ expiryPlc,
+ skipVals,
+ canRemap,
+ needVer,
+ keepCacheObjects);
assert !F.isEmpty(keys);
- this.cctx = cctx;
- this.keys = keys;
- this.readThrough = readThrough;
- this.reload = reload;
- this.forcePrimary = forcePrimary;
this.tx = tx;
- this.subjId = subjId;
- this.taskName = taskName;
- this.deserializePortable = deserializePortable;
- this.expiryPlc = expiryPlc;
- this.skipVals = skipVals;
- this.canRemap = canRemap;
futId = IgniteUuid.randomUuid();
@@ -318,16 +268,17 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings = U.newHashMap(affNodes.size());
- Map<KeyCacheObject, GridCacheVersion> savedVers = null;
+ Map<KeyCacheObject, GridNearCacheEntry> savedEntries = null;
// Assign keys to primary nodes.
for (KeyCacheObject key : keys)
- savedVers = map(key, mappings, topVer, mapped, savedVers);
+ savedEntries = map(key, mappings, topVer, mapped, savedEntries);
if (isDone())
return;
- final Map<KeyCacheObject, GridCacheVersion> saved = savedVers;
+ final Map<KeyCacheObject, GridNearCacheEntry> saved = savedEntries != null ? savedEntries :
+ Collections.<KeyCacheObject, GridNearCacheEntry>emptyMap();
final int keysSize = keys.size();
@@ -346,7 +297,6 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
-1,
mappedKeys,
readThrough,
- reload,
topVer,
subjId,
taskName == null ? 0 : taskName.hashCode(),
@@ -405,7 +355,6 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
ver,
mappedKeys,
readThrough,
- reload,
topVer,
subjId,
taskName == null ? 0 : taskName.hashCode(),
@@ -434,43 +383,64 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
* @param key Key to map.
* @param topVer Topology version
* @param mapped Previously mapped.
- * @param savedVers Saved versions.
+ * @param saved Reserved near cache entries.
* @return Map.
*/
- private Map<KeyCacheObject, GridCacheVersion> map(
+ private Map<KeyCacheObject, GridNearCacheEntry> map(
KeyCacheObject key,
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings,
AffinityTopologyVersion topVer,
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped,
- Map<KeyCacheObject, GridCacheVersion> savedVers
+ Map<KeyCacheObject, GridNearCacheEntry> saved
) {
final GridNearCacheAdapter near = cache();
// Allow to get cached value from the local node.
boolean allowLocRead = !forcePrimary || cctx.affinity().primary(cctx.localNode(), key, topVer);
- GridCacheEntryEx entry = allowLocRead ? near.peekEx(key) : null;
-
while (true) {
+ GridNearCacheEntry entry = allowLocRead ? (GridNearCacheEntry)near.peekEx(key) : null;
+
try {
CacheObject v = null;
+ GridCacheVersion ver = null;
boolean isNear = entry != null;
// First we peek into near cache.
- if (isNear)
- v = entry.innerGet(tx,
- /*swap*/false,
- /*read-through*/false,
- /*fail-fast*/true,
- /*unmarshal*/true,
- /*metrics*/true,
- /*events*/!skipVals,
- /*temporary*/false,
- subjId,
- null,
- taskName,
- expiryPlc);
+ if (isNear) {
+ if (needVer) {
+ T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+ null,
+ /*swap*/true,
+ /*unmarshal*/true,
+ /**update-metrics*/true,
+ /*event*/!skipVals,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+
+ if (res != null) {
+ v = res.get1();
+ ver = res.get2();
+ }
+ }
+ else {
+ v = entry.innerGet(tx,
+ /*swap*/false,
+ /*read-through*/false,
+ /*fail-fast*/true,
+ /*unmarshal*/true,
+ /*metrics*/true,
+ /*events*/!skipVals,
+ /*temporary*/false,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+ }
+ }
ClusterNode affNode = null;
@@ -486,18 +456,37 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
if (dhtEntry != null) {
boolean isNew = dhtEntry.isNewLocked() || !dhtEntry.valid(topVer);
- v = dhtEntry.innerGet(tx,
- /*swap*/true,
- /*read-through*/false,
- /*fail-fast*/true,
- /*unmarshal*/true,
- /*update-metrics*/false,
- /*events*/!isNear && !skipVals,
- /*temporary*/false,
- subjId,
- null,
- taskName,
- expiryPlc);
+ if (needVer) {
+ T2<CacheObject, GridCacheVersion> res = dhtEntry.innerGetVersioned(
+ null,
+ /*swap*/true,
+ /*unmarshal*/true,
+ /**update-metrics*/false,
+ /*event*/!isNear && !skipVals,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+
+ if (res != null) {
+ v = res.get1();
+ ver = res.get2();
+ }
+ }
+ else {
+ v = dhtEntry.innerGet(tx,
+ /*swap*/true,
+ /*read-through*/false,
+ /*fail-fast*/true,
+ /*unmarshal*/true,
+ /*update-metrics*/false,
+ /*events*/!isNear && !skipVals,
+ /*temporary*/false,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+ }
// Entry was not in memory or in swap, so we remove it from cache.
if (v == null && isNew && dhtEntry.markObsoleteIfEmpty(ver))
@@ -515,7 +504,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache " +
"(all partition nodes left the grid)."));
- return savedVers;
+ return saved;
}
if (!affNode.isLocal() && cctx.cache().configuration().isStatisticsEnabled() && !skipVals)
@@ -534,14 +523,29 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
}
}
- if (v != null && !reload) {
- K key0 = key.value(cctx.cacheObjectContext(), true);
- V val0 = v.value(cctx.cacheObjectContext(), true);
+ if (v != null) {
+ if (needVer) {
+ V val0 = (V)new T2<>(skipVals ? true : v, ver);
+
+ add(new GridFinishedFuture<>(Collections.singletonMap((K)key, val0)));
+ }
+ else {
+ if (keepCacheObjects) {
+ K key0 = (K)key;
+ V val0 = (V)(skipVals ? true : v);
+
+ add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
+ }
+ else {
+ K key0 = key.value(cctx.cacheObjectContext(), true);
+ V val0 = v.value(cctx.cacheObjectContext(), true);
- val0 = (V)cctx.unwrapPortableIfNeeded(val0, !deserializePortable);
- key0 = (K)cctx.unwrapPortableIfNeeded(key0, !deserializePortable);
+ val0 = (V)cctx.unwrapPortableIfNeeded(val0, !deserializePortable);
+ key0 = (K)cctx.unwrapPortableIfNeeded(key0, !deserializePortable);
- add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
+ add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
+ }
+ }
}
else {
if (affNode == null) {
@@ -551,19 +555,10 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache " +
"(all partition nodes left the grid)."));
- return savedVers;
+ return saved;
}
}
- GridNearCacheEntry nearEntry = allowLocRead ? near.peekExx(key) : null;
-
- entry = nearEntry;
-
- if (savedVers == null)
- savedVers = U.newHashMap(3);
-
- savedVers.put(key, nearEntry == null ? null : nearEntry.dhtVersion());
-
LinkedHashMap<KeyCacheObject, Boolean> keys = mapped.get(affNode);
if (keys != null && keys.containsKey(key)) {
@@ -572,10 +567,23 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
MAX_REMAP_CNT + " attempts (key got remapped to the same node) " +
"[key=" + key + ", node=" + U.toShortString(affNode) + ", mappings=" + mapped + ']'));
- return savedVers;
+ return saved;
}
}
+ if (!cctx.affinity().localNode(key, topVer)) {
+ GridNearCacheEntry nearEntry = entry != null ? entry : near.entryExx(key, topVer);
+
+ nearEntry.reserveEviction();
+
+ entry = null;
+
+ if (saved == null)
+ saved = U.newHashMap(3);
+
+ saved.put(key, nearEntry);
+ }
+
// Don't add reader if transaction acquires lock anyway to avoid deadlock.
boolean addRdr = tx == null || tx.optimistic();
@@ -598,21 +606,15 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
break;
}
catch (GridCacheEntryRemovedException ignored) {
- entry = allowLocRead ? near.peekEx(key) : null;
- }
- catch (GridCacheFilterFailedException e) {
- if (log.isDebugEnabled())
- log.debug("Filter validation failed for entry: " + e);
-
- break;
+ // Retry.
}
finally {
- if (entry != null && !reload && tx == null)
+ if (entry != null && tx == null)
cctx.evicts().touch(entry, topVer);
}
}
- return savedVers;
+ return saved;
}
/**
@@ -655,7 +657,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
* @param nodeId Node id.
* @param keys Keys.
* @param infos Entry infos.
- * @param savedVers Saved versions.
+ * @param savedEntries Saved entries.
* @param topVer Topology version
* @return Result map.
*/
@@ -663,7 +665,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
UUID nodeId,
Collection<KeyCacheObject> keys,
Collection<GridCacheEntryInfo> infos,
- Map<KeyCacheObject, GridCacheVersion> savedVers,
+ Map<KeyCacheObject, GridNearCacheEntry> savedEntries,
AffinityTopologyVersion topVer
) {
boolean empty = F.isEmpty(keys);
@@ -681,9 +683,10 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
// Entries available locally in DHT should not be loaded into near cache for reading.
if (!cctx.affinity().localNode(info.key(), cctx.affinity().affinityTopologyVersion())) {
- GridNearCacheEntry entry = cache().entryExx(info.key(), topVer);
+ GridNearCacheEntry entry = savedEntries.get(info.key());
- GridCacheVersion saved = savedVers.get(info.key());
+ if (entry == null)
+ entry = cache().entryExx(info.key(), topVer);
// Load entry into cache.
entry.loadedValue(tx,
@@ -691,14 +694,11 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
info.value(),
atomic ? info.version() : ver,
info.version(),
- saved,
info.ttl(),
info.expireTime(),
true,
topVer,
subjId);
-
- cctx.evicts().touch(entry, topVer);
}
CacheObject val = info.value();
@@ -706,7 +706,16 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
assert skipVals == (info.value() == null);
- cctx.addResult(map, key, val, skipVals, false, deserializePortable, false);
+ if (needVer)
+ versionedResult(map, key, val, info.version());
+ else
+ cctx.addResult(map,
+ key,
+ val,
+ skipVals,
+ keepCacheObjects,
+ deserializePortable,
+ false);
}
catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
@@ -724,6 +733,26 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
return map;
}
+ /**
+ * @param keys Keys.
+ * @param saved Saved entries.
+ * @param topVer Topology version.
+ */
+ private void releaseEvictions(Collection<KeyCacheObject> keys,
+ Map<KeyCacheObject, GridNearCacheEntry> saved,
+ AffinityTopologyVersion topVer) {
+ for (KeyCacheObject key : keys) {
+ GridNearCacheEntry entry = saved.get(key);
+
+ if (entry != null) {
+ entry.releaseEviction();
+
+ if (tx == null)
+ cctx.evicts().touch(entry, topVer);
+ }
+ }
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
Collection<String> futs = F.viewReadOnly(futures(), new C1<IgniteInternalFuture<?>, String>() {
@@ -763,7 +792,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
private LinkedHashMap<KeyCacheObject, Boolean> keys;
/** Saved entry versions. */
- private Map<KeyCacheObject, GridCacheVersion> savedVers;
+ private Map<KeyCacheObject, GridNearCacheEntry> savedEntries;
/** Topology version on which this future was mapped. */
private AffinityTopologyVersion topVer;
@@ -774,18 +803,18 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
/**
* @param node Node.
* @param keys Keys.
- * @param savedVers Saved entry versions.
+ * @param savedEntries Saved entries.
* @param topVer Topology version.
*/
MiniFuture(
ClusterNode node,
LinkedHashMap<KeyCacheObject, Boolean> keys,
- Map<KeyCacheObject, GridCacheVersion> savedVers,
+ Map<KeyCacheObject, GridNearCacheEntry> savedEntries,
AffinityTopologyVersion topVer
) {
this.node = node;
this.keys = keys;
- this.savedVers = savedVers;
+ this.savedEntries = savedEntries;
this.topVer = topVer;
}
@@ -821,6 +850,17 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
onDone(e);
}
+ /** {@inheritDoc} */
+ @Override public boolean onDone(@Nullable Map<K, V> res, @Nullable Throwable err) {
+ if (super.onDone(res, err)) {
+ releaseEvictions(keys.keySet(), savedEntries, topVer);
+
+ return true;
+ }
+ else
+ return false;
+ }
+
/**
* @param e Topology exception.
*/
@@ -915,7 +955,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
}), F.t(node, keys), topVer);
// It is critical to call onDone after adding futures to compound list.
- onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedVers, topVer));
+ onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedEntries, topVer));
return;
}
@@ -935,12 +975,12 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
}), F.t(node, keys), new AffinityTopologyVersion(readyTopVer));
// It is critical to call onDone after adding futures to compound list.
- onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedVers, topVer));
+ onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedEntries, topVer));
}
});
}
else
- onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedVers, topVer));
+ onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedEntries, topVer));
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
index ff6375a..8482217 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
@@ -109,7 +109,6 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
* @param ver Version.
* @param keys Keys.
* @param readThrough Read through flag.
- * @param reload Reload flag.
* @param skipVals Skip values flag. When false, only boolean values will be returned indicating whether
* cache entry has a value.
* @param topVer Topology version.
@@ -125,7 +124,6 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
GridCacheVersion ver,
LinkedHashMap<KeyCacheObject, Boolean> keys,
boolean readThrough,
- boolean reload,
@NotNull AffinityTopologyVersion topVer,
UUID subjId,
int taskNameHash,
@@ -145,7 +143,6 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
this.keys = keys.keySet();
this.flags = keys.values();
this.readThrough = readThrough;
- this.reload = reload;
this.topVer = topVer;
this.subjId = subjId;
this.taskNameHash = taskNameHash;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
new file mode 100644
index 0000000..47c1d21
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -0,0 +1,930 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.near;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.cluster.ClusterTopologyException;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
+import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
+import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxMapping;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
+import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
+import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
+import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.future.GridCompoundFuture;
+import org.apache.ignite.internal.util.future.GridFinishedFuture;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.C1;
+import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiTuple;
+import org.apache.ignite.lang.IgniteClosure;
+import org.apache.ignite.lang.IgniteProductVersion;
+import org.apache.ignite.lang.IgniteReducer;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
+import static org.apache.ignite.transactions.TransactionState.PREPARED;
+import static org.apache.ignite.transactions.TransactionState.PREPARING;
+
+/**
+ *
+ */
+public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter
+ implements GridCacheMvccFuture<IgniteInternalTx> {
+ /** */
+ public static final IgniteProductVersion SER_TX_SINCE = IgniteProductVersion.fromString("1.5.0");
+
+ /** */
+ @GridToStringExclude
+ private KeyLockFuture keyLockFut = new KeyLockFuture();
+
+ /** */
+ @GridToStringExclude
+ private ClientRemapFuture remapFut;
+
+ /**
+ * @param cctx Context.
+ * @param tx Transaction.
+ */
+ public GridNearOptimisticSerializableTxPrepareFuture(GridCacheSharedContext cctx, GridNearTxLocal tx) {
+ super(cctx, tx);
+
+ assert tx.optimistic() && tx.serializable() : tx;
+
+ // Should wait for all mini futures completion before finishing tx.
+ ignoreChildFailures(IgniteCheckedException.class);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
+ if (log.isDebugEnabled())
+ log.debug("Transaction future received owner changed callback: " + entry);
+
+ if ((entry.context().isNear() || entry.context().isLocal()) && owner != null) {
+ IgniteTxEntry txEntry = tx.entry(entry.txKey());
+
+ if (txEntry != null) {
+ if (entry.context().isLocal()) {
+ GridCacheVersion serReadVer = txEntry.serializableReadVersion();
+
+ if (serReadVer != null) {
+ GridCacheContext ctx = entry.context();
+
+ while (true) {
+ try {
+ if (!entry.checkSerializableReadVersion(serReadVer)) {
+ Object key = entry.key().value(ctx.cacheObjectContext(), false);
+
+ IgniteTxOptimisticCheckedException err0 =
+ new IgniteTxOptimisticCheckedException("Failed to prepare transaction, " +
+ "read/write conflict [key=" + key + ", cache=" + ctx.name() + ']');
+
+ err.compareAndSet(null, err0);
+ }
+
+ break;
+ }
+ catch (GridCacheEntryRemovedException e) {
+ entry = ctx.cache().entryEx(entry.key());
+
+ txEntry.cached(entry);
+ }
+ }
+
+ }
+ }
+
+ keyLockFut.onKeyLocked(entry.txKey());
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<? extends ClusterNode> nodes() {
+ return F.viewReadOnly(futures(), new IgniteClosure<IgniteInternalFuture<?>, ClusterNode>() {
+ @Nullable @Override public ClusterNode apply(IgniteInternalFuture<?> f) {
+ if (isMini(f))
+ return ((MiniFuture)f).node();
+
+ return cctx.discovery().localNode();
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean onNodeLeft(UUID nodeId) {
+ boolean found = false;
+
+ for (IgniteInternalFuture<?> fut : futures()) {
+ if (isMini(fut)) {
+ MiniFuture f = (MiniFuture) fut;
+
+ if (f.node().id().equals(nodeId)) {
+ ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Remote node left grid: " +
+ nodeId);
+
+ e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
+
+ f.onNodeLeft(e);
+
+ found = true;
+ }
+ }
+ }
+
+ return found;
+ }
+
+ /**
+ * @param m Failed mapping.
+ * @param e Error.
+ */
+ private void onError(@Nullable GridDistributedTxMapping m, Throwable e) {
+ if (X.hasCause(e, ClusterTopologyCheckedException.class) || X.hasCause(e, ClusterTopologyException.class)) {
+ if (tx.onePhaseCommit()) {
+ tx.markForBackupCheck();
+
+ onComplete();
+
+ return;
+ }
+ }
+
+ if (e instanceof IgniteTxOptimisticCheckedException) {
+ if (m != null)
+ tx.removeMapping(m.node().id());
+ }
+
+ err.compareAndSet(null, e);
+
+ keyLockFut.onDone(e);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
+ if (!isDone()) {
+ for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
+ if (isMini(fut)) {
+ MiniFuture f = (MiniFuture)fut;
+
+ if (f.futureId().equals(res.miniId())) {
+ assert f.node().id().equals(nodeId);
+
+ f.onResult(res);
+ }
+ }
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean onDone(IgniteInternalTx t, Throwable err) {
+ if (isDone())
+ return false;
+
+ if (err != null) {
+ this.err.compareAndSet(null, err);
+
+ keyLockFut.onDone(err);
+ }
+
+ return onComplete();
+ }
+
+ /**
+ * @param f Future.
+ * @return {@code True} if mini-future.
+ */
+ private boolean isMini(IgniteInternalFuture<?> f) {
+ return f.getClass().equals(MiniFuture.class);
+ }
+
+ /**
+ * Completeness callback.
+ *
+ * @return {@code True} if future was finished by this call.
+ */
+ private boolean onComplete() {
+ Throwable err0 = err.get();
+
+ if (err0 == null || tx.needCheckBackup())
+ tx.state(PREPARED);
+
+ if (super.onDone(tx, err0)) {
+ if (err0 != null)
+ tx.setRollbackOnly();
+
+ // Don't forget to clean up.
+ cctx.mvcc().removeFuture(this);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Initializes future.
+ *
+ * @param remap Remap flag.
+ */
+ @Override protected void prepare0(boolean remap, boolean topLocked) {
+ try {
+ boolean txStateCheck = remap ? tx.state() == PREPARING : tx.state(PREPARING);
+
+ if (!txStateCheck) {
+ if (tx.setRollbackOnly()) {
+ if (tx.timedOut())
+ onError(null, new IgniteTxTimeoutCheckedException("Transaction timed out and " +
+ "was rolled back: " + this));
+ else
+ onError(null, new IgniteCheckedException("Invalid transaction state for prepare " +
+ "[state=" + tx.state() + ", tx=" + this + ']'));
+ }
+ else
+ onError(null, new IgniteTxRollbackCheckedException("Invalid transaction state for " +
+ "prepare [state=" + tx.state() + ", tx=" + this + ']'));
+
+ return;
+ }
+
+ prepare(tx.readEntries(), tx.writeEntries(), remap, topLocked);
+
+ markInitialized();
+ }
+ catch (IgniteCheckedException e) {
+ onDone(e);
+ }
+ }
+
+ /**
+ * @param reads Read entries.
+ * @param writes Write entries.
+ * @param remap Remap flag.
+ * @param topLocked Topology locked flag.
+ * @throws IgniteCheckedException If failed.
+ */
+ @SuppressWarnings("unchecked")
+ private void prepare(
+ Iterable<IgniteTxEntry> reads,
+ Iterable<IgniteTxEntry> writes,
+ boolean remap,
+ boolean topLocked
+ ) throws IgniteCheckedException {
+ AffinityTopologyVersion topVer = tx.topologyVersion();
+
+ assert topVer.topologyVersion() > 0;
+
+ txMapping = new GridDhtTxMapping();
+
+ if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
+ for (int cacheId : tx.activeCacheIds()) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (CU.affinityNodes(cacheCtx, topVer).isEmpty()) {
+ onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
+ "partition nodes left the grid): " + cacheCtx.name()));
+
+ return;
+ }
+ }
+ }
+
+ Map<IgniteBiTuple<ClusterNode, Boolean>, GridDistributedTxMapping> mappings = new HashMap<>();
+
+ for (IgniteTxEntry write : writes)
+ map(write, topVer, mappings, remap, topLocked);
+
+ for (IgniteTxEntry read : reads)
+ map(read, topVer, mappings, remap, topLocked);
+
+ keyLockFut.onAllKeysAdded();
+
+ if (!remap)
+ add(keyLockFut);
+
+ if (isDone()) {
+ if (log.isDebugEnabled())
+ log.debug("Abandoning (re)map because future is done: " + this);
+
+ return;
+ }
+
+ tx.addEntryMapping(mappings.values());
+
+ cctx.mvcc().recheckPendingLocks();
+
+ tx.transactionNodes(txMapping.transactionNodes());
+
+ checkOnePhase();
+
+ for (GridDistributedTxMapping m : mappings.values()) {
+ assert !m.empty();
+
+ MiniFuture fut = new MiniFuture(m);
+
+ add(fut);
+ }
+
+ Collection<IgniteInternalFuture<?>> futs = (Collection)futures();
+
+ Iterator<IgniteInternalFuture<?>> it = futs.iterator();
+
+ while (it.hasNext()) {
+ IgniteInternalFuture<?> fut0 = it.next();
+
+ if (skipFuture(remap, fut0))
+ continue;
+
+ MiniFuture fut = (MiniFuture)fut0;
+
+ IgniteCheckedException err = prepare(fut);
+
+ if (err != null) {
+ while (it.hasNext()) {
+ fut0 = it.next();
+
+ if (skipFuture(remap, fut0))
+ continue;
+
+ fut = (MiniFuture)fut0;
+
+ tx.removeMapping(fut.mapping().node().id());
+
+ fut.onResult(new IgniteCheckedException("Failed to prepare transaction.", err));
+ }
+
+ break;
+ }
+ }
+
+ markInitialized();
+ }
+
+ /**
+ * @param remap Remap flag.
+ * @param fut Future.
+ * @return {@code True} if skip future during remap.
+ */
+ private boolean skipFuture(boolean remap, IgniteInternalFuture<?> fut) {
+ return !(isMini(fut)) || (remap && ((MiniFuture)fut).rcvRes.get());
+ }
+
+ /**
+ * @param fut Mini future.
+ * @return Prepare error if any.
+ */
+ @Nullable private IgniteCheckedException prepare(final MiniFuture fut) {
+ GridDistributedTxMapping m = fut.mapping();
+
+ final ClusterNode n = m.node();
+
+ GridNearTxPrepareRequest req = new GridNearTxPrepareRequest(
+ futId,
+ tx.topologyVersion(),
+ tx,
+ m.reads(),
+ m.writes(),
+ m.near(),
+ txMapping.transactionNodes(),
+ m.last(),
+ m.lastBackups(),
+ tx.onePhaseCommit(),
+ tx.needReturnValue() && tx.implicit(),
+ tx.implicitSingle(),
+ m.explicitLock(),
+ tx.subjectId(),
+ tx.taskNameHash(),
+ m.clientFirst(),
+ tx.activeCachesDeploymentEnabled());
+
+ for (IgniteTxEntry txEntry : m.writes()) {
+ if (txEntry.op() == TRANSFORM)
+ req.addDhtVersion(txEntry.txKey(), null);
+ }
+
+ // Must lock near entries separately.
+ if (m.near()) {
+ try {
+ tx.optimisticLockEntries(F.concat(false, m.writes(), m.reads()));
+
+ tx.userPrepare();
+ }
+ catch (IgniteCheckedException e) {
+ fut.onResult(e);
+
+ return e;
+ }
+ }
+
+ req.miniId(fut.futureId());
+
+ // If this is the primary node for the keys.
+ if (n.isLocal()) {
+ IgniteInternalFuture<GridNearTxPrepareResponse> prepFut = cctx.tm().txHandler().prepareTx(n.id(), tx, req);
+
+ prepFut.listen(new CI1<IgniteInternalFuture<GridNearTxPrepareResponse>>() {
+ @Override public void apply(IgniteInternalFuture<GridNearTxPrepareResponse> prepFut) {
+ try {
+ fut.onResult(prepFut.get());
+ }
+ catch (IgniteCheckedException e) {
+ fut.onResult(e);
+ }
+ }
+ });
+ }
+ else {
+ try {
+ cctx.io().send(n, req, tx.ioPolicy());
+ }
+ catch (ClusterTopologyCheckedException e) {
+ e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
+
+ fut.onNodeLeft(e);
+
+ return e;
+ }
+ catch (IgniteCheckedException e) {
+ fut.onResult(e);
+
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param entry Transaction entry.
+ * @param topVer Topology version.
+ * @param curMapping Current mapping.
+ * @param remap Remap flag.
+ * @param topLocked Topology locked flag.
+ */
+ private void map(
+ IgniteTxEntry entry,
+ AffinityTopologyVersion topVer,
+ Map<IgniteBiTuple<ClusterNode, Boolean>, GridDistributedTxMapping> curMapping,
+ boolean remap,
+ boolean topLocked
+ ) {
+ GridCacheContext cacheCtx = entry.context();
+
+ List<ClusterNode> nodes = cacheCtx.affinity().nodes(entry.key(), topVer);
+
+ txMapping.addMapping(nodes);
+
+ ClusterNode primary = F.first(nodes);
+
+ assert primary != null;
+
+ if (log.isDebugEnabled()) {
+ log.debug("Mapped key to primary node [key=" + entry.key() +
+ ", part=" + cacheCtx.affinity().partition(entry.key()) +
+ ", primary=" + U.toShortString(primary) + ", topVer=" + topVer + ']');
+ }
+
+ if (primary.version().compareTo(SER_TX_SINCE) < 0) {
+ onDone(new IgniteCheckedException("Optimistic serializable transactions can be used only with node " +
+ "version starting from " + SER_TX_SINCE));
+
+ return;
+ }
+
+ // Must re-initialize cached entry while holding topology lock.
+ if (cacheCtx.isNear())
+ entry.cached(cacheCtx.nearTx().entryExx(entry.key(), topVer));
+ else if (!cacheCtx.isLocal())
+ entry.cached(cacheCtx.colocated().entryExx(entry.key(), topVer, true));
+ else
+ entry.cached(cacheCtx.local().entryEx(entry.key(), topVer));
+
+ if (!remap && (cacheCtx.isNear() || cacheCtx.isLocal())) {
+ if (entry.explicitVersion() == null)
+ keyLockFut.addLockKey(entry.txKey());
+ }
+
+ IgniteBiTuple<ClusterNode, Boolean> key = F.t(primary, cacheCtx.isNear());
+
+ GridDistributedTxMapping cur = curMapping.get(key);
+
+ if (cur == null) {
+ cur = new GridDistributedTxMapping(primary);
+
+ curMapping.put(key, cur);
+
+ if (primary.isLocal()) {
+ if (entry.context().isNear())
+ tx.nearLocallyMapped(true);
+ else if (entry.context().isColocated())
+ tx.colocatedLocallyMapped(true);
+ }
+
+ // Initialize near flag right away.
+ cur.near(cacheCtx.isNear());
+
+ cur.clientFirst(!topLocked && cctx.kernalContext().clientNode());
+
+ cur.last(true);
+ }
+
+ cur.add(entry);
+
+ if (entry.explicitVersion() != null) {
+ tx.markExplicit(primary.id());
+
+ cur.markExplicitLock();
+ }
+
+ entry.nodeId(primary.id());
+
+ if (cacheCtx.isNear()) {
+ while (true) {
+ try {
+ GridNearCacheEntry cached = (GridNearCacheEntry)entry.cached();
+
+ cached.dhtNodeId(tx.xidVersion(), primary.id());
+
+ break;
+ }
+ catch (GridCacheEntryRemovedException ignore) {
+ entry.cached(cacheCtx.near().entryEx(entry.key()));
+ }
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ Collection<String> futs = F.viewReadOnly(futures(),
+ new C1<IgniteInternalFuture<?>, String>() {
+ @Override public String apply(IgniteInternalFuture<?> f) {
+ return "[node=" + ((MiniFuture)f).node().id() +
+ ", loc=" + ((MiniFuture)f).node().isLocal() +
+ ", done=" + f.isDone() + "]";
+ }
+ },
+ new P1<IgniteInternalFuture<?>>() {
+ @Override public boolean apply(IgniteInternalFuture<?> f) {
+ return isMini(f);
+ }
+ });
+
+ return S.toString(GridNearOptimisticSerializableTxPrepareFuture.class, this,
+ "innerFuts", futs,
+ "keyLockFut", keyLockFut,
+ "tx", tx,
+ "super", super.toString());
+ }
+
+ /**
+ *
+ */
+ private class ClientRemapFuture extends GridCompoundFuture<GridNearTxPrepareResponse, Boolean> {
+ /** */
+ private boolean remap = true;
+
+ /**
+ *
+ */
+ public ClientRemapFuture() {
+ super();
+
+ reducer(new IgniteReducer<GridNearTxPrepareResponse, Boolean>() {
+ @Override public boolean collect(GridNearTxPrepareResponse res) {
+ assert res != null;
+
+ if (res.clientRemapVersion() == null)
+ remap = false;
+
+ return true;
+ }
+
+ @Override public Boolean reduce() {
+ return remap;
+ }
+ });
+ }
+ }
+
+ /**
+ *
+ */
+ private class MiniFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ private final IgniteUuid futId = IgniteUuid.randomUuid();
+
+ /** Keys. */
+ @GridToStringInclude
+ private GridDistributedTxMapping m;
+
+ /** Flag to signal some result being processed. */
+ private AtomicBoolean rcvRes = new AtomicBoolean(false);
+
+ /**
+ * @param m Mapping.
+ */
+ MiniFuture(GridDistributedTxMapping m) {
+ this.m = m;
+ }
+
+ /**
+ * @return Future ID.
+ */
+ IgniteUuid futureId() {
+ return futId;
+ }
+
+ /**
+ * @return Node ID.
+ */
+ public ClusterNode node() {
+ return m.node();
+ }
+
+ /**
+ * @return Keys.
+ */
+ public GridDistributedTxMapping mapping() {
+ return m;
+ }
+
+ /**
+ * @param e Error.
+ */
+ void onResult(Throwable e) {
+ if (rcvRes.compareAndSet(false, true)) {
+ onError(m, e);
+
+ if (log.isDebugEnabled())
+ log.debug("Failed to get future result [fut=" + this + ", err=" + e + ']');
+
+ // Fail.
+ onDone(e);
+ }
+ else
+ U.warn(log, "Received error after another result has been processed [fut=" +
+ GridNearOptimisticSerializableTxPrepareFuture.this + ", mini=" + this + ']', e);
+ }
+
+ /**
+ * @param e Node failure.
+ */
+ void onNodeLeft(ClusterTopologyCheckedException e) {
+ if (isDone())
+ return;
+
+ if (rcvRes.compareAndSet(false, true)) {
+ if (log.isDebugEnabled())
+ log.debug("Remote node left grid while sending or waiting for reply (will not retry): " + this);
+
+ onError(null, e);
+
+ onDone(e);
+ }
+ }
+
+ /**
+ * @param res Result callback.
+ */
+ @SuppressWarnings("unchecked")
+ void onResult(final GridNearTxPrepareResponse res) {
+ if (isDone())
+ return;
+
+ if (rcvRes.compareAndSet(false, true)) {
+ if (res.error() != null) {
+ // Fail the whole compound future.
+ onError(m, res.error());
+
+ onDone(res.error());
+ }
+ else {
+ if (res.clientRemapVersion() != null) {
+ assert cctx.kernalContext().clientNode();
+ assert m.clientFirst();
+
+ tx.removeMapping(m.node().id());
+
+ ClientRemapFuture remapFut0 = null;
+
+ synchronized (GridNearOptimisticSerializableTxPrepareFuture.this) {
+ if (remapFut == null) {
+ remapFut = new ClientRemapFuture();
+
+ remapFut0 = remapFut;
+ }
+ }
+
+ if (remapFut0 != null) {
+ Collection<IgniteInternalFuture<?>> futs = (Collection)futures();
+
+ for (IgniteInternalFuture<?> fut : futs) {
+ if (isMini(fut) && fut != this)
+ remapFut0.add((MiniFuture)fut);
+ }
+
+ remapFut0.markInitialized();
+
+ remapFut0.listen(new CI1<IgniteInternalFuture<Boolean>>() {
+ @Override public void apply(IgniteInternalFuture<Boolean> remapFut0) {
+ try {
+ IgniteInternalFuture<?> affFut =
+ cctx.exchange().affinityReadyFuture(res.clientRemapVersion());
+
+ if (affFut == null)
+ affFut = new GridFinishedFuture<Object>();
+
+ if (remapFut.get()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Will remap client tx [" +
+ "fut=" + GridNearOptimisticSerializableTxPrepareFuture.this +
+ ", topVer=" + res.topologyVersion() + ']');
+ }
+
+ synchronized (GridNearOptimisticSerializableTxPrepareFuture.this) {
+ assert remapFut0 == remapFut;
+
+ remapFut = null;
+ }
+
+ affFut.listen(new CI1<IgniteInternalFuture<?>>() {
+ @Override public void apply(IgniteInternalFuture<?> affFut) {
+ try {
+ affFut.get();
+
+ remap(res);
+ }
+ catch (IgniteCheckedException e) {
+ onDone(e);
+ }
+ }
+ });
+ }
+ else {
+ ClusterTopologyCheckedException err = new ClusterTopologyCheckedException(
+ "Cluster topology changed while client transaction is preparing.");
+
+ err.retryReadyFuture(affFut);
+
+ onDone(err);
+ }
+ }
+ catch (IgniteCheckedException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Prepare failed, will not remap tx: " +
+ GridNearOptimisticSerializableTxPrepareFuture.this);
+ }
+
+ onDone(e);
+ }
+ }
+ });
+ }
+ else
+ onDone(res);
+ }
+ else {
+ onPrepareResponse(m, res);
+
+ // Finish this mini future (need result only on client node).
+ onDone(cctx.kernalContext().clientNode() ? res : null);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param res Response.
+ */
+ private void remap(final GridNearTxPrepareResponse res) {
+ prepareOnTopology(true, new Runnable() {
+ @Override public void run() {
+ onDone(res);
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(MiniFuture.class, this, "done", isDone(), "cancelled", isCancelled(), "err", error());
+ }
+ }
+
+ /**
+ * Keys lock future.
+ */
+ private class KeyLockFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
+ /** */
+ @GridToStringInclude
+ private Collection<IgniteTxKey> lockKeys = new GridConcurrentHashSet<>();
+
+ /** */
+ private volatile boolean allKeysAdded;
+
+ /**
+ * @param key Key to track for locking.
+ */
+ private void addLockKey(IgniteTxKey key) {
+ assert !allKeysAdded;
+
+ lockKeys.add(key);
+ }
+
+ /**
+ * @param key Locked keys.
+ */
+ private void onKeyLocked(IgniteTxKey key) {
+ lockKeys.remove(key);
+
+ checkLocks();
+ }
+
+ /**
+ * Moves future to the ready state.
+ */
+ private void onAllKeysAdded() {
+ allKeysAdded = true;
+
+ checkLocks();
+ }
+
+ /**
+ * @return {@code True} if all locks are owned.
+ */
+ private boolean checkLocks() {
+ boolean locked = lockKeys.isEmpty();
+
+ if (locked && allKeysAdded) {
+ if (log.isDebugEnabled())
+ log.debug("All locks are acquired for near prepare future: " + this);
+
+ onDone((GridNearTxPrepareResponse)null);
+ }
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Still waiting for locks [fut=" + this + ", keys=" + lockKeys + ']');
+ }
+
+ return locked;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(KeyLockFuture.class, this, super.toString());
+ }
+ }
+}
[16/23] ignite git commit: Ignite JMS 1.1 Streamer: Upgrade test
ActiveMQ to 5.12.0.
Posted by yz...@apache.org.
Ignite JMS 1.1 Streamer: Upgrade test ActiveMQ to 5.12.0.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e769c3a8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e769c3a8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e769c3a8
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: e769c3a807b3f367fc1ef48d62ca3e055123d8ee
Parents: 9d7543a
Author: Raul Kripalani <ra...@apache.org>
Authored: Wed Oct 28 12:05:41 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Wed Oct 28 12:05:52 2015 +0000
----------------------------------------------------------------------
modules/jms11/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/e769c3a8/modules/jms11/pom.xml
----------------------------------------------------------------------
diff --git a/modules/jms11/pom.xml b/modules/jms11/pom.xml
index 47a1495..72a643b 100644
--- a/modules/jms11/pom.xml
+++ b/modules/jms11/pom.xml
@@ -35,7 +35,7 @@
<url>http://ignite.apache.org</url>
<properties>
- <activemq.version>5.11.1</activemq.version>
+ <activemq.version>5.12.0</activemq.version>
</properties>
<dependencies>
[12/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index 6db00ab..af43113 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -18,7 +18,6 @@
package org.apache.ignite.internal.processors.cache.distributed.near;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -36,17 +35,14 @@ import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxMapping;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
-import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.GridConcurrentHashSet;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.lang.GridPlainRunnable;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.CI1;
@@ -57,7 +53,6 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteClosure;
import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.transactions.TransactionOptimisticException;
import org.apache.ignite.transactions.TransactionTimeoutException;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentLinkedDeque8;
@@ -69,7 +64,7 @@ import static org.apache.ignite.transactions.TransactionState.PREPARING;
/**
*
*/
-public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAdapter
+public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter
implements GridCacheMvccFuture<IgniteInternalTx> {
/** */
@GridToStringInclude
@@ -82,7 +77,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
public GridNearOptimisticTxPrepareFuture(GridCacheSharedContext cctx, GridNearTxLocal tx) {
super(cctx, tx);
- assert tx.optimistic() : tx;
+ assert tx.optimistic() && !tx.serializable() : tx;
}
/** {@inheritDoc} */
@@ -139,11 +134,9 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
}
/**
- * @param nodeId Failed node ID.
- * @param mappings Remaining mappings.
* @param e Error.
*/
- void onError(@Nullable UUID nodeId, @Nullable Iterable<GridDistributedTxMapping> mappings, Throwable e) {
+ void onError(Throwable e) {
if (X.hasCause(e, ClusterTopologyCheckedException.class) || X.hasCause(e, ClusterTopologyException.class)) {
if (tx.onePhaseCommit()) {
tx.markForBackupCheck();
@@ -157,12 +150,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
if (err.compareAndSet(null, e)) {
boolean marked = tx.setRollbackOnly();
- if (e instanceof IgniteTxOptimisticCheckedException) {
- assert nodeId != null : "Missing node ID for optimistic failure exception: " + e;
-
- tx.removeKeysMapping(nodeId, mappings);
- }
-
if (e instanceof IgniteTxRollbackCheckedException) {
if (marked) {
try {
@@ -199,7 +186,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
/** {@inheritDoc} */
@Override public void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
if (!isDone()) {
- for (IgniteInternalFuture<IgniteInternalTx> fut : pending()) {
+ for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
if (isMini(fut)) {
MiniFuture f = (MiniFuture)fut;
@@ -253,212 +240,38 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
return false;
}
- /** {@inheritDoc} */
- @Override public void prepare() {
- // Obtain the topology version to use.
- AffinityTopologyVersion topVer = cctx.mvcc().lastExplicitLockTopologyVersion(Thread.currentThread().getId());
-
- // If there is another system transaction in progress, use it's topology version to prevent deadlock.
- if (topVer == null && tx != null && tx.system()) {
- IgniteInternalTx tx0 = cctx.tm().anyActiveThreadTx(tx);
-
- if (tx0 != null)
- topVer = tx0.topologyVersionSnapshot();
- }
-
- if (topVer != null) {
- tx.topologyVersion(topVer);
-
- cctx.mvcc().addFuture(this);
-
- prepare0(false, true);
-
- return;
- }
-
- prepareOnTopology(false, null);
- }
-
- /**
- * @param remap Remap flag.
- * @param c Optional closure to run after map.
- */
- private void prepareOnTopology(final boolean remap, @Nullable final Runnable c) {
- GridDhtTopologyFuture topFut = topologyReadLock();
-
- AffinityTopologyVersion topVer = null;
-
- try {
- if (topFut == null) {
- assert isDone();
-
- return;
- }
-
- if (topFut.isDone()) {
- topVer = topFut.topologyVersion();
-
- if (remap)
- tx.onRemap(topVer);
- else
- tx.topologyVersion(topVer);
-
- if (!remap)
- cctx.mvcc().addFuture(this);
- }
- }
- finally {
- topologyReadUnlock();
- }
-
- if (topVer != null) {
- StringBuilder invalidCaches = null;
-
- for (Integer cacheId : tx.activeCacheIds()) {
- GridCacheContext ctx = cctx.cacheContext(cacheId);
-
- assert ctx != null : cacheId;
-
- Throwable err = topFut.validateCache(ctx);
-
- if (err != null) {
- if (invalidCaches != null)
- invalidCaches.append(", ");
- else
- invalidCaches = new StringBuilder();
-
- invalidCaches.append(U.maskName(ctx.name()));
- }
- }
-
- if (invalidCaches != null) {
- onDone(new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
- invalidCaches.toString()));
-
- return;
- }
-
- prepare0(remap, false);
-
- if (c != null)
- c.run();
- }
- else {
- topFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
- @Override public void apply(final IgniteInternalFuture<AffinityTopologyVersion> fut) {
- cctx.kernalContext().closure().runLocalSafe(new GridPlainRunnable() {
- @Override public void run() {
- try {
- fut.get();
-
- prepareOnTopology(remap, c);
- }
- catch (IgniteCheckedException e) {
- onDone(e);
- }
- finally {
- cctx.txContextReset();
- }
- }
- });
- }
- });
- }
- }
-
- /**
- * Acquires topology read lock.
- *
- * @return Topology ready future.
- */
- private GridDhtTopologyFuture topologyReadLock() {
- if (tx.activeCacheIds().isEmpty())
- return cctx.exchange().lastTopologyFuture();
-
- GridCacheContext<?, ?> nonLocCtx = null;
-
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (!cacheCtx.isLocal()) {
- nonLocCtx = cacheCtx;
-
- break;
- }
- }
-
- if (nonLocCtx == null)
- return cctx.exchange().lastTopologyFuture();
-
- nonLocCtx.topology().readLock();
-
- if (nonLocCtx.topology().stopping()) {
- onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
- nonLocCtx.name()));
-
- return null;
- }
-
- return nonLocCtx.topology().topologyVersionFuture();
- }
-
- /**
- * Releases topology read lock.
- */
- private void topologyReadUnlock() {
- if (!tx.activeCacheIds().isEmpty()) {
- GridCacheContext<?, ?> nonLocCtx = null;
-
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (!cacheCtx.isLocal()) {
- nonLocCtx = cacheCtx;
-
- break;
- }
- }
-
- if (nonLocCtx != null)
- nonLocCtx.topology().readUnlock();
- }
- }
-
/**
* Initializes future.
*
* @param remap Remap flag.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
*/
- private void prepare0(boolean remap, boolean topLocked) {
+ @Override protected void prepare0(boolean remap, boolean topLocked) {
try {
boolean txStateCheck = remap ? tx.state() == PREPARING : tx.state(PREPARING);
if (!txStateCheck) {
if (tx.setRollbackOnly()) {
if (tx.timedOut())
- onError(null, null, new IgniteTxTimeoutCheckedException("Transaction timed out and " +
+ onError(new IgniteTxTimeoutCheckedException("Transaction timed out and " +
"was rolled back: " + this));
else
- onError(null, null, new IgniteCheckedException("Invalid transaction state for prepare " +
+ onError(new IgniteCheckedException("Invalid transaction state for prepare " +
"[state=" + tx.state() + ", tx=" + this + ']'));
}
else
- onError(null, null, new IgniteTxRollbackCheckedException("Invalid transaction state for " +
+ onError(new IgniteTxRollbackCheckedException("Invalid transaction state for " +
"prepare [state=" + tx.state() + ", tx=" + this + ']'));
return;
}
- prepare(
- tx.optimistic() && tx.serializable() ? tx.readEntries() : Collections.<IgniteTxEntry>emptyList(),
- tx.writeEntries(),
- topLocked);
+ prepare(tx.writeEntries(), topLocked);
markInitialized();
}
- catch (TransactionTimeoutException | TransactionOptimisticException e) {
- onError(cctx.localNodeId(), null, e);
+ catch (TransactionTimeoutException e) {
+ onError( e);
}
catch (IgniteCheckedException e) {
onDone(e);
@@ -466,13 +279,11 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
}
/**
- * @param reads Read entries.
* @param writes Write entries.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
* @throws IgniteCheckedException If failed.
*/
private void prepare(
- Iterable<IgniteTxEntry> reads,
Iterable<IgniteTxEntry> writes,
boolean topLocked
) throws IgniteCheckedException {
@@ -484,7 +295,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
ConcurrentLinkedDeque8<GridDistributedTxMapping> mappings = new ConcurrentLinkedDeque8<>();
- if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
+ if (!F.isEmpty(writes)) {
for (int cacheId : tx.activeCacheIds()) {
GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
@@ -500,25 +311,8 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
// Assign keys to primary nodes.
GridDistributedTxMapping cur = null;
- for (IgniteTxEntry read : reads) {
- GridDistributedTxMapping updated = map(read, topVer, cur, false, topLocked);
-
- if (cur != updated) {
- mappings.offer(updated);
-
- if (updated.node().isLocal()) {
- if (read.context().isNear())
- tx.nearLocallyMapped(true);
- else if (read.context().isColocated())
- tx.colocatedLocallyMapped(true);
- }
-
- cur = updated;
- }
- }
-
for (IgniteTxEntry write : writes) {
- GridDistributedTxMapping updated = map(write, topVer, cur, true, topLocked);
+ GridDistributedTxMapping updated = map(write, topVer, cur, topLocked);
if (cur != updated) {
mappings.offer(updated);
@@ -576,7 +370,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
futId,
tx.topologyVersion(),
tx,
- tx.optimistic() && tx.serializable() ? m.reads() : null,
+ null,
m.writes(),
m.near(),
txMapping.transactionNodes(),
@@ -604,7 +398,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
tx.userPrepare();
}
catch (IgniteCheckedException e) {
- onError(null, null, e);
+ onError(e);
}
}
@@ -651,7 +445,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
* @param entry Transaction entry.
* @param topVer Topology version.
* @param cur Current mapping.
- * @param waitLock Wait lock flag.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
* @return Mapping.
*/
@@ -659,7 +452,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
IgniteTxEntry entry,
AffinityTopologyVersion topVer,
@Nullable GridDistributedTxMapping cur,
- boolean waitLock,
boolean topLocked
) {
GridCacheContext cacheCtx = entry.context();
@@ -687,7 +479,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
entry.cached(cacheCtx.local().entryEx(entry.key(), topVer));
if (cacheCtx.isNear() || cacheCtx.isLocal()) {
- if (waitLock && entry.explicitVersion() == null)
+ if (entry.explicitVersion() == null)
lockKeys.add(entry.txKey());
}
@@ -749,7 +541,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
/**
*
*/
- private class MiniFuture extends GridFutureAdapter<IgniteInternalTx> {
+ private class MiniFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
/** */
private static final long serialVersionUID = 0L;
@@ -828,7 +620,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
// Fail the whole future (make sure not to remap on different primary node
// to prevent multiple lock coordinators).
- onError(null, null, e);
+ onError(e);
}
}
@@ -836,14 +628,14 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
* @param nodeId Failed node ID.
* @param res Result callback.
*/
- void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
+ void onResult(UUID nodeId, final GridNearTxPrepareResponse res) {
if (isDone())
return;
if (rcvRes.compareAndSet(false, true)) {
if (res.error() != null) {
// Fail the whole compound future.
- onError(nodeId, mappings, res.error());
+ onError(res.error());
}
else {
if (res.clientRemapVersion() != null) {
@@ -877,7 +669,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
proceedPrepare(mappings);
// Finish this mini future.
- onDone(tx);
+ onDone((GridNearTxPrepareResponse)null);
}
}
}
@@ -889,7 +681,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
private void remap() {
prepareOnTopology(true, new Runnable() {
@Override public void run() {
- onDone(tx);
+ onDone((GridNearTxPrepareResponse)null);
}
});
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
new file mode 100644
index 0000000..fd9183e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.near;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+import org.apache.ignite.internal.util.lang.GridPlainRunnable;
+import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public abstract class GridNearOptimisticTxPrepareFutureAdapter extends GridNearTxPrepareFutureAdapter {
+ /**
+ * @param cctx Context.
+ * @param tx Transaction.
+ */
+ public GridNearOptimisticTxPrepareFutureAdapter(GridCacheSharedContext cctx, GridNearTxLocal tx) {
+ super(cctx, tx);
+
+ assert tx.optimistic() : tx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public final void prepare() {
+ // Obtain the topology version to use.
+ AffinityTopologyVersion topVer = cctx.mvcc().lastExplicitLockTopologyVersion(Thread.currentThread().getId());
+
+ // If there is another system transaction in progress, use it's topology version to prevent deadlock.
+ if (topVer == null && tx != null && tx.system()) {
+ IgniteInternalTx tx0 = cctx.tm().anyActiveThreadTx(tx);
+
+ if (tx0 != null)
+ topVer = tx0.topologyVersionSnapshot();
+ }
+
+ if (topVer != null) {
+ tx.topologyVersion(topVer);
+
+ cctx.mvcc().addFuture(this);
+
+ prepare0(false, true);
+
+ return;
+ }
+
+ prepareOnTopology(false, null);
+ }
+
+ /**
+ * Acquires topology read lock.
+ *
+ * @return Topology ready future.
+ */
+ protected final GridDhtTopologyFuture topologyReadLock() {
+ if (tx.activeCacheIds().isEmpty())
+ return cctx.exchange().lastTopologyFuture();
+
+ GridCacheContext<?, ?> nonLocCtx = null;
+
+ for (int cacheId : tx.activeCacheIds()) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (!cacheCtx.isLocal()) {
+ nonLocCtx = cacheCtx;
+
+ break;
+ }
+ }
+
+ if (nonLocCtx == null)
+ return cctx.exchange().lastTopologyFuture();
+
+ nonLocCtx.topology().readLock();
+
+ if (nonLocCtx.topology().stopping()) {
+ onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
+ nonLocCtx.name()));
+
+ return null;
+ }
+
+ return nonLocCtx.topology().topologyVersionFuture();
+ }
+
+ /**
+ * Releases topology read lock.
+ */
+ protected final void topologyReadUnlock() {
+ if (!tx.activeCacheIds().isEmpty()) {
+ GridCacheContext<?, ?> nonLocCtx = null;
+
+ for (int cacheId : tx.activeCacheIds()) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (!cacheCtx.isLocal()) {
+ nonLocCtx = cacheCtx;
+
+ break;
+ }
+ }
+
+ if (nonLocCtx != null)
+ nonLocCtx.topology().readUnlock();
+ }
+ }
+
+ /**
+ * @param remap Remap flag.
+ * @param c Optional closure to run after map.
+ */
+ protected final void prepareOnTopology(final boolean remap, @Nullable final Runnable c) {
+ GridDhtTopologyFuture topFut = topologyReadLock();
+
+ AffinityTopologyVersion topVer = null;
+
+ try {
+ if (topFut == null) {
+ assert isDone();
+
+ return;
+ }
+
+ if (topFut.isDone()) {
+ topVer = topFut.topologyVersion();
+
+ if (remap)
+ tx.onRemap(topVer);
+ else
+ tx.topologyVersion(topVer);
+
+ if (!remap)
+ cctx.mvcc().addFuture(this);
+ }
+ }
+ finally {
+ topologyReadUnlock();
+ }
+
+ if (topVer != null) {
+ StringBuilder invalidCaches = null;
+
+ for (Integer cacheId : tx.activeCacheIds()) {
+ GridCacheContext ctx = cctx.cacheContext(cacheId);
+
+ assert ctx != null : cacheId;
+
+ Throwable err = topFut.validateCache(ctx);
+
+ if (err != null) {
+ if (invalidCaches != null)
+ invalidCaches.append(", ");
+ else
+ invalidCaches = new StringBuilder();
+
+ invalidCaches.append(U.maskName(ctx.name()));
+ }
+ }
+
+ if (invalidCaches != null) {
+ onDone(new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
+ invalidCaches.toString()));
+
+ return;
+ }
+
+ prepare0(remap, false);
+
+ if (c != null)
+ c.run();
+ }
+ else {
+ topFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
+ @Override public void apply(final IgniteInternalFuture<AffinityTopologyVersion> fut) {
+ cctx.kernalContext().closure().runLocalSafe(new GridPlainRunnable() {
+ @Override public void run() {
+ try {
+ fut.get();
+
+ prepareOnTopology(remap, c);
+ }
+ catch (IgniteCheckedException e) {
+ onDone(e);
+ }
+ finally {
+ cctx.txContextReset();
+ }
+ }
+ });
+ }
+ });
+ }
+ }
+
+ /**
+ * @param remap Remap flag.
+ * @param topLocked {@code True} if thread already acquired lock preventing topology change.
+ */
+ protected abstract void prepare0(boolean remap, boolean topLocked);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
index 62f9bb3..11d31b2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
@@ -103,7 +103,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
if (!isDone()) {
assert res.clientRemapVersion() == null : res;
- for (IgniteInternalFuture<IgniteInternalTx> fut : pending()) {
+ for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
MiniFuture f = (MiniFuture)fut;
if (f.futureId().equals(res.miniId())) {
@@ -292,7 +292,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
/**
*
*/
- private class MiniFuture extends GridFutureAdapter<IgniteInternalTx> {
+ private class MiniFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
/** */
private static final long serialVersionUID = 0L;
@@ -332,7 +332,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
else {
onPrepareResponse(m, res);
- onDone(tx);
+ onDone(res);
}
}
@@ -344,7 +344,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
tx.markForBackupCheck();
// Do not fail future for one-phase transaction right away.
- onDone(tx);
+ onDone((GridNearTxPrepareResponse)null);
}
onError(e);
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
index c3bb324..0e8aa0d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
@@ -117,7 +117,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
@Nullable final Collection<? extends K> keys,
boolean forcePrimary,
boolean skipTx,
- @Nullable final GridCacheEntryEx entry,
@Nullable UUID subjId,
String taskName,
final boolean deserializePortable,
@@ -143,7 +142,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
@Override public IgniteInternalFuture<Map<K, V>> op(IgniteTxLocalAdapter tx) {
return tx.getAllAsync(ctx,
ctx.cacheKeysView(keys),
- entry,
deserializePortable,
skipVals,
false,
@@ -156,7 +154,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
return loadAsync(null,
ctx.cacheKeysView(keys),
- false,
forcePrimary,
subjId,
taskName,
@@ -174,6 +171,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
* @param deserializePortable Deserialize portable flag.
* @param expiryPlc Expiry policy.
* @param skipVals Skip values flag.
+ * @param needVer If {@code true} returns values as tuples containing value and version.
* @return Future.
*/
IgniteInternalFuture<Map<K, V>> txLoadAsync(GridNearTxLocal tx,
@@ -181,21 +179,23 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
boolean readThrough,
boolean deserializePortable,
@Nullable IgniteCacheExpiryPolicy expiryPlc,
- boolean skipVals) {
+ boolean skipVals,
+ boolean needVer) {
assert tx != null;
GridNearGetFuture<K, V> fut = new GridNearGetFuture<>(ctx,
keys,
readThrough,
- false,
- false,
+ /*force primary*/needVer,
tx,
CU.subjectId(tx, ctx.shared()),
tx.resolveTaskName(),
deserializePortable,
expiryPlc,
skipVals,
- /*can remap*/true);
+ /*can remap*/true,
+ needVer,
+ /*keepCacheObjects*/true);
// init() will register future for responses if it has remote mappings.
fut.init();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index 1a4f130..46c9f3e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
@@ -266,9 +266,11 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
}
if (tx.onePhaseCommit()) {
- finishOnePhase();
+ boolean commit = this.commit && err == null;
- tx.tmFinish(commit && err == null);
+ finishOnePhase(commit);
+
+ tx.tmFinish(commit);
}
Throwable th = this.err.get();
@@ -510,9 +512,9 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
}
/**
- *
+ * @param commit Commit flag.
*/
- private void finishOnePhase() {
+ private void finishOnePhase(boolean commit) {
// No need to send messages as transaction was already committed on remote node.
// Finish local mapping only as we need send commit message to backups.
for (GridDistributedTxMapping m : mappings.values()) {
@@ -522,6 +524,8 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
// Add new future.
if (fut != null)
add(fut);
+
+ break;
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index ea96649..883c285 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -55,14 +55,15 @@ import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.future.GridEmbeddedFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.lang.GridClosureException;
+import org.apache.ignite.internal.util.lang.GridInClosure3;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;
@@ -342,32 +343,30 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/** {@inheritDoc} */
- @Override public IgniteInternalFuture<Boolean> loadMissing(
+ @Override public IgniteInternalFuture<Void> loadMissing(
final GridCacheContext cacheCtx,
boolean readThrough,
boolean async,
final Collection<KeyCacheObject> keys,
- boolean deserializePortable,
boolean skipVals,
- final IgniteBiInClosure<KeyCacheObject, Object> c
+ final boolean needVer,
+ final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c
) {
if (cacheCtx.isNear()) {
return cacheCtx.nearTx().txLoadAsync(this,
keys,
readThrough,
- deserializePortable,
+ /*deserializePortable*/false,
accessPolicy(cacheCtx, keys),
- skipVals).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Boolean>() {
- @Override public Boolean apply(IgniteInternalFuture<Map<Object, Object>> f) {
+ skipVals,
+ needVer).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
+ @Override public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
try {
Map<Object, Object> map = f.get();
- // Must loop through keys, not map entries,
- // as map entries may not have all the keys.
- for (KeyCacheObject key : keys)
- c.apply(key, map.get(key.value(cacheCtx.cacheObjectContext(), false)));
+ processLoaded(map, keys, needVer, c);
- return true;
+ return null;
}
catch (Exception e) {
setRollbackOnly();
@@ -381,39 +380,73 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
return cacheCtx.colocated().loadAsync(
keys,
readThrough,
- /*reload*/false,
- /*force primary*/false,
+ /*force primary*/needVer,
topologyVersion(),
CU.subjectId(this, cctx),
resolveTaskName(),
- deserializePortable,
+ /*deserializePortable*/false,
accessPolicy(cacheCtx, keys),
skipVals,
- /*can remap*/true
- ).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Boolean>() {
- @Override public Boolean apply(IgniteInternalFuture<Map<Object, Object>> f) {
- try {
- Map<Object, Object> map = f.get();
-
- // Must loop through keys, not map entries,
- // as map entries may not have all the keys.
- for (KeyCacheObject key : keys)
- c.apply(key, map.get(key.value(cacheCtx.cacheObjectContext(), false)));
-
- return true;
- }
- catch (Exception e) {
- setRollbackOnly();
-
- throw new GridClosureException(e);
- }
+ /*can remap*/true,
+ needVer,
+ /*keepCacheObject*/true
+ ).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
+ @Override public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
+ try {
+ Map<Object, Object> map = f.get();
+
+ processLoaded(map, keys, needVer, c);
+
+ return null;
}
- });
+ catch (Exception e) {
+ setRollbackOnly();
+
+ throw new GridClosureException(e);
+ }
+ }
+ });
}
else {
assert cacheCtx.isLocal();
- return super.loadMissing(cacheCtx, readThrough, async, keys, deserializePortable, skipVals, c);
+ return super.loadMissing(cacheCtx, readThrough, async, keys, skipVals, needVer, c);
+ }
+ }
+
+ /**
+ * @param map Loaded values.
+ * @param keys Keys.
+ * @param needVer If {@code true} version is required for loaded values.
+ * @param c Closure.
+ */
+ private void processLoaded(
+ Map<Object, Object> map,
+ final Collection<KeyCacheObject> keys,
+ boolean needVer,
+ GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
+ for (KeyCacheObject key : keys) {
+ Object val = map.get(key);
+
+ if (val != null) {
+ Object v;
+ GridCacheVersion ver;
+
+ if (needVer) {
+ T2<Object, GridCacheVersion> t = (T2)val;
+
+ v = t.get1();
+ ver = t.get2();
+ }
+ else {
+ v = val;
+ ver = null;
+ }
+
+ c.apply(key, v, ver);
+ }
+ else
+ c.apply(key, null, IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER);
}
}
@@ -555,36 +588,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
}
-
- /**
- * Removes mapping in case of optimistic tx failure on primary node.
- *
- * @param failedNodeId Failed node ID.
- * @param mapQueue Mappings queue.
- */
- void removeKeysMapping(UUID failedNodeId, Iterable<GridDistributedTxMapping> mapQueue) {
- assert failedNodeId != null;
- assert mapQueue != null;
-
- mappings.remove(failedNodeId);
-
- if (!F.isEmpty(mapQueue)) {
- for (GridDistributedTxMapping m : mapQueue) {
- UUID nodeId = m.node().id();
-
- GridDistributedTxMapping mapping = mappings.get(nodeId);
-
- if (mapping != null) {
- for (IgniteTxEntry entry : m.entries())
- mapping.removeEntry(entry);
-
- if (mapping.entries().isEmpty())
- mappings.remove(nodeId);
- }
- }
- }
- }
-
/**
* @param nodeId Node ID to mark with explicit lock.
* @return {@code True} if mapping was found.
@@ -621,7 +624,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
Collection<GridCacheVersion> committedVers,
Collection<GridCacheVersion> rolledbackVers)
{
- Collection<IgniteTxEntry> entries = F.concat(false, mapping.reads(), mapping.writes());
+ Collection<IgniteTxEntry> entries = F.concat(false, mapping.writes(), mapping.reads());
for (IgniteTxEntry txEntry : entries) {
while (true) {
@@ -743,8 +746,13 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
if (fut == null) {
// Future must be created before any exception can be thrown.
- fut = optimistic() ? new GridNearOptimisticTxPrepareFuture(cctx, this) :
- new GridNearPessimisticTxPrepareFuture(cctx, this);
+ if (optimistic()) {
+ fut = serializable() ?
+ new GridNearOptimisticSerializableTxPrepareFuture(cctx, this) :
+ new GridNearOptimisticTxPrepareFuture(cctx, this);
+ }
+ else
+ fut = new GridNearPessimisticTxPrepareFuture(cctx, this);
if (!prepFut.compareAndSet(null, fut))
return prepFut.get();
@@ -871,7 +879,8 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
public IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsyncLocal(
@Nullable Collection<IgniteTxEntry> reads,
@Nullable Collection<IgniteTxEntry> writes,
- Map<UUID, Collection<UUID>> txNodes, boolean last,
+ Map<UUID, Collection<UUID>> txNodes,
+ boolean last,
Collection<UUID> lastBackups
) {
if (state() != PREPARING) {
@@ -899,7 +908,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
try {
// At this point all the entries passed in must be enlisted in transaction because this is an
// optimistic transaction.
- optimisticLockEntries = writes;
+ optimisticLockEntries = (serializable() && optimistic()) ? F.concat(false, writes, reads) : writes;
userPrepare();
@@ -1192,12 +1201,8 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
return plc;
}
- /**
- * @param cacheCtx Cache context.
- * @param keys Keys.
- * @return Expiry policy.
- */
- private IgniteCacheExpiryPolicy accessPolicy(GridCacheContext cacheCtx, Collection<KeyCacheObject> keys) {
+ /** {@inheritDoc} */
+ @Override protected IgniteCacheExpiryPolicy accessPolicy(GridCacheContext cacheCtx, Collection<KeyCacheObject> keys) {
if (accessMap != null) {
for (Map.Entry<IgniteTxKey, IgniteCacheExpiryPolicy> e : accessMap.entrySet()) {
if (e.getKey().cacheId() == cacheCtx.cacheId() && keys.contains(e.getKey().key()))
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
index fac7a12..45477a0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
@@ -34,7 +34,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
-import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
+import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.F;
@@ -48,15 +48,15 @@ import static org.apache.ignite.internal.processors.cache.GridCacheOperation.NOO
/**
* Common code for tx prepare in optimistic and pessimistic modes.
*/
-public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundIdentityFuture<IgniteInternalTx>
+public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundFuture<GridNearTxPrepareResponse, IgniteInternalTx>
implements GridCacheFuture<IgniteInternalTx> {
/** Logger reference. */
protected static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
/** */
- private static final IgniteReducer<IgniteInternalTx, IgniteInternalTx> REDUCER =
- new IgniteReducer<IgniteInternalTx, IgniteInternalTx>() {
- @Override public boolean collect(IgniteInternalTx e) {
+ private static final IgniteReducer<GridNearTxPrepareResponse, IgniteInternalTx> REDUCER =
+ new IgniteReducer<GridNearTxPrepareResponse, IgniteInternalTx>() {
+ @Override public boolean collect(GridNearTxPrepareResponse e) {
return true;
}
@@ -94,7 +94,7 @@ public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundIdentit
* @param tx Transaction.
*/
public GridNearTxPrepareFutureAdapter(GridCacheSharedContext cctx, final GridNearTxLocal tx) {
- super(cctx.kernalContext(), REDUCER);
+ super(REDUCER);
assert cctx != null;
assert tx != null;
@@ -201,6 +201,7 @@ public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundIdentit
}
catch (GridCacheEntryRemovedException ignored) {
// Retry.
+ txEntry.cached(cacheCtx.cache().entryEx(txEntry.key()));
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
index cacac13..85ed881 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
@@ -67,6 +67,8 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
*
* @param threadId Owning thread ID.
* @param ver Lock version.
+ * @param serOrder Version for serializable transactions ordering.
+ * @param serReadVer Optional read entry version for optimistic serializable transaction.
* @param timeout Timeout to acquire lock.
* @param reenter Reentry flag.
* @param tx Transaction flag.
@@ -77,6 +79,8 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
@Nullable public GridCacheMvccCandidate addLocal(
long threadId,
GridCacheVersion ver,
+ @Nullable GridCacheVersion serOrder,
+ @Nullable GridCacheVersion serReadVer,
long timeout,
boolean reenter,
boolean tx,
@@ -91,6 +95,11 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
synchronized (this) {
checkObsolete();
+ if (serReadVer != null) {
+ if (!checkSerializableReadVersion(serReadVer))
+ return null;
+ }
+
GridCacheMvcc mvcc = mvccExtras();
if (mvcc == null) {
@@ -103,12 +112,16 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
cand = mvcc.addLocal(
this,
+ /*nearNodeId*/null,
+ /*nearVer*/null,
threadId,
ver,
timeout,
+ serOrder,
reenter,
tx,
- implicitSingle
+ implicitSingle,
+ /*dht-local*/false
);
owner = mvcc.localOwner();
@@ -191,10 +204,16 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
}
/** {@inheritDoc} */
- @Override public boolean tmLock(IgniteInternalTx tx, long timeout) throws GridCacheEntryRemovedException {
+ @Override public boolean tmLock(IgniteInternalTx tx,
+ long timeout,
+ @Nullable GridCacheVersion serOrder,
+ GridCacheVersion serReadVer)
+ throws GridCacheEntryRemovedException {
GridCacheMvccCandidate cand = addLocal(
tx.threadId(),
tx.xidVersion(),
+ serOrder,
+ serReadVer,
timeout,
/*reenter*/false,
/*tx*/true,
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
index 7018c4e..cb14b4c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
@@ -225,6 +225,8 @@ public final class GridLocalLockFuture<K, V> extends GridFutureAdapter<Boolean>
GridCacheMvccCandidate c = entry.addLocal(
threadId,
lockVer,
+ null,
+ null,
timeout,
!inTx(),
inTx(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
index 0bf6ea2..8446665 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
@@ -495,7 +495,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
@Nullable final Collection<? extends K> keys,
final boolean forcePrimary,
boolean skipTx,
- @Nullable final GridCacheEntryEx entry,
@Nullable UUID subjId,
final String taskName,
final boolean deserializePortable,
@@ -595,10 +594,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
catch (GridCacheEntryRemovedException ignored) {
// No-op, retry.
}
- catch (GridCacheFilterFailedException ignored) {
- // No-op, skip the key.
- break;
- }
finally {
if (entry != null)
ctx.evicts().touch(entry, ctx.affinity().affinityTopologyVersion());
@@ -615,7 +610,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
return getAllAsync(
keys,
opCtx == null || !opCtx.skipStore(),
- null,
false,
subjId,
taskName,
@@ -1284,9 +1278,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
catch (GridCacheEntryRemovedException ignore) {
assert false : "Entry cannot become obsolete while holding lock.";
}
- catch (GridCacheFilterFailedException ignore) {
- assert false : "Filter should never fail with failFast=false and empty filter.";
- }
}
// Store final batch.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
index c0c2284..716676f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
@@ -147,12 +147,6 @@ public class IgniteTransactionsImpl<K, V> implements IgniteTransactionsEx {
cctx.kernalContext().gateway().readLock();
try {
- TransactionConfiguration cfg = cctx.gridConfig().getTransactionConfiguration();
-
- if (!cfg.isTxSerializableEnabled() && isolation == SERIALIZABLE)
- throw new IllegalArgumentException("SERIALIZABLE isolation level is disabled (to enable change " +
- "'txSerializableEnabled' configuration property)");
-
IgniteInternalTx tx = cctx.tm().userTx(sysCacheCtx);
if (tx != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index 7d7e3e8..1c82636 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -325,7 +325,8 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
threadId = Thread.currentThread().getId();
- log = U.logger(cctx.kernalContext(), logRef, this);
+ if (log == null)
+ log = U.logger(cctx.kernalContext(), logRef, this);
}
/**
@@ -374,7 +375,8 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
implicitSingle = false;
loc = false;
- log = U.logger(cctx.kernalContext(), logRef, this);
+ if (log == null)
+ log = U.logger(cctx.kernalContext(), logRef, this);
}
/** {@inheritDoc} */
@@ -430,6 +432,9 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> optimisticLockEntries() {
+ if (serializable() && optimistic())
+ return F.concat(false, writeEntries(), readEntries());
+
return writeEntries();
}
@@ -1267,88 +1272,81 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
if (F.isEmpty(txEntry.entryProcessors()))
return F.t(txEntry.op(), txEntry.value());
else {
- try {
- boolean recordEvt = cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ);
+ boolean recordEvt = cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ);
- CacheObject cacheVal = txEntry.hasValue() ? txEntry.value() :
- txEntry.cached().innerGet(this,
- /*swap*/false,
- /*read through*/false,
- /*fail fast*/true,
- /*unmarshal*/true,
- /*metrics*/metrics,
- /*event*/recordEvt,
- /*temporary*/true,
- /*subjId*/subjId,
- /**closure name */recordEvt ? F.first(txEntry.entryProcessors()).get1() : null,
- resolveTaskName(),
- null);
+ CacheObject cacheVal = txEntry.hasValue() ? txEntry.value() :
+ txEntry.cached().innerGet(this,
+ /*swap*/false,
+ /*read through*/false,
+ /*fail fast*/true,
+ /*unmarshal*/true,
+ /*metrics*/metrics,
+ /*event*/recordEvt,
+ /*temporary*/true,
+ /*subjId*/subjId,
+ /**closure name */recordEvt ? F.first(txEntry.entryProcessors()).get1() : null,
+ resolveTaskName(),
+ null);
- boolean modified = false;
+ boolean modified = false;
- Object val = null;
+ Object val = null;
- Object key = null;
+ Object key = null;
- GridCacheVersion ver;
-
- try {
- ver = txEntry.cached().version();
- }
- catch (GridCacheEntryRemovedException e) {
- assert optimistic() : txEntry;
+ GridCacheVersion ver;
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
+ try {
+ ver = txEntry.cached().version();
+ }
+ catch (GridCacheEntryRemovedException e) {
+ assert optimistic() : txEntry;
- ver = null;
- }
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
- for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : txEntry.entryProcessors()) {
- CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(txEntry.context(),
- txEntry.key(), key, cacheVal, val, ver);
+ ver = null;
+ }
- try {
- EntryProcessor<Object, Object, Object> processor = t.get1();
+ for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : txEntry.entryProcessors()) {
+ CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(txEntry.context(),
+ txEntry.key(), key, cacheVal, val, ver);
- processor.process(invokeEntry, t.get2());
+ try {
+ EntryProcessor<Object, Object, Object> processor = t.get1();
- val = invokeEntry.getValue();
+ processor.process(invokeEntry, t.get2());
- key = invokeEntry.key();
- }
- catch (Exception ignore) {
- // No-op.
- }
+ val = invokeEntry.getValue();
- modified |= invokeEntry.modified();
+ key = invokeEntry.key();
+ }
+ catch (Exception ignore) {
+ // No-op.
}
- if (modified)
- cacheVal = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(val));
+ modified |= invokeEntry.modified();
+ }
- GridCacheOperation op = modified ? (val == null ? DELETE : UPDATE) : NOOP;
+ if (modified)
+ cacheVal = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(val));
- if (op == NOOP) {
- ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
+ GridCacheOperation op = modified ? (val == null ? DELETE : UPDATE) : NOOP;
- if (expiry != null) {
- long ttl = CU.toTtl(expiry.getExpiryForAccess());
+ if (op == NOOP) {
+ ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
- txEntry.ttl(ttl);
+ if (expiry != null) {
+ long ttl = CU.toTtl(expiry.getExpiryForAccess());
- if (ttl == CU.TTL_ZERO)
- op = DELETE;
- }
- }
+ txEntry.ttl(ttl);
- return F.t(op, cacheVal);
+ if (ttl == CU.TTL_ZERO)
+ op = DELETE;
+ }
}
- catch (GridCacheFilterFailedException e) {
- assert false : "Empty filter failed for innerGet: " + e;
- return null;
- }
+ return F.t(op, cacheVal);
}
}
@@ -1498,9 +1496,8 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
* @param e Entry to evict if it qualifies for eviction.
* @param primaryOnly Flag to try to evict only on primary node.
* @return {@code True} if attempt was made to evict the entry.
- * @throws IgniteCheckedException If failed.
*/
- protected boolean evictNearEntry(IgniteTxEntry e, boolean primaryOnly) throws IgniteCheckedException {
+ protected boolean evictNearEntry(IgniteTxEntry e, boolean primaryOnly) {
assert e != null;
if (isNearLocallyMapped(e, primaryOnly)) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
index 2462dda..9eb2808 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
@@ -66,6 +66,12 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
/** */
private static final long serialVersionUID = 0L;
+ /** Dummy version for non-existing entry read in SERIALIZABLE transaction. */
+ public static final GridCacheVersion SER_READ_EMPTY_ENTRY_VER = new GridCacheVersion(0, 0, 0, 0);
+
+ /** Dummy version for any existing entry read in SERIALIZABLE transaction. */
+ public static final GridCacheVersion SER_READ_NOT_EMPTY_VER = new GridCacheVersion(0, 0, 0, 1);
+
/** Owning transaction. */
@GridToStringExclude
@GridDirectTransient
@@ -175,6 +181,9 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
*/
private byte flags;
+ /** */
+ private GridCacheVersion serReadVer;
+
/**
* Required by {@link Externalizable}
*/
@@ -316,6 +325,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
cp.conflictVer = conflictVer;
cp.expiryPlc = expiryPlc;
cp.flags = flags;
+ cp.serReadVer = serReadVer;
return cp;
}
@@ -822,6 +832,23 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
this.entryProcessorCalcVal = entryProcessorCalcVal;
}
+ /**
+ * @return Read version for serializable transaction.
+ */
+ @Nullable public GridCacheVersion serializableReadVersion() {
+ return serReadVer;
+ }
+
+ /**
+ * @param serReadVer Read version for serializable transaction.
+ */
+ public void serializableReadVersion(GridCacheVersion serReadVer) {
+ assert this.serReadVer == null;
+ assert serReadVer != null;
+
+ this.serReadVer = serReadVer;
+ }
+
/** {@inheritDoc} */
@Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
writer.setBuffer(buf);
@@ -884,18 +911,24 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
writer.incrementState();
case 8:
- if (!writer.writeByteArray("transformClosBytes", transformClosBytes))
+ if (!writer.writeMessage("serReadVer", serReadVer))
return false;
writer.incrementState();
case 9:
- if (!writer.writeLong("ttl", ttl))
+ if (!writer.writeByteArray("transformClosBytes", transformClosBytes))
return false;
writer.incrementState();
case 10:
+ if (!writer.writeLong("ttl", ttl))
+ return false;
+
+ writer.incrementState();
+
+ case 11:
if (!writer.writeMessage("val", val))
return false;
@@ -979,7 +1012,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
reader.incrementState();
case 8:
- transformClosBytes = reader.readByteArray("transformClosBytes");
+ serReadVer = reader.readMessage("serReadVer");
if (!reader.isLastRead())
return false;
@@ -987,7 +1020,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
reader.incrementState();
case 9:
- ttl = reader.readLong("ttl");
+ transformClosBytes = reader.readByteArray("transformClosBytes");
if (!reader.isLastRead())
return false;
@@ -995,6 +1028,14 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
reader.incrementState();
case 10:
+ ttl = reader.readLong("ttl");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 11:
val = reader.readMessage("val");
if (!reader.isLastRead())
@@ -1014,7 +1055,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 11;
+ return 12;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index 530fbdf..d9786a8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@ -68,6 +68,7 @@ import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteFutureCancelledException;
+import org.apache.ignite.transactions.TransactionState;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
@@ -417,7 +418,8 @@ public class IgniteTxHandler {
if (tx.isRollbackOnly()) {
try {
- tx.rollback();
+ if (tx.state() != TransactionState.ROLLED_BACK && tx.state() != TransactionState.ROLLING_BACK)
+ tx.rollback();
}
catch (IgniteCheckedException e) {
U.error(log, "Failed to rollback transaction: " + tx, e);
[04/23] ignite git commit: Merge branch 'master' into ignite-1747
Posted by yz...@apache.org.
Merge branch 'master' into ignite-1747
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b12663fc
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b12663fc
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b12663fc
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: b12663fc44b2a0b8d0d867aa2c762e62b0c71250
Parents: 0e48722 15cc1bd
Author: Raul Kripalani <ra...@apache.org>
Authored: Mon Oct 26 13:05:46 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Mon Oct 26 13:05:46 2015 +0000
----------------------------------------------------------------------
.../internal/portable/PortableContext.java | 12 +--
.../ignite/internal/util/nio/GridNioServer.java | 2 +-
...ledFairAffinityMultiNodeFullApiSelfTest.java | 8 +-
...icOffHeapTieredMultiNodeFullApiSelfTest.java | 7 +-
.../replicated/GridReplicatedTxPreloadTest.java | 7 +-
.../nio/IgniteExceptionInNioWorkerSelfTest.java | 105 +++++++++++++++++++
.../tcp/TcpClientDiscoverySpiSelfTest.java | 4 +-
.../ignite/testsuites/IgniteBasicTestSuite.java | 3 +
.../CacheHibernateBlobStoreSelfTest.java | 6 +-
.../yardstick/IgniteBenchmarkArguments.java | 11 ++
.../cache/IgniteCacheAbstractBenchmark.java | 63 +++++++++++
.../cache/IgnitePutAllTxBenchmark.java | 6 +-
12 files changed, 220 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
[21/23] ignite git commit: Fixed test.
Posted by yz...@apache.org.
Fixed test.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/215b0cd9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/215b0cd9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/215b0cd9
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 215b0cd9cac7d67fb5609058f8270e6bc38c8f76
Parents: 2a7d886
Author: sboikov <sb...@gridgain.com>
Authored: Wed Oct 28 17:25:10 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Oct 28 17:25:10 2015 +0300
----------------------------------------------------------------------
.../processors/cache/CacheSerializableTransactionsTest.java | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/215b0cd9/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
index 70ddfa0..8c135ad 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
@@ -177,6 +177,8 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
try {
IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+ awaitPartitionMapExchange();
+
List<Integer> keys = testKeys(cache);
for (Integer key : keys)
[23/23] ignite git commit: Merge branches
'ignite-1.4-slow-server-debug' and 'master' of
https://git-wip-us.apache.org/repos/asf/ignite into
ignite-1.4-slow-server-debug
Posted by yz...@apache.org.
Merge branches 'ignite-1.4-slow-server-debug' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-1.4-slow-server-debug
Conflicts:
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/aa3de386
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/aa3de386
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/aa3de386
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: aa3de38649977745063ffbf153edb6ffca8c8706
Parents: 502223a
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Wed Oct 28 18:22:05 2015 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Wed Oct 28 18:22:05 2015 +0300
----------------------------------------------------------------------
.../internal/processors/cache/transactions/IgniteTxManager.java | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/aa3de386/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index 05129bb..e42dc4d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -28,7 +28,6 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteClientDisconnectedException;
@@ -62,7 +61,6 @@ import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.GridBoundedConcurrentOrderedMap;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.lang.GridFunc;
import org.apache.ignite.internal.util.lang.IgnitePair;
import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
@@ -77,7 +75,6 @@ import org.apache.ignite.transactions.TransactionIsolation;
import org.apache.ignite.transactions.TransactionState;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
-import org.jsr166.ConcurrentLinkedDeque8;
import org.jsr166.ConcurrentLinkedHashMap;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_MAX_COMPLETED_TX_COUNT;
[08/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
index cedb693..2577d93 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
@@ -52,6 +52,7 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.PRIMARY_SYNC
import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
/**
*
@@ -190,6 +191,11 @@ public class CrossCacheTxRandomOperationsTest extends GridCommonAbstractTest {
txOperations(OPTIMISTIC, REPEATABLE_READ, crossCacheTx, false);
txOperations(OPTIMISTIC, REPEATABLE_READ, crossCacheTx, true);
+
+ if (writeSync == FULL_SYNC) {
+ txOperations(OPTIMISTIC, SERIALIZABLE, crossCacheTx, false);
+ txOperations(OPTIMISTIC, SERIALIZABLE, crossCacheTx, true);
+ }
}
finally {
ignite.destroyCache(CACHE1);
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
index f4813ff..da54d15 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.cache;
+import java.util.Collections;
import java.util.concurrent.atomic.AtomicReference;
import javax.cache.CacheException;
import org.apache.ignite.Ignite;
@@ -330,14 +331,21 @@ public abstract class GridCacheAbstractFailoverSelfTest extends GridCacheAbstrac
* @throws IgniteCheckedException If failed.
*/
private void remove(Ignite ignite, IgniteCache<String, Integer> cache, final int cnt,
- TransactionConcurrency concurrency, TransactionIsolation isolation) throws Exception {
+ TransactionConcurrency concurrency, final TransactionIsolation isolation) throws Exception {
try {
info("Removing values form cache [0," + cnt + ')');
CU.inTx(ignite, cache, concurrency, isolation, new CIX1<IgniteCache<String, Integer>>() {
@Override public void applyx(IgniteCache<String, Integer> cache) {
- for (int i = 0; i < cnt; i++)
- cache.remove("key" + i);
+ for (int i = 0; i < cnt; i++) {
+ String key = "key" + i;
+
+ // Use removeAll for serializable tx to avoid version check.
+ if (isolation == TransactionIsolation.SERIALIZABLE)
+ cache.removeAll(Collections.singleton(key));
+ else
+ cache.remove(key);
+ }
}
});
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
index ec3ea0c..a6b5535 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
@@ -3692,7 +3692,7 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract
if (txShouldBeUsed()) {
try (Transaction tx = transactions().txStart(OPTIMISTIC, READ_COMMITTED)) {
// Remove missing key.
- assertTrue(jcache().remove(UUID.randomUUID().toString()));
+ assertFalse(jcache().remove(UUID.randomUUID().toString()));
tx.commit();
}
@@ -3708,7 +3708,7 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract
if (txShouldBeUsed()) {
try (Transaction tx = transactions().txStart(OPTIMISTIC, READ_COMMITTED)) {
// Remove missing key.
- assertTrue(jcache().remove(UUID.randomUUID().toString()));
+ assertFalse(jcache().remove(UUID.randomUUID().toString()));
tx.setRollbackOnly();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
index 122910e..5044516 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
@@ -30,6 +30,8 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.cache.CacheException;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteTransactions;
import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
@@ -37,9 +39,11 @@ import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.NearCacheConfiguration;
import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.util.lang.GridTuple;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
@@ -48,11 +52,18 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
import org.jsr166.ConcurrentHashMap8;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
/**
* Tests that removes are not lost when topology changes.
@@ -155,29 +166,54 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
* @throws Exception If failed.
*/
public void testPutAndRemove() throws Exception {
- putAndRemove(DUR, GridTestUtils.TestMemoryMode.HEAP);
+ putAndRemove(DUR, null, null, GridTestUtils.TestMemoryMode.HEAP);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testPutAndRemovePessimisticTx() throws Exception {
+ if (atomicityMode() != CacheAtomicityMode.TRANSACTIONAL)
+ return;
+
+ putAndRemove(30_000, PESSIMISTIC, REPEATABLE_READ, GridTestUtils.TestMemoryMode.HEAP);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testPutAndRemoveOptimisticSerializableTx() throws Exception {
+ if (atomicityMode() != CacheAtomicityMode.TRANSACTIONAL)
+ return;
+
+ putAndRemove(30_000, OPTIMISTIC, SERIALIZABLE, GridTestUtils.TestMemoryMode.HEAP);
}
/**
* @throws Exception If failed.
*/
public void testPutAndRemoveOffheapEvict() throws Exception {
- putAndRemove(30_000, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT);
+ putAndRemove(30_000, null, null, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT);
}
/**
* @throws Exception If failed.
*/
public void testPutAndRemoveOffheapEvictSwap() throws Exception {
- putAndRemove(30_000, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT_SWAP);
+ putAndRemove(30_000, null, null, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT_SWAP);
}
/**
* @param duration Test duration.
+ * @param txConcurrency Transaction concurrency if test explicit transaction.
+ * @param txIsolation Transaction isolation if test explicit transaction.
* @param memMode Memory mode.
* @throws Exception If failed.
*/
- private void putAndRemove(long duration, GridTestUtils.TestMemoryMode memMode) throws Exception {
+ private void putAndRemove(long duration,
+ final TransactionConcurrency txConcurrency,
+ final TransactionIsolation txIsolation,
+ GridTestUtils.TestMemoryMode memMode) throws Exception {
assertEquals(testClientNode(), (boolean) grid(0).configuration().isClientMode());
grid(0).destroyCache(null);
@@ -216,6 +252,8 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
ThreadLocalRandom rnd = ThreadLocalRandom.current();
+ IgniteTransactions txs = sndCache0.unwrap(Ignite.class).transactions();
+
while (!stop.get()) {
for (int i = 0; i < 100; i++) {
int key = rnd.nextInt(KEYS_CNT);
@@ -225,14 +263,54 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
while (true) {
try {
if (put) {
- sndCache0.put(key, i);
+ boolean failed = false;
+
+ if (txConcurrency != null) {
+ try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) {
+ sndCache0.put(key, i);
+
+ tx.commit();
+ }
+ catch (CacheException | IgniteException e) {
+ if (!X.hasCause(e, ClusterTopologyCheckedException.class)) {
+ log.error("Unexpected error: " + e);
+
+ throw e;
+ }
- expVals.put(key, F.t(i));
+ failed = true;
+ }
+ }
+ else
+ sndCache0.put(key, i);
+
+ if (!failed)
+ expVals.put(key, F.t(i));
}
else {
- sndCache0.remove(key);
+ boolean failed = false;
+
+ if (txConcurrency != null) {
+ try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) {
+ sndCache0.remove(key);
+
+ tx.commit();
+ }
+ catch (CacheException | IgniteException e) {
+ if (!X.hasCause(e, ClusterTopologyCheckedException.class)) {
+ log.error("Unexpected error: " + e);
+
+ throw e;
+ }
+
+ failed = true;
+ }
+ }
+ else
+ sndCache0.remove(key);
- expVals.put(key, F.<Integer>t(null));
+ if (!failed)
+ expVals.put(key, F.<Integer>t(null));
}
break;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
index 67bc08c..1ef77f2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
@@ -162,9 +162,6 @@ public class GridCacheConcurrentTxMultiNodeTest extends GridCommonAbstractTest {
c.setPeerClassLoadingEnabled(false);
- // Enable tracing.
-// Logger.getLogger("org.apache.ignite.kernal.processors.cache.GridCacheDgcManager.trace").setLevel(Level.DEBUG);
-
return c;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
index 084bc75..234f362 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
@@ -88,7 +88,8 @@ public class GridCacheMvccFlagsTest extends GridCommonAbstractTest {
true,
true,
true,
- true
+ true,
+ null
);
c.setOwner();
@@ -128,7 +129,8 @@ public class GridCacheMvccFlagsTest extends GridCommonAbstractTest {
false,
false,
false,
- false
+ false,
+ null
);
short flags = c.flags();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
index 0af7183..1b97663 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
@@ -595,6 +595,170 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
}
/**
+ * @throws Exception If failed.
+ */
+ public void testSerializableLocks() throws Exception {
+ checkSerializableAdd(false);
+
+ checkSerializableAdd(true);
+
+ checkNonSerializableConflict();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ private void checkNonSerializableConflict() throws Exception {
+ GridCacheAdapter<String, String> cache = grid.internalCache();
+
+ UUID nodeId = UUID.randomUUID();
+
+ GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+ GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+ GridCacheMvccCandidate cand1 = mvcc.addLocal(e,
+ nodeId,
+ null,
+ 1,
+ version(1),
+ 0,
+ null,
+ false,
+ true,
+ false,
+ true
+ );
+
+ assertNotNull(cand1);
+
+ GridCacheMvccCandidate cand2 = mvcc.addLocal(e,
+ nodeId,
+ null,
+ 1,
+ version(2),
+ 0,
+ new GridCacheVersion(0, 0, 30, 1),
+ false,
+ true,
+ false,
+ true
+ );
+
+ assertNull(cand2);
+ }
+
+ /**
+ * @param incVer If {@code true} lock version is incremented.
+ * @throws Exception If failed.
+ */
+ private void checkSerializableAdd(boolean incVer) throws Exception {
+ GridCacheAdapter<String, String> cache = grid.internalCache();
+
+ UUID nodeId = UUID.randomUUID();
+
+ GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+ GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+ GridCacheVersion serOrder1 = new GridCacheVersion(0, 0, 10, 1);
+ GridCacheVersion serOrder2 = new GridCacheVersion(0, 0, 20, 1);
+ GridCacheVersion serOrder3 = new GridCacheVersion(0, 0, 15, 1);
+ GridCacheVersion serOrder4 = new GridCacheVersion(0, 0, 30, 1);
+
+ GridCacheVersion ver1 = incVer ? version(1) : version(4);
+ GridCacheVersion ver2 = incVer ? version(2) : version(3);
+ GridCacheVersion ver3 = incVer ? version(3) : version(2);
+ GridCacheVersion ver4 = incVer ? version(4) : version(1);
+
+ GridCacheMvccCandidate cand1 = mvcc.addLocal(e,
+ nodeId,
+ null,
+ 1,
+ ver1,
+ 0,
+ serOrder1,
+ false,
+ true,
+ false,
+ true
+ );
+
+ assertNotNull(cand1);
+
+ GridCacheMvccCandidate cand2 = mvcc.addLocal(e,
+ nodeId,
+ null,
+ 2,
+ ver2,
+ 0,
+ serOrder2,
+ false,
+ true,
+ false,
+ true
+ );
+
+ assertNotNull(cand2);
+
+ GridCacheMvccCandidate cand3 = mvcc.addLocal(e,
+ nodeId,
+ null,
+ 3,
+ ver3,
+ 0,
+ serOrder3,
+ false,
+ true,
+ false,
+ true
+ );
+
+ assertNull(cand3);
+
+ GridCacheMvccCandidate cand4 = mvcc.addLocal(e,
+ nodeId,
+ null,
+ 4,
+ ver4,
+ 0,
+ serOrder4,
+ false,
+ true,
+ false,
+ true
+ );
+
+ assertNotNull(cand4);
+
+ GridCacheMvccCandidate owner = mvcc.recheck();
+
+ assertNull(owner);
+
+ cand2.setReady();
+
+ owner = mvcc.recheck();
+
+ assertNull(owner);
+
+ cand1.setReady();
+
+ owner = mvcc.recheck();
+
+ assertSame(cand1, owner);
+
+ owner = mvcc.recheck();
+
+ assertSame(cand1, owner);
+
+ mvcc.remove(cand1.version());
+
+ owner = mvcc.recheck();
+
+ assertSame(cand2, owner);
+ }
+
+ /**
* Gets version based on order.
*
* @param order Order.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
index cdf8eca..59f9a9d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
@@ -101,7 +101,8 @@ public class GridCacheMvccSelfTest extends GridCommonAbstractTest {
true,
false,
false,
- false
+ false,
+ null
);
Marshaller marshaller = getTestResources().getMarshaller();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
index 1fef4d5..abb2767 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
@@ -33,6 +33,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersionedEnt
import org.apache.ignite.internal.processors.dr.GridDrType;
import org.apache.ignite.internal.util.lang.GridMetadataAwareAdapter;
import org.apache.ignite.internal.util.lang.GridTuple3;
+import org.apache.ignite.internal.util.typedef.T2;
import org.jetbrains.annotations.Nullable;
/**
@@ -441,6 +442,22 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
}
/** @inheritDoc */
+ @Nullable @Override public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+ IgniteInternalTx tx,
+ boolean readSwap,
+ boolean unmarshal,
+ boolean updateMetrics,
+ boolean evt,
+ UUID subjId,
+ Object transformClo,
+ String taskName,
+ @Nullable IgniteCacheExpiryPolicy expiryPlc) {
+ assert false;
+
+ return null;
+ }
+
+ /** @inheritDoc */
@Override public CacheObject innerReload() {
return val;
}
@@ -456,9 +473,14 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
boolean evt,
boolean metrics,
AffinityTopologyVersion topVer,
- CacheEntryPredicate[] filter, GridDrType drType,
- long drExpireTime, @Nullable GridCacheVersion drVer, UUID subjId, String taskName) throws IgniteCheckedException,
- GridCacheEntryRemovedException {
+ CacheEntryPredicate[] filter,
+ GridDrType drType,
+ long drExpireTime,
+ @Nullable GridCacheVersion drVer,
+ UUID subjId,
+ String taskName,
+ @Nullable GridCacheVersion dhtVer)
+ throws IgniteCheckedException, GridCacheEntryRemovedException {
return new GridCacheUpdateTxResult(true, rawPut(val, ttl));
}
@@ -528,8 +550,9 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
GridDrType drType,
@Nullable GridCacheVersion drVer,
UUID subjId,
- String taskName
- ) throws IgniteCheckedException, GridCacheEntryRemovedException {
+ String taskName,
+ @Nullable GridCacheVersion dhtVer
+ ) throws IgniteCheckedException, GridCacheEntryRemovedException {
obsoleteVer = ver;
CacheObject old = val;
@@ -552,7 +575,10 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
}
/** @inheritDoc */
- @Override public boolean tmLock(IgniteInternalTx tx, long timeout) {
+ @Override public boolean tmLock(IgniteInternalTx tx,
+ long timeout,
+ @Nullable GridCacheVersion serOrder,
+ GridCacheVersion serReadVer) {
assert false; return false;
}
@@ -613,6 +639,13 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
}
/** @inheritDoc */
+ @Override public boolean checkSerializableReadVersion(GridCacheVersion ver) {
+ assert false;
+
+ return false;
+ }
+
+ /** @inheritDoc */
@Override public boolean initialValue(
CacheObject val,
GridCacheVersion ver,
@@ -640,8 +673,12 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
}
/** @inheritDoc */
- @Override public boolean versionedValue(CacheObject val, GridCacheVersion curVer, GridCacheVersion newVer) {
- assert false; return false;
+ @Override public GridCacheVersion versionedValue(CacheObject val,
+ GridCacheVersion curVer,
+ GridCacheVersion newVer) {
+ assert false;
+
+ return null;
}
/** @inheritDoc */
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
index fcf46cf..dff0344 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
@@ -175,9 +175,7 @@ abstract class IgniteTxAbstractTest extends GridCommonAbstractTest {
for (int i = 0; i < iterations(); i++) {
IgniteCache<Integer, String> cache = jcache(gridIdx);
- Transaction tx = ignite(gridIdx).transactions().txStart(concurrency, isolation, 0, 0);
-
- try {
+ try (Transaction tx = ignite(gridIdx).transactions().txStart(concurrency, isolation, 0, 0)) {
int prevKey = -1;
for (Integer key : getKeys()) {
@@ -236,46 +234,22 @@ abstract class IgniteTxAbstractTest extends GridCommonAbstractTest {
debug("Committed transaction [i=" + i + ", tx=" + tx + ']');
}
catch (TransactionOptimisticException e) {
- if (concurrency != OPTIMISTIC || isolation != SERIALIZABLE) {
- error("Received invalid optimistic failure.", e);
+ if (!(concurrency == OPTIMISTIC && isolation == SERIALIZABLE)) {
+ log.error("Unexpected error: " + e, e);
throw e;
}
-
- if (isTestDebug())
- info("Optimistic transaction failure (will rollback) [i=" + i + ", msg=" + e.getMessage() +
- ", tx=" + tx.xid() + ']');
-
- try {
- tx.rollback();
- }
- catch (IgniteException ex) {
- error("Failed to rollback optimistic failure: " + tx, ex);
-
- throw ex;
- }
}
- catch (Exception e) {
- error("Transaction failed (will rollback): " + tx, e);
-
- tx.rollback();
+ catch (Throwable e) {
+ log.error("Unexpected error: " + e, e);
throw e;
}
- catch (Error e) {
- error("Error when executing transaction (will rollback): " + tx, e);
-
- tx.rollback();
+ }
- throw e;
- }
- finally {
- Transaction t = ignite(gridIdx).transactions().tx();
+ Transaction tx = ignite(gridIdx).transactions().tx();
- assert t == null : "Thread should not have transaction upon completion ['t==tx'=" + (t == tx) +
- ", t=" + t + (t != tx ? "tx=" + tx : "tx=''") + ']';
- }
- }
+ assertNull("Thread should not have transaction upon completion", tx);
if (printMemoryStats()) {
if (cntr.getAndIncrement() % 100 == 0)
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
index 9e14d30..f13ba8c 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
@@ -219,78 +219,98 @@ public abstract class IgniteTxMultiThreadedAbstractTest extends IgniteTxAbstract
* @throws Exception If failed.
*/
public void testOptimisticSerializableConsistency() throws Exception {
- fail("https://issues.apache.org/jira/browse/IGNITE-582");
-
final IgniteCache<Integer, Long> cache = grid(0).cache(null);
- final int THREADS = 2;
+ final int THREADS = 3;
final int ITERATIONS = 100;
- final int key = 0;
+ for (int key0 = 100_000; key0 < 100_000 + 20; key0++) {
+ final int key = key0;
- cache.put(key, 0L);
+ cache.put(key, 0L);
- List<IgniteInternalFuture<Collection<Long>>> futs = new ArrayList<>(THREADS);
+ List<IgniteInternalFuture<Collection<Long>>> futs = new ArrayList<>(THREADS);
- for (int i = 0; i < THREADS; i++) {
- futs.add(GridTestUtils.runAsync(new Callable<Collection<Long>>() {
- @Override public Collection<Long> call() throws Exception {
- Collection<Long> res = new ArrayList<>();
+ for (int i = 0; i < THREADS; i++) {
+ futs.add(GridTestUtils.runAsync(new Callable<Collection<Long>>() {
+ @Override public Collection<Long> call() throws Exception {
+ Collection<Long> res = new ArrayList<>();
- for (int i = 0; i < ITERATIONS; i++) {
- while (true) {
- try (Transaction tx = grid(0).transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
- long val = cache.get(key);
+ for (int i = 0; i < ITERATIONS; i++) {
+ while (true) {
+ try (Transaction tx = grid(0).transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ long val = cache.get(key);
- cache.put(key, val + 1);
+ cache.put(key, val + 1);
- tx.commit();
+ tx.commit();
- assertTrue(res.add(val + 1));
+ assertTrue(res.add(val + 1));
- break;
- }
- catch(TransactionOptimisticException e) {
- log.info("Got error, will retry: " + e);
+ break;
+ }
+ catch (TransactionOptimisticException e) {
+ // Retry.
+ }
}
}
+
+ return res;
}
+ }));
+ }
- return res;
- }
- }));
- }
+ long total = 0;
- List<Collection<Long>> cols = new ArrayList<>(THREADS);
+ List<Collection<Long>> cols = new ArrayList<>(THREADS);
- for (IgniteInternalFuture<Collection<Long>> fut : futs) {
- Collection<Long> col = fut.get();
+ for (IgniteInternalFuture<Collection<Long>> fut : futs) {
+ Collection<Long> col = fut.get();
- assertEquals(ITERATIONS, col.size());
+ assertEquals(ITERATIONS, col.size());
- cols.add(col);
- }
+ total += col.size();
+
+ cols.add(col);
+ }
+
+ log.info("Cache value: " + cache.get(key));
- Set<Long> duplicates = new HashSet<>();
+ Set<Long> duplicates = new HashSet<>();
- for (Collection<Long> col1 : cols) {
- for (Long val1 : col1) {
- for (Collection<Long> col2 : cols) {
- if (col1 == col2)
- continue;
+ for (Collection<Long> col1 : cols) {
+ for (Long val1 : col1) {
+ for (Collection<Long> col2 : cols) {
+ if (col1 == col2)
+ continue;
- for (Long val2 : col2) {
- if (val1.equals(val2)) {
- duplicates.add(val2);
+ for (Long val2 : col2) {
+ if (val1.equals(val2)) {
+ duplicates.add(val2);
- break;
+ break;
+ }
}
}
}
}
- }
- assertTrue("Found duplicated values: " + duplicates, duplicates.isEmpty());
+ assertTrue("Found duplicated values: " + duplicates, duplicates.isEmpty());
+
+ assertEquals((long)THREADS * ITERATIONS, total);
+
+ // Try to update one more time to make sure cache is in consistent state.
+ try (Transaction tx = grid(0).transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ long val = cache.get(key);
+
+ cache.put(key, val);
+
+ tx.commit();
+ }
+
+ for (int i = 0; i < gridCount(); i++)
+ assertEquals(total, grid(i).cache(null).get(key));
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java
new file mode 100644
index 0000000..ab9dc76
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed;
+
+import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxMultiThreadedSelfTest;
+
+/**
+ *
+ */
+public class GridCachePartitionedNearDisabledTxMultiThreadedSelfTest
+ extends GridCachePartitionedTxMultiThreadedSelfTest {
+ /** {@inheritDoc} */
+ @Override protected boolean nearEnabled() {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
index b6e86f2..cb83798 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
@@ -80,6 +80,7 @@ import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.transactions.Transaction;
import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.jetbrains.annotations.Nullable;
@@ -93,6 +94,7 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
/**
*
@@ -803,6 +805,9 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
TestCommunicationSpi spi = (TestCommunicationSpi)ignite3.configuration().getCommunicationSpi();
+ for (int i = 0; i < 100; i++)
+ primaryCache(i, null).put(i, -1);
+
final Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < 100; i++)
@@ -866,6 +871,150 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
/**
* @throws Exception If failed.
*/
+ public void testOptimisticSerializableTx() throws Exception {
+ optimisticSerializableTx(null);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testOptimisticSerializableTxNearEnabled() throws Exception {
+ optimisticSerializableTx(new NearCacheConfiguration());
+ }
+
+ /**
+ * @param nearCfg Near cache configuration.
+ * @throws Exception If failed.
+ */
+ private void optimisticSerializableTx(NearCacheConfiguration nearCfg) throws Exception {
+ ccfg = new CacheConfiguration();
+
+ ccfg.setCacheMode(PARTITIONED);
+ ccfg.setBackups(1);
+ ccfg.setAtomicityMode(TRANSACTIONAL);
+ ccfg.setWriteSynchronizationMode(FULL_SYNC);
+ ccfg.setRebalanceMode(SYNC);
+ ccfg.setNearConfiguration(nearCfg);
+
+ IgniteEx ignite0 = startGrid(0);
+ IgniteEx ignite1 = startGrid(1);
+
+ client = true;
+
+ final Ignite ignite2 = startGrid(2);
+
+ assertTrue(ignite2.configuration().isClientMode());
+
+ final Map<Integer, Integer> map = new HashMap<>();
+
+ for (int i = 0; i < 100; i++)
+ map.put(i, i);
+
+ TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi();
+
+ spi.blockMessages(GridNearTxPrepareRequest.class, ignite0.localNode().id());
+ spi.blockMessages(GridNearTxPrepareRequest.class, ignite1.localNode().id());
+
+ spi.record(GridNearTxPrepareRequest.class);
+
+ final IgniteCache<Integer, Integer> cache = ignite2.cache(null);
+
+ IgniteInternalFuture<?> putFut = GridTestUtils.runAsync(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ Thread.currentThread().setName("put-thread");
+
+ try (Transaction tx = ignite2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.putAll(map);
+
+ tx.commit();
+ }
+
+ return null;
+ }
+ });
+
+ assertFalse(putFut.isDone());
+
+ client = false;
+
+ IgniteEx ignite3 = startGrid(3);
+
+ log.info("Stop block1.");
+
+ spi.stopBlock();
+
+ putFut.get();
+
+ spi.record(null);
+
+ checkData(map, null, cache, 4);
+
+ List<Object> msgs = spi.recordedMessages();
+
+ for (Object msg : msgs)
+ assertTrue(((GridNearTxPrepareRequest)msg).firstClientRequest());
+
+ assertEquals(5, msgs.size());
+
+ ignite3.close();
+
+ for (int i = 0; i < 100; i++)
+ map.put(i, i + 1);
+
+ spi.blockMessages(GridNearTxPrepareRequest.class, ignite0.localNode().id());
+ spi.blockMessages(GridNearTxPrepareRequest.class, ignite1.localNode().id());
+
+ spi.record(GridNearTxPrepareRequest.class);
+
+ putFut = GridTestUtils.runAsync(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ Thread.currentThread().setName("put-thread");
+
+ try (Transaction tx = ignite2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ for (Map.Entry<Integer, Integer> e : map.entrySet())
+ cache.put(e.getKey(), e.getValue());
+
+ tx.commit();
+ }
+
+ return null;
+ }
+ });
+
+ ignite3 = startGrid(3);
+
+ log.info("Stop block2.");
+
+ spi.stopBlock();
+
+ putFut.get();
+
+ spi.record(null);
+
+ msgs = spi.recordedMessages();
+
+ for (Object msg : msgs)
+ assertTrue(((GridNearTxPrepareRequest)msg).firstClientRequest());
+
+ assertEquals(5, msgs.size());
+
+ checkData(map, null, cache, 4);
+
+ for (int i = 0; i < 100; i++)
+ map.put(i, i + 2);
+
+ try (Transaction tx = ignite2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.putAll(map);
+
+ tx.commit();
+ }
+
+ checkData(map, null, cache, 4);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testLock() throws Exception {
lock(null);
}
@@ -1428,6 +1577,13 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
/**
* @throws Exception If failed.
*/
+ public void testOptimisticSerializableTxPutAllMultinode() throws Exception {
+ multinode(null, TestType.OPTIMISTIC_SERIALIZABLE_TX);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testPessimisticTxPutAllMultinode() throws Exception {
multinode(null, TestType.PESSIMISTIC_TX);
}
@@ -1497,7 +1653,9 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
IgniteCache<Integer, Integer> cache = ignite.cache(null);
- boolean useTx = testType == TestType.OPTIMISTIC_TX || testType == TestType.PESSIMISTIC_TX;
+ boolean useTx = testType == TestType.OPTIMISTIC_TX ||
+ testType == TestType.OPTIMISTIC_SERIALIZABLE_TX ||
+ testType == TestType.PESSIMISTIC_TX;
if (useTx || testType == TestType.LOCK) {
assertEquals(TRANSACTIONAL,
@@ -1532,7 +1690,10 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
TransactionConcurrency concurrency =
testType == TestType.PESSIMISTIC_TX ? PESSIMISTIC : OPTIMISTIC;
- try (Transaction tx = txs.txStart(concurrency, REPEATABLE_READ)) {
+ TransactionIsolation isolation = testType == TestType.OPTIMISTIC_SERIALIZABLE_TX ?
+ SERIALIZABLE : REPEATABLE_READ;
+
+ try (Transaction tx = txs.txStart(concurrency, isolation)) {
cache.putAll(map);
tx.commit();
@@ -1822,6 +1983,8 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
super.sendMessage(msg.get1(), msg.get2());
}
+
+ blockedMsgs.clear();
}
}
}
@@ -1837,6 +2000,9 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
OPTIMISTIC_TX,
/** */
+ OPTIMISTIC_SERIALIZABLE_TX,
+
+ /** */
PESSIMISTIC_TX,
/** */
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
index 8500e97..7fe0138 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
@@ -37,6 +37,7 @@ import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
@@ -58,6 +59,7 @@ import static org.apache.ignite.testframework.GridTestUtils.setMemoryMode;
import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
/**
*
@@ -175,6 +177,13 @@ public class IgniteCacheCrossCacheTxFailoverTest extends GridCommonAbstractTest
/**
* @throws Exception If failed.
*/
+ public void testCrossCacheOptimisticSerializableTxFailover() throws Exception {
+ crossCacheTxFailover(PARTITIONED, true, OPTIMISTIC, SERIALIZABLE, TestMemoryMode.HEAP);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testCrossCacheOptimisticTxFailoverOffheapSwap() throws Exception {
crossCacheTxFailover(PARTITIONED, true, OPTIMISTIC, REPEATABLE_READ, TestMemoryMode.OFFHEAP_EVICT_SWAP);
}
@@ -424,6 +433,11 @@ public class IgniteCacheCrossCacheTxFailoverTest extends GridCommonAbstractTest
@Override public int hashCode() {
return (int)(key ^ (key >>> 32));
}
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(TestKey.class, this);
+ }
}
/**
@@ -446,6 +460,11 @@ public class IgniteCacheCrossCacheTxFailoverTest extends GridCommonAbstractTest
public long value() {
return val;
}
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(TestValue.class, this);
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
index 8645497..8a4609b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
@@ -21,6 +21,7 @@ import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.processors.cache.GridCacheAbstractSelfTest;
@@ -28,6 +29,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteFutureTimeoutException;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
import org.apache.ignite.testframework.GridTestUtils;
/**
@@ -41,6 +43,15 @@ public class IgniteCacheLockFailoverSelfTest extends GridCacheAbstractSelfTest {
}
/** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ ((TcpCommunicationSpi)cfg.getCommunicationSpi()).setSharedMemoryPort(-1);
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
super.afterTest();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
index 3913957..74d2d09 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
@@ -98,7 +98,11 @@ public class GridCacheAtomicInvalidPartitionHandlingSelfTest extends GridCommonA
cfg.setCacheConfiguration(ccfg);
- cfg.setCommunicationSpi(new DelayCommunicationSpi());
+ DelayCommunicationSpi spi = new DelayCommunicationSpi();
+
+ spi.setSharedMemoryPort(-1);
+
+ cfg.setCommunicationSpi(spi);
if (testClientNode() && getTestGridName(0).equals(gridName))
cfg.setClientMode(true);
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
index 9546d61..02aa824 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
@@ -31,6 +31,7 @@ public class GridCacheNearTxExceptionSelfTest extends IgniteTxExceptionAbstractS
return PARTITIONED;
}
+ /** {@inheritDoc} */
@Override public void testTransformBackup(){
fail("https://issues.apache.org/jira/browse/IGNITE-1601");
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
index 6ed25eb..20ee904 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.distributed.near;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
import org.apache.ignite.internal.processors.cache.IgniteTxMultiThreadedAbstractTest;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
@@ -40,11 +41,6 @@ public class GridCachePartitionedTxMultiThreadedSelfTest extends IgniteTxMultiTh
private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
/** {@inheritDoc} */
- @Override public void testOptimisticSerializableCommitMultithreaded() throws Exception {
- fail("https://issues.apache.org/jira/browse/IGNITE-806");
- }
-
- /** {@inheritDoc} */
@SuppressWarnings({"ConstantConditions"})
@Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
IgniteConfiguration c = super.getConfiguration(gridName);
@@ -60,6 +56,8 @@ public class GridCachePartitionedTxMultiThreadedSelfTest extends IgniteTxMultiTh
cc.setWriteSynchronizationMode(FULL_SYNC);
+ cc.setNearConfiguration(nearEnabled() ? new NearCacheConfiguration() : null);
+
c.setCacheConfiguration(cc);
TcpDiscoverySpi disco = new TcpDiscoverySpi();
@@ -74,6 +72,13 @@ public class GridCachePartitionedTxMultiThreadedSelfTest extends IgniteTxMultiTh
return c;
}
+ /**
+ * @return {@code True} if near cache is enabled.
+ */
+ protected boolean nearEnabled() {
+ return true;
+ }
+
/** {@inheritDoc} */
@Override protected int gridCount() {
return 3;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java
new file mode 100644
index 0000000..32e204b
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.datastreamer;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK;
+import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.PRIMARY;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class DataStreamerUpdateAfterLoadTest extends GridCommonAbstractTest {
+ /** */
+ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ private boolean client;
+
+ /** */
+ private static final int NODES = 4;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
+
+ cfg.setClientMode(client);
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGridsMultiThreaded(NODES - 1);
+
+ client = true;
+
+ startGrid(NODES - 1);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ stopAllGrids();
+
+ super.afterTestsStopped();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testUpdateAfterLoad() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ int key = 0;
+
+ try (IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg)) {
+ key = testLoadAndUpdate(cache.getName(), key, false);
+
+ testLoadAndUpdate(cache.getName(), key, true);
+
+ ignite0.destroyCache(cache.getName());
+ }
+ }
+ }
+
+ /**
+ * @param cacheName Cache name.
+ * @param key Key.
+ * @param allowOverwrite Streamer flag.
+ * @return Next key.
+ * @throws Exception If failed.
+ */
+ private int testLoadAndUpdate(String cacheName, int key, boolean allowOverwrite) throws Exception {
+ for (int loadNode = 0; loadNode < NODES; loadNode++) {
+ Ignite loadIgnite = ignite(loadNode);
+
+ for (int updateNode = 0; updateNode < NODES; updateNode++) {
+ try (IgniteDataStreamer<Integer, Integer> streamer = loadIgnite.dataStreamer(cacheName)) {
+ streamer.allowOverwrite(allowOverwrite);
+
+ streamer.addData(key, key);
+ }
+
+ Ignite updateIgnite = ignite(updateNode);
+
+ IgniteCache<Integer, Integer> cache = updateIgnite.cache(cacheName);
+
+ if (allowOverwrite)
+ atomicClockModeDelay(cache);
+
+ updateIgnite.cache(cacheName).put(key, key + 1);
+
+ checkValue(key, key + 1, cacheName);
+
+ key++;
+ }
+ }
+
+ return key;
+ }
+
+ /**
+ * @param key Key.
+ * @param val Value.
+ * @param cacheName Cache name.
+ */
+ private void checkValue(Integer key, Integer val, String cacheName) {
+ for (int i = 0; i < NODES; i++) {
+ IgniteCache<Integer, Integer> cache = ignite(i).cache(cacheName);
+
+ assertEquals("Unexpected value " + i, val, cache.get(key));
+ }
+ }
+
+ /**
+ * @return Cache configurations to test.
+ */
+ private List<CacheConfiguration<Integer, Integer>> cacheConfigurations() {
+ List<CacheConfiguration<Integer, Integer>> ccfgs = new ArrayList<>();
+
+ ccfgs.add(cacheConfiguration(CacheAtomicityMode.ATOMIC, PRIMARY, 1, "cache-" + ccfgs.size()));
+ ccfgs.add(cacheConfiguration(CacheAtomicityMode.ATOMIC, PRIMARY, 0, "cache-" + ccfgs.size()));
+ ccfgs.add(cacheConfiguration(CacheAtomicityMode.ATOMIC, CLOCK, 1, "cache-" + ccfgs.size()));
+ ccfgs.add(cacheConfiguration(CacheAtomicityMode.TRANSACTIONAL, null, 1, "cache-" + ccfgs.size()));
+ ccfgs.add(cacheConfiguration(CacheAtomicityMode.TRANSACTIONAL, null, 0, "cache-" + ccfgs.size()));
+
+ return ccfgs;
+ }
+
+ /**
+ * @param atomicityMode Cache atomicity mode.
+ * @param writeOrderMode Cache write order mode.
+ * @param backups Number of backups.
+ * @param name Cache name.
+ * @return Cache configuration.
+ */
+ private CacheConfiguration<Integer, Integer> cacheConfiguration(CacheAtomicityMode atomicityMode,
+ CacheAtomicWriteOrderMode writeOrderMode,
+ int backups,
+ String name) {
+ CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+
+ ccfg.setName(name);
+ ccfg.setAtomicityMode(atomicityMode);
+ ccfg.setBackups(backups);
+ ccfg.setAtomicWriteOrderMode(writeOrderMode);
+ ccfg.setWriteSynchronizationMode(FULL_SYNC);
+
+ return ccfg;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java b/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
index cf2ff41..a6dfc9c 100644
--- a/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
@@ -26,6 +26,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.testframework.junits.GridTestKernalContext;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.testframework.junits.logger.GridTestLog4jLogger;
+import org.jetbrains.annotations.Nullable;
/**
* Tests hashmap load.
@@ -81,7 +82,10 @@ public class GridHashMapLoadTest extends GridCommonAbstractTest {
map.put(key, new GridCacheMapEntry(ctx, ctx.toCacheKeyObject(key),
key.hashCode(), ctx.toCacheObject(val), null, 1) {
- @Override public boolean tmLock(IgniteInternalTx tx, long timeout) {
+ @Override public boolean tmLock(IgniteInternalTx tx,
+ long timeout,
+ @Nullable GridCacheVersion serOrder,
+ GridCacheVersion serReadVer) {
return false;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java b/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
index cc5226f..f50a732 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
@@ -180,6 +180,14 @@ public class GridTestSwapSpaceSpi extends IgniteSpiAdapter implements SwapSpaceS
}
/**
+ *
+ */
+ public void clearAll() {
+ for (Space space : spaces.values())
+ space.clear();
+ }
+
+ /**
* Gets space, creates if does not exist.
*
* @param spaceName Space name.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
index e4c2129..28d5c73 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
@@ -77,6 +77,8 @@ import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.testframework.junits.GridAbstractTest;
import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
import org.apache.ignite.transactions.TransactionRollbackException;
import org.jetbrains.annotations.Nullable;
@@ -1026,8 +1028,23 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
* @throws Exception If failed.
*/
protected <T> T doInTransaction(Ignite ignite, Callable<T> clo) throws Exception {
+ return doInTransaction(ignite, PESSIMISTIC, REPEATABLE_READ, clo);
+ }
+
+ /**
+ * @param ignite Ignite instance.
+ * @param concurrency Transaction concurrency.
+ * @param isolation Transaction isolation.
+ * @param clo Closure.
+ * @return Result of closure execution.
+ * @throws Exception If failed.
+ */
+ protected <T> T doInTransaction(Ignite ignite,
+ TransactionConcurrency concurrency,
+ TransactionIsolation isolation,
+ Callable<T> clo) throws Exception {
while (true) {
- try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
+ try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
T res = clo.call();
tx.commit();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
index d2904e87..c62a131 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
@@ -122,6 +122,7 @@ import org.apache.ignite.internal.processors.datastreamer.DataStreamProcessorSel
import org.apache.ignite.internal.processors.datastreamer.DataStreamerImplSelfTest;
import org.apache.ignite.internal.processors.datastreamer.DataStreamerMultiThreadedSelfTest;
import org.apache.ignite.internal.processors.datastreamer.DataStreamerMultinodeCreateCacheTest;
+import org.apache.ignite.internal.processors.datastreamer.DataStreamerUpdateAfterLoadTest;
import org.apache.ignite.testframework.GridTestUtils;
/**
@@ -213,7 +214,8 @@ public class IgniteCacheTestSuite extends TestSuite {
suite.addTestSuite(GridCacheAffinityApiSelfTest.class);
suite.addTestSuite(GridCacheStoreValueBytesSelfTest.class);
GridTestUtils.addTestIfNeeded(suite, DataStreamProcessorSelfTest.class, ignoredTests);
- suite.addTestSuite(DataStreamerMultiThreadedSelfTest.class);
+ GridTestUtils.addTestIfNeeded(suite, DataStreamerUpdateAfterLoadTest.class, ignoredTests);
+ suite.addTestSuite(DataStreamerMultiThreadedSelfTest.class);
suite.addTestSuite(DataStreamerMultinodeCreateCacheTest.class);
suite.addTestSuite(DataStreamerImplSelfTest.class);
GridTestUtils.addTestIfNeeded(suite, GridCacheEntryMemorySizeSelfTest.class, ignoredTests);
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
index 93bd26c..5138dac 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
@@ -36,6 +36,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCachePartitionMapUpdate
import org.apache.ignite.internal.processors.cache.IgniteDynamicCacheAndNodeStop;
import org.apache.ignite.internal.processors.cache.distributed.CacheLoadingConcurrentGridStartSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitionNotLoadedEventSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitionedNearDisabledTxMultiThreadedSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.GridCacheTransformEventSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheClientNodeChangingTopologyTest;
import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheClientNodePartitionsExchangeTest;
@@ -190,6 +191,7 @@ public class IgniteCacheTestSuite2 extends TestSuite {
suite.addTest(new TestSuite(GridCacheDhtInternalEntrySelfTest.class));
suite.addTest(new TestSuite(GridCacheDhtMappingSelfTest.class));
suite.addTest(new TestSuite(GridCachePartitionedTxMultiThreadedSelfTest.class));
+ suite.addTest(new TestSuite(GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.class));
suite.addTest(new TestSuite(GridCacheDhtPreloadSelfTest.class));
suite.addTest(new TestSuite(GridCacheDhtPreloadOffHeapSelfTest.class));
suite.addTest(new TestSuite(GridCacheDhtPreloadBigDataSelfTest.class));
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
new file mode 100644
index 0000000..0f86c4c
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.internal.processors.cache.CacheNearReaderUpdateTest;
+import org.apache.ignite.internal.processors.cache.CacheSerializableTransactionsTest;
+
+/**
+ * Test suite.
+ */
+public class IgniteCacheTestSuite5 extends TestSuite {
+ /**
+ * @return IgniteCache test suite.
+ * @throws Exception Thrown in case of the failure.
+ */
+ public static TestSuite suite() throws Exception {
+ TestSuite suite = new TestSuite("IgniteCache Test Suite part 5");
+
+ suite.addTestSuite(CacheSerializableTransactionsTest.class);
+ suite.addTestSuite(CacheNearReaderUpdateTest.class);
+
+ return suite;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/config/benchmark-multicast.properties
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/benchmark-multicast.properties b/modules/yardstick/config/benchmark-multicast.properties
index 82bf766..82fc3f8 100644
--- a/modules/yardstick/config/benchmark-multicast.properties
+++ b/modules/yardstick/config/benchmark-multicast.properties
@@ -86,5 +86,8 @@ CONFIGS="\
-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgnitePutTxOffHeapValuesBenchmark -sn IgniteNode -ds ${ver}tx-put-offheap-val-1-backup,\
-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-offheap-1-backup,\
-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryJoinOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-join-offheap-1-backup,\
--cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryPutOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-put-offheap-1-backup\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryPutOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-put-offheap-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -bs 100 -dn IgnitePutAllBenchmark -sn IgniteNode -ds ${ver}atomic-putAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -bs 100 -dn IgnitePutAllTxBenchmark -sn IgniteNode -ds ${ver}tx-putAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -bs 100 -dn IgnitePutAllSerializableTxBenchmark -sn IgniteNode -ds ${ver}tx-putAllSerializable-1-backup\
"
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java
new file mode 100644
index 0000000..32e7653
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.apache.ignite.yardstick.cache.model.Account;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class IgniteAccountSerializableTxBenchmark extends IgniteAccountTxAbstractBenchmark {
+ /** */
+ private static final int ACCOUNT_NUMBER = 3;
+
+ /** {@inheritDoc} */
+ @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+ Set<Integer> accountIds = new HashSet<>();
+
+ while (accountIds.size() < ACCOUNT_NUMBER)
+ accountIds.add(nextRandom(args.range()));
+
+ while (true) {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Map<Integer, Account> accounts = (Map)cache.getAll(accountIds);
+
+ if (accounts.size() != ACCOUNT_NUMBER)
+ throw new Exception("Failed to find accounts: " + accountIds);
+
+ Integer fromId = accountIds.iterator().next();
+
+ int fromBalance = accounts.get(fromId).balance();
+
+ for (Integer id : accountIds) {
+ if (id.equals(fromId))
+ continue;
+
+ Account account = accounts.get(id);
+
+ if (fromBalance > 0) {
+ fromBalance--;
+
+ cache.put(id, new Account(account.balance() + 1));
+ }
+ }
+
+ cache.put(fromId, new Account(fromBalance));
+
+ tx.commit();
+ }
+ catch (TransactionOptimisticException e) {
+ continue;
+ }
+
+ break;
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java
new file mode 100644
index 0000000..0266a3c
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.yardstick.cache.model.Account;
+import org.yardstickframework.BenchmarkConfiguration;
+
+import static org.yardstickframework.BenchmarkUtils.println;
+
+/**
+ *
+ */
+public abstract class IgniteAccountTxAbstractBenchmark extends IgniteCacheAbstractBenchmark {
+ /** */
+ protected IgniteTransactions txs;
+
+ /** {@inheritDoc} */
+ @Override public void setUp(BenchmarkConfiguration cfg) throws Exception {
+ super.setUp(cfg);
+
+ txs = ignite().transactions();
+
+ println(cfg, "Populating data...");
+
+ long start = System.nanoTime();
+
+ try (IgniteDataStreamer<Integer, Account> dataLdr = ignite().dataStreamer(cache.getName())) {
+ for (int i = 0; i < args.range() && !Thread.currentThread().isInterrupted(); i++) {
+ dataLdr.addData(i, new Account(100_000));
+
+ if (i % 100000 == 0)
+ println(cfg, "Populated accounts: " + i);
+ }
+ }
+
+ println(cfg, "Finished populating data in " + ((System.nanoTime() - start) / 1_000_000) + " ms.");
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteCache<Integer, Object> cache() {
+ return ignite().cache("tx");
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java
new file mode 100644
index 0000000..78e675e
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.yardstick.cache.model.Account;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+
+/**
+ *
+ */
+public class IgniteAccountTxBenchmark extends IgniteAccountTxAbstractBenchmark {
+ /** */
+ private static final int ACCOUNT_NUMBER = 3;
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+ Set<Integer> accountIds = new TreeSet<>();
+
+ while (accountIds.size() < ACCOUNT_NUMBER)
+ accountIds.add(nextRandom(args.range()));
+
+ try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
+ Map<Integer, Account> accounts = (Map)cache.getAll(accountIds);
+
+ if (accounts.size() != ACCOUNT_NUMBER)
+ throw new Exception("Failed to find accounts: " + accountIds);
+
+ Integer fromId = accountIds.iterator().next();
+
+ int fromBalance = accounts.get(fromId).balance();
+
+ for (Integer id : accountIds) {
+ if (id.equals(fromId))
+ continue;
+
+ Account account = accounts.get(id);
+
+ if (fromBalance > 0) {
+ fromBalance--;
+
+ cache.put(id, new Account(account.balance() + 1));
+ }
+ }
+
+ cache.put(fromId, new Account(fromBalance));
+
+ tx.commit();
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
index 1260f9c..22a9eac 100644
--- a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
@@ -88,6 +88,9 @@ public abstract class IgniteCacheAbstractBenchmark extends IgniteAbstractBenchma
/** */
final int max;
+ /** */
+ final ThreadLocalRandom rnd;
+
/**
* @param min Min.
* @param max Max.
@@ -95,13 +98,15 @@ public abstract class IgniteCacheAbstractBenchmark extends IgniteAbstractBenchma
private ThreadRange(int min, int max) {
this.min = min;
this.max = max;
+
+ rnd = ThreadLocalRandom.current();
}
/**
* @return Next random key.
*/
int nextRandom() {
- return ThreadLocalRandom.current().nextInt(min, max);
+ return rnd.nextInt(min, max);
}
}
}
\ No newline at end of file
[18/23] ignite git commit: testUseDefaultSuid fixed
Posted by yz...@apache.org.
testUseDefaultSuid fixed
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c39b6d43
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c39b6d43
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c39b6d43
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: c39b6d43d61c9aab3dcd3240537a487c2e4605ad
Parents: 7f0b3fc
Author: agura <ag...@gridgain.com>
Authored: Wed Oct 28 15:57:10 2015 +0300
Committer: agura <ag...@gridgain.com>
Committed: Wed Oct 28 15:57:10 2015 +0300
----------------------------------------------------------------------
.../apache/ignite/internal/IgniteKernal.java | 69 ++++++++++----------
.../GridDiscoveryManagerAttributesSelfTest.java | 23 ++++---
2 files changed, 50 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/c39b6d43/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 0865119..4820a93 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -17,6 +17,38 @@
package org.apache.ignite.internal;
+import java.io.Externalizable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.management.JMException;
+import javax.management.ObjectName;
import org.apache.ignite.IgniteAtomicLong;
import org.apache.ignite.IgniteAtomicReference;
import org.apache.ignite.IgniteAtomicSequence;
@@ -135,42 +167,10 @@ import org.apache.ignite.spi.IgniteSpi;
import org.apache.ignite.spi.IgniteSpiVersionCheckException;
import org.jetbrains.annotations.Nullable;
-import javax.management.JMException;
-import javax.management.ObjectName;
-import java.io.Externalizable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidObjectException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.text.DateFormat;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Timer;
-import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
import static org.apache.ignite.IgniteSystemProperties.IGNITE_CONFIG_URL;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_DAEMON;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_NO_ASCII;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_STARVATION_CHECK_INTERVAL;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_SUCCESS_FILE;
@@ -1268,7 +1268,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
add(ATTR_BUILD_VER, VER_STR);
add(ATTR_BUILD_DATE, BUILD_TSTAMP_STR);
add(ATTR_MARSHALLER, cfg.getMarshaller().getClass().getName());
- add(ATTR_MARSHALLER_USE_DFLT_SUID, OptimizedMarshaller.USE_DFLT_SUID);
+ add(ATTR_MARSHALLER_USE_DFLT_SUID,
+ getBoolean(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, OptimizedMarshaller.USE_DFLT_SUID));
add(ATTR_USER_NAME, System.getProperty("user.name"));
add(ATTR_GRID_NAME, gridName);
http://git-wip-us.apache.org/repos/asf/ignite/blob/c39b6d43/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
index 6e2c635..3a2f3ba 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
@@ -25,9 +25,9 @@ import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
import static org.apache.ignite.configuration.DeploymentMode.CONTINUOUS;
import static org.apache.ignite.configuration.DeploymentMode.SHARED;
@@ -121,22 +121,29 @@ public abstract class GridDiscoveryManagerAttributesSelfTest extends GridCommonA
* @throws Exception If failed.
*/
public void testUseDefaultSuid() throws Exception {
- doTestUseDefaultSuid(true, false, true);
- doTestUseDefaultSuid(false, true, true);
- doTestUseDefaultSuid(true, true, false);
- doTestUseDefaultSuid(false, false, false);
+ try {
+ doTestUseDefaultSuid(Boolean.TRUE.toString(), Boolean.FALSE.toString(), true);
+ doTestUseDefaultSuid(Boolean.FALSE.toString(), Boolean.TRUE.toString(), true);
+
+ doTestUseDefaultSuid(Boolean.TRUE.toString(), Boolean.TRUE.toString(), false);
+ doTestUseDefaultSuid(Boolean.FALSE.toString(), Boolean.FALSE.toString(), false);
+ }
+ finally {
+ System.setProperty(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID,
+ String.valueOf(OptimizedMarshaller.USE_DFLT_SUID));
+ }
}
/**
* @throws Exception If failed.
*/
- private void doTestUseDefaultSuid(Boolean first, Boolean second, boolean fail) throws Exception {
+ private void doTestUseDefaultSuid(String first, String second, boolean fail) throws Exception {
try {
- GridTestUtils.setFieldValue(null, OptimizedMarshaller.class, "USE_DFLT_SUID", first);
+ System.setProperty(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, first);
startGrid(0);
- GridTestUtils.setFieldValue(null, OptimizedMarshaller.class, "USE_DFLT_SUID", second);
+ System.setProperty(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, second);
try {
startGrid(1);
[02/23] ignite git commit: review
Posted by yz...@apache.org.
review
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/056490d2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/056490d2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/056490d2
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 056490d239c46a3950234ce7ea9afc4b203a00c3
Parents: cb0d432
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Thu Oct 22 13:52:43 2015 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Thu Oct 22 13:52:43 2015 +0300
----------------------------------------------------------------------
.../apache/ignite/stream/mqtt/MqttStreamer.java | 125 ++++++++++---------
.../stream/mqtt/IgniteMqttStreamerTest.java | 71 +++++------
.../mqtt/IgniteMqttStreamerTestSuite.java | 2 -
3 files changed, 102 insertions(+), 96 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/056490d2/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
index 39d8d6e..a075695 100644
--- a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
+++ b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
@@ -74,10 +74,8 @@ import org.eclipse.paho.client.mqttv3.MqttMessage;
* {@link #setConnectOptions(MqttConnectOptions)} setter.
*
* @see <a href="https://github.com/rholder/guava-retrying">guava-retrying library</a>
- *
*/
public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> implements MqttCallback {
-
/** Logger. */
private IgniteLogger log;
@@ -96,8 +94,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
/** The topics to subscribe to, if many. */
private List<String> topics;
- /** The qualities of service to use for multiple topic subscriptions. If specified, it must contain the same
- * number of elements as {@link #topics}. */
+ /**
+ * The qualities of service to use for multiple topic subscriptions. If specified, it must contain the same
+ * number of elements as {@link #topics}.
+ */
private List<Integer> qualitiesOfService;
/** The MQTT client ID (optional). */
@@ -118,8 +118,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
/** If disconnecting forcibly, the timeout. */
private Integer disconnectForciblyTimeout;
- /** The strategy to determine how long to wait between retry attempts. By default, this streamer uses a
- * Fibonacci-based strategy. */
+ /**
+ * The strategy to determine how long to wait between retry attempts. By default, this streamer uses a
+ * Fibonacci-based strategy.
+ */
private WaitStrategy retryWaitStrategy = WaitStrategies.fibonacciWait();
/** The strategy to determine when to stop retrying to (re-)connect. By default, we never stop. */
@@ -149,7 +151,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
if (!stopped)
throw new IgniteException("Attempted to start an already started MQTT Streamer");
- // for simplicity, if these are null initialize to empty lists
+ // For simplicity, if these are null initialize to empty lists.
topics = topics == null ? new ArrayList<String>() : topics;
qualitiesOfService = qualitiesOfService == null ? new ArrayList<Integer>() : qualitiesOfService;
@@ -157,45 +159,47 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
try {
Map<String, Object> logValues = new HashMap<>();
- // parameter validations
+ // Parameter validations.
A.notNull(getStreamer(), "streamer");
A.notNull(getIgnite(), "ignite");
- A.ensure(!(getSingleTupleExtractor() == null && getMultipleTupleExtractor() == null), "tuple extractor missing");
- A.ensure(getSingleTupleExtractor() == null || getMultipleTupleExtractor() == null, "cannot provide " +
- "both single and multiple tuple extractor");
+ A.ensure(!(getSingleTupleExtractor() == null && getMultipleTupleExtractor() == null),
+ "tuple extractor missing");
+ A.ensure(getSingleTupleExtractor() == null || getMultipleTupleExtractor() == null,
+ "cannot provide both single and multiple tuple extractor");
A.notNullOrEmpty(brokerUrl, "broker URL");
- // if the client ID is empty, generate one
+ // If the client ID is empty, generate one.
if (clientId == null || clientId.length() == 0)
clientId = MqttClient.generateClientId();
- // if we have both a single topic and a list of topics (but the list of topic is not of
- // size 1 and == topic, as this would be a case of re-initialization), fail
+ // If we have both a single topic and a list of topics (but the list of topic is not of
+ // size 1 and == topic, as this would be a case of re-initialization), fail.
if (topic != null && topic.length() > 0 && !topics.isEmpty() &&
topics.size() != 1 && !topics.get(0).equals(topic))
- throw new IllegalArgumentException("Cannot specify both a single topic and a list at the same time");
+ throw new IllegalArgumentException("Cannot specify both a single topic and a list at the same time.");
- // same as above but for QoS
+ // Same as above but for QoS.
if (qualityOfService != null && !qualitiesOfService.isEmpty() && qualitiesOfService.size() != 1 &&
!qualitiesOfService.get(0).equals(qualityOfService))
- throw new IllegalArgumentException("Cannot specify both a single QoS and a list at the same time");
+ throw new IllegalArgumentException("Cannot specify both a single QoS and a list at the same time.");
- // Paho API requires disconnect timeout if providing a quiesce timeout and disconnecting forcibly
+ // Paho API requires disconnect timeout if providing a quiesce timeout and disconnecting forcibly.
if (disconnectForcibly && disconnectQuiesceTimeout != null)
A.notNull(disconnectForciblyTimeout, "disconnect timeout cannot be null when disconnecting forcibly " +
"with quiesce");
- // if we have multiple topics
+ // If we have multiple topics.
if (!topics.isEmpty()) {
for (String t : topics)
A.notNullOrEmpty(t, "topic in list of topics");
- A.ensure(qualitiesOfService.isEmpty() || qualitiesOfService.size() == topics.size(), "qualities of " +
- "service must be either empty or have the same size as topics list");
+ A.ensure(qualitiesOfService.isEmpty() || qualitiesOfService.size() == topics.size(),
+ "qualities of service must be either empty or have the same size as topics list");
logValues.put("topics", topics);
}
- else { // just the single topic
+ else {
+ // Just the single topic.
topics.add(topic);
if (qualityOfService != null)
@@ -204,29 +208,29 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
logValues.put("topic", topic);
}
- // finish building log values
+ // Finish building log values.
logValues.put("brokerUrl", brokerUrl);
logValues.put("clientId", clientId);
- // cache log values
+ // Cache log values.
cachedLogValues = "[" + Joiner.on(", ").withKeyValueSeparator("=").join(logValues) + "]";
- // create logger
+ // Create logger.
log = getIgnite().log();
- // create the mqtt client
+ // Create the MQTT client.
if (persistence == null)
client = new MqttClient(brokerUrl, clientId);
else
client = new MqttClient(brokerUrl, clientId, persistence);
- // set this as a callback
+ // Set this as a callback.
client.setCallback(this);
- // set stopped to false, as the connection will start async
+ // Set stopped to false, as the connection will start async.
stopped = false;
- // build retrier
+ // Build retrier.
Retryer<Boolean> retrier = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(new Predicate<Boolean>() {
@Override public boolean apply(Boolean connected) {
@@ -238,29 +242,29 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
.withStopStrategy(retryStopStrategy)
.build();
- // create the connection retrier
+ // Create the connection retrier.
connectionRetrier = new MqttConnectionRetrier(retrier);
log.info("Starting MQTT Streamer " + cachedLogValues);
- // connect
+ // Connect.
connectionRetrier.connect();
-
}
- catch (Throwable t) {
- throw new IgniteException("Exception while initializing MqttStreamer", t);
+ catch (Exception e) {
+ throw new IgniteException("Failed to initialize MQTT Streamer.", e);
}
-
}
/**
* Stops streamer.
+ *
+ * @throws IgniteException If failed.
*/
public void stop() throws IgniteException {
if (stopped)
- throw new IgniteException("Attempted to stop an already stopped MQTT Streamer");
+ throw new IgniteException("Failed to stop MQTT Streamer (already stopped).");
- // stop the retrier
+ // Stop the retrier.
connectionRetrier.stop();
try {
@@ -273,23 +277,22 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
else
client.disconnectForcibly(disconnectQuiesceTimeout, disconnectForciblyTimeout);
-
- } else {
+ }
+ else {
if (disconnectQuiesceTimeout == null)
client.disconnect();
else
client.disconnect(disconnectQuiesceTimeout);
-
}
client.close();
+
connected = false;
stopped = true;
-
}
- catch (Throwable t) {
- throw new IgniteException("Exception while stopping MqttStreamer", t);
+ catch (Exception e) {
+ throw new IgniteException("Failed to stop Exception while stopping MQTT Streamer.", e);
}
}
@@ -502,9 +505,9 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
}
/**
- * Sets whether to disconnect forcibly or not when shutting down. By default, it's <tt>false</tt>.
+ * Sets whether to disconnect forcibly or not when shutting down. By default, it's {@code false}.
*
- * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's <tt>false</tt>.
+ * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's {@code false}.
*/
public void setDisconnectForcibly(boolean disconnectForcibly) {
this.disconnectForcibly = disconnectForcibly;
@@ -593,7 +596,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
}
/**
- * Sets whether to block the start() method until connected for the first time. By default, it's <tt>false</tt>.
+ * Sets whether to block the start() method until connected for the first time. By default, it's {@code false}.
*
* @param blockUntilConnected Whether to block or not.
*/
@@ -601,6 +604,11 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
this.blockUntilConnected = blockUntilConnected;
}
+ /**
+ * Gets whether to block the start() method until connected for the first time. By default, it's {@code false}.
+ *
+ * @return {@code true} if should connect synchronously in start.
+ */
public boolean isBlockUntilConnected() {
return blockUntilConnected;
}
@@ -608,7 +616,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
/**
* Returns whether this streamer is stopped.
*
- * @return <tt>true</tt> if stopped; <tt>false</tt> if not.
+ * @return {@code true} if stopped; {@code false} if not.
*/
public boolean isStopped() {
return stopped;
@@ -617,7 +625,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
/**
* Returns whether this streamer is connected.
*
- * @return <tt>true</tt> if connected; <tt>false</tt> if not.
+ * @return {@code true} if connected; {@code false} if not.
*/
public boolean isConnected() {
return connected;
@@ -628,15 +636,15 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
* the (re-)connections.
*/
private class MqttConnectionRetrier {
-
/** The guava-retrying retrier object. */
private final Retryer<Boolean> retrier;
/** Single-threaded pool. */
- private ExecutorService executor = Executors.newSingleThreadExecutor();
+ private ExecutorService exec = Executors.newSingleThreadExecutor();
/**
* Constructor.
+ *
* @param retrier The retryier object.
*/
public MqttConnectionRetrier(Retryer<Boolean> retrier) {
@@ -649,21 +657,21 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
public void connect() {
Callable<Boolean> callable = retrier.wrap(new Callable<Boolean>() {
@Override public Boolean call() throws Exception {
- // if we're already connected, return immediately
+ // If we're already connected, return immediately.
if (connected)
return true;
if (stopped)
return false;
- // connect to broker
+ // Connect to broker.
if (connectOptions == null)
client.connect();
else
client.connect(connectOptions);
- // always use the multiple topics variant of the mqtt client; even if the user specified a single
- // topic and/or QoS, the initialization code would have placed it inside the 1..n structures
+ // Always use the multiple topics variant of the mqtt client; even if the user specified a single
+ // topic and/or QoS, the initialization code would have placed it inside the 1..n structures.
if (qualitiesOfService.isEmpty())
client.subscribe(topics.toArray(new String[0]));
@@ -679,11 +687,12 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
log.info("MQTT Streamer (re-)connected and subscribed " + cachedLogValues);
connected = true;
- return connected;
+
+ return true;
}
});
- Future<Boolean> result = executor.submit(callable);
+ Future<Boolean> result = exec.submit(callable);
if (blockUntilConnected) {
try {
@@ -699,9 +708,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
* Stops this connection utility class by shutting down the thread pool.
*/
public void stop() {
- executor.shutdownNow();
+ exec.shutdownNow();
}
-
}
-
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/056490d2/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
index 76404b8..6b07fde 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
@@ -60,11 +60,8 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
/**
* Test for {@link MqttStreamer}.
- *
- * @author Raul Kripalani
*/
public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
-
/** The test data. */
private static final Map<Integer, String> TEST_DATA = new HashMap<>();
@@ -106,8 +103,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- *
- * @throws Exception
+ * @throws Exception If failed.
*/
@Before @SuppressWarnings("unchecked")
public void beforeTest() throws Exception {
@@ -154,8 +150,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- *
- * @throws Exception
+ * @throws Exception If failed.
*/
@After
public void afterTest() throws Exception {
@@ -175,7 +170,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testSingleTopic_NoQoS_OneEntryPerMessage() throws Exception {
// configure streamer
@@ -197,7 +192,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testMultipleTopics_NoQoS_OneEntryPerMessage() throws Exception {
// configure streamer
@@ -223,7 +218,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testSingleTopic_NoQoS_MultipleEntriesOneMessage() throws Exception {
// configure streamer
@@ -245,7 +240,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testMultipleTopics_NoQoS_MultipleEntriesOneMessage() throws Exception {
// configure streamer
@@ -271,7 +266,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testSingleTopic_NoQoS_ConnectOptions_Durable() throws Exception {
// configure streamer
@@ -312,7 +307,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testSingleTopic_NoQoS_Reconnect() throws Exception {
// configure streamer
@@ -358,7 +353,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testSingleTopic_NoQoS_RetryOnce() throws Exception {
// configure streamer
@@ -397,7 +392,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testMultipleTopics_MultipleQoS_OneEntryPerMessage() throws Exception {
// configure streamer
@@ -424,7 +419,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @throws Exception If failed.
*/
public void testMultipleTopics_MultipleQoS_Mismatch() throws Exception {
// configure streamer
@@ -443,7 +438,8 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @param dataStreamer Streamer.
+ * @return MQTT streamer.
*/
private MqttStreamer<Integer, String> createMqttStreamer(IgniteDataStreamer<Integer, String> dataStreamer) {
MqttStreamer<Integer, String> streamer = new MqttStreamer<>();
@@ -460,10 +456,15 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @param topics Topics.
+ * @param fromIdx From index.
+ * @param cnt Count.
+ * @param singleMsg Single message flag.
+ * @throws MqttException If failed.
*/
- private void sendMessages(final List<String> topics, int fromIdx, int count, boolean singleMessage) throws MqttException {
- if (singleMessage) {
+ private void sendMessages(final List<String> topics, int fromIdx, int cnt, boolean singleMsg)
+ throws MqttException {
+ if (singleMsg) {
final List<StringBuilder> sbs = new ArrayList<>(topics.size());
// initialize String Builders for each topic
@@ -474,7 +475,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
});
// fill String Builders for each topic
- F.forEach(F.range(fromIdx, fromIdx + count), new IgniteInClosure<Integer>() {
+ F.forEach(F.range(fromIdx, fromIdx + cnt), new IgniteInClosure<Integer>() {
@Override public void apply(Integer integer) {
sbs.get(integer % topics.size()).append(integer.toString() + "," + TEST_DATA.get(integer) + "\n");
}
@@ -488,7 +489,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
}
else {
- for (int i = fromIdx; i < fromIdx + count; i++) {
+ for (int i = fromIdx; i < fromIdx + cnt; i++) {
byte[] payload = (i + "," + TEST_DATA.get(i)).getBytes();
MqttMessage msg = new MqttMessage(payload);
@@ -499,14 +500,16 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception
+ * @param expect Expected count.
+ * @return Latch to be counted down in listener.
*/
private CountDownLatch subscribeToPutEvents(int expect) {
Ignite ignite = grid();
// Listen to cache PUT events and expect as many as messages as test data items
final CountDownLatch latch = new CountDownLatch(expect);
- @SuppressWarnings("serial") IgniteBiPredicate<UUID, CacheEvent> callback = new IgniteBiPredicate<UUID, CacheEvent>() {
+
+ IgniteBiPredicate<UUID, CacheEvent> callback = new IgniteBiPredicate<UUID, CacheEvent>() {
@Override public boolean apply(UUID uuid, CacheEvent evt) {
latch.countDown();
@@ -514,32 +517,32 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
};
- remoteListener = ignite.events(ignite.cluster().forCacheNodes(null)).remoteListen(callback, null, EVT_CACHE_OBJECT_PUT);
+ remoteListener = ignite.events(ignite.cluster().forCacheNodes(null))
+ .remoteListen(callback, null, EVT_CACHE_OBJECT_PUT);
+
return latch;
}
/**
- * @throws Exception
+ * @param cnt Count.
*/
- private void assertCacheEntriesLoaded(int count) {
+ private void assertCacheEntriesLoaded(int cnt) {
// get the cache and check that the entries are present
IgniteCache<Integer, String> cache = grid().cache(null);
// for each key from 0 to count from the TEST_DATA (ordered by key), check that the entry is present in cache
- for (Integer key : new ArrayList<>(new TreeSet<>(TEST_DATA.keySet())).subList(0, count))
+ for (Integer key : new ArrayList<>(new TreeSet<>(TEST_DATA.keySet())).subList(0, cnt))
assertEquals(TEST_DATA.get(key), cache.get(key));
// assert that the cache exactly the specified amount of elements
- assertEquals(count, cache.size(CachePeekMode.ALL));
+ assertEquals(cnt, cache.size(CachePeekMode.ALL));
// remove the event listener
grid().events(grid().cluster().forCacheNodes(null)).stopRemoteListen(remoteListener);
}
/**
- * Returns a {@link StreamSingleTupleExtractor} for testing.
- *
- * @throws Exception
+ * @return {@link StreamSingleTupleExtractor} for testing.
*/
public static StreamSingleTupleExtractor<MqttMessage, Integer, String> singleTupleExtractor() {
return new StreamSingleTupleExtractor<MqttMessage, Integer, String>() {
@@ -552,9 +555,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * Returns a {@link StreamMultipleTupleExtractor} for testing.
- *
- * @throws Exception
+ * @return {@link StreamMultipleTupleExtractor} for testing.
*/
public static StreamMultipleTupleExtractor<MqttMessage, Integer, String> multipleTupleExtractor() {
return new StreamMultipleTupleExtractor<MqttMessage, Integer, String>() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/056490d2/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
index 413eaab..ed0c2f7 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
@@ -22,8 +22,6 @@ import org.junit.runners.Suite;
/**
* MQTT streamer tests.
- *
- * @author Raul Kripalani
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
[20/23] ignite git commit: Merge remote-tracking branch
'origin/master'
Posted by yz...@apache.org.
Merge remote-tracking branch 'origin/master'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2a7d8865
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2a7d8865
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2a7d8865
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 2a7d886553a967b330342d7b6734a256ce890946
Parents: a5d50a6 c39b6d4
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Oct 28 17:11:30 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Oct 28 17:11:30 2015 +0300
----------------------------------------------------------------------
.../ClientAbstractMultiThreadedSelfTest.java | 3 +-
.../apache/ignite/IgniteSystemProperties.java | 9 +
.../affinity/fair/FairAffinityFunction.java | 497 +-
.../rendezvous/RendezvousAffinityFunction.java | 140 +-
.../configuration/TransactionConfiguration.java | 6 +-
.../apache/ignite/internal/IgniteKernal.java | 69 +-
.../ignite/internal/IgniteNodeAttributes.java | 3 +
.../processors/cache/CacheMetricsImpl.java | 12 +-
.../processors/cache/GridCacheAdapter.java | 459 +-
.../processors/cache/GridCacheEntryEx.java | 62 +-
.../processors/cache/GridCacheMapEntry.java | 137 +-
.../processors/cache/GridCacheMvcc.java | 143 +-
.../cache/GridCacheMvccCandidate.java | 26 +-
.../processors/cache/GridCacheProcessor.java | 26 -
.../processors/cache/GridCacheUtils.java | 50 +
.../distributed/GridDistributedCacheEntry.java | 12 +-
.../GridDistributedTxRemoteAdapter.java | 56 +-
.../dht/CacheDistributedGetFutureAdapter.java | 158 +
.../distributed/dht/GridDhtCacheAdapter.java | 17 +-
.../distributed/dht/GridDhtCacheEntry.java | 23 +-
.../cache/distributed/dht/GridDhtGetFuture.java | 199 +-
.../distributed/dht/GridDhtLockFuture.java | 5 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 105 +-
.../cache/distributed/dht/GridDhtTxLocal.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 109 +-
.../dht/GridPartitionedGetFuture.java | 179 +-
.../dht/atomic/GridDhtAtomicCache.java | 16 +-
.../dht/colocated/GridDhtColocatedCache.java | 130 +-
.../colocated/GridDhtColocatedLockFuture.java | 6 +-
.../distributed/near/GridNearAtomicCache.java | 2 -
.../distributed/near/GridNearCacheAdapter.java | 32 +-
.../distributed/near/GridNearCacheEntry.java | 81 +-
.../distributed/near/GridNearGetFuture.java | 340 +-
.../distributed/near/GridNearGetRequest.java | 3 -
...arOptimisticSerializableTxPrepareFuture.java | 930 ++++
.../near/GridNearOptimisticTxPrepareFuture.java | 252 +-
...ridNearOptimisticTxPrepareFutureAdapter.java | 222 +
.../GridNearPessimisticTxPrepareFuture.java | 8 +-
.../near/GridNearTransactionalCache.java | 14 +-
.../near/GridNearTxFinishFuture.java | 12 +-
.../cache/distributed/near/GridNearTxLocal.java | 157 +-
.../near/GridNearTxPrepareFutureAdapter.java | 13 +-
.../cache/local/GridLocalCacheEntry.java | 23 +-
.../cache/local/GridLocalLockFuture.java | 2 +
.../local/atomic/GridLocalAtomicCache.java | 9 -
.../continuous/CacheContinuousQueryManager.java | 6 +-
.../transactions/IgniteTransactionsImpl.java | 6 -
.../cache/transactions/IgniteTxAdapter.java | 123 +-
.../cache/transactions/IgniteTxEntry.java | 51 +-
.../cache/transactions/IgniteTxHandler.java | 4 +-
.../transactions/IgniteTxLocalAdapter.java | 832 ++--
.../cache/transactions/IgniteTxLocalEx.java | 27 +-
.../cache/transactions/IgniteTxManager.java | 327 +-
.../cache/version/GridCacheVersionManager.java | 73 +-
.../datastreamer/DataStreamerImpl.java | 2 +-
.../ignite/internal/util/lang/GridFunc.java | 8 +-
.../optimized/OptimizedMarshaller.java | 10 +-
.../optimized/OptimizedMarshallerUtils.java | 35 +-
.../ignite/spi/discovery/tcp/ServerImpl.java | 52 +
.../apache/ignite/transactions/Transaction.java | 2 +-
.../transactions/TransactionIsolation.java | 3 +-
.../AbstractAffinityFunctionSelfTest.java | 293 ++
.../affinity/AffinityClientNodeSelfTest.java | 194 +
...ityFunctionBackupFilterAbstractSelfTest.java | 138 +
...unctionExcludeNeighborsAbstractSelfTest.java | 182 +
.../affinity/IgniteClientNodeAffinityTest.java | 194 -
.../fair/FairAffinityDynamicCacheSelfTest.java | 99 +
...airAffinityFunctionBackupFilterSelfTest.java | 35 +
...ffinityFunctionExcludeNeighborsSelfTest.java | 31 +
.../fair/FairAffinityFunctionNodesSelfTest.java | 245 +
.../fair/FairAffinityFunctionSelfTest.java | 31 +
.../GridFairAffinityFunctionNodesSelfTest.java | 245 -
.../fair/GridFairAffinityFunctionSelfTest.java | 270 --
.../IgniteFairAffinityDynamicCacheSelfTest.java | 99 -
...ousAffinityFunctionBackupFilterSelfTest.java | 35 +
...ffinityFunctionExcludeNeighborsSelfTest.java | 32 +
.../RendezvousAffinityFunctionSelfTest.java | 50 +
.../GridDiscoveryManagerAttributesSelfTest.java | 51 +-
.../cache/CacheNearReaderUpdateTest.java | 388 ++
.../CacheSerializableTransactionsTest.java | 4295 ++++++++++++++++++
.../cache/CrossCacheTxRandomOperationsTest.java | 8 +-
.../GridCacheAbstractFailoverSelfTest.java | 14 +-
.../cache/GridCacheAbstractFullApiSelfTest.java | 4 +-
.../GridCacheAbstractLocalStoreSelfTest.java | 5 +
.../GridCacheAbstractRemoveFailureTest.java | 94 +-
.../GridCacheConcurrentTxMultiNodeTest.java | 3 -
...idCacheConfigurationConsistencySelfTest.java | 17 -
.../cache/GridCacheMvccFlagsTest.java | 6 +-
.../cache/GridCacheMvccPartitionedSelfTest.java | 164 +
.../processors/cache/GridCacheMvccSelfTest.java | 3 +-
.../processors/cache/GridCacheTestEntryEx.java | 53 +-
.../cache/IgniteCacheCreateRestartSelfTest.java | 2 +
.../processors/cache/IgniteTxAbstractTest.java | 42 +-
.../IgniteTxMultiThreadedAbstractTest.java | 106 +-
...IgnitePartitionedCountDownLatchSelfTest.java | 7 +-
...dCachePartitionedAffinityFilterSelfTest.java | 143 -
...onedNearDisabledTxMultiThreadedSelfTest.java | 31 +
...niteCacheClientNodeChangingTopologyTest.java | 170 +-
.../dht/GridCacheDhtPreloadPutGetSelfTest.java | 3 +
.../IgniteCacheCrossCacheTxFailoverTest.java | 19 +
.../dht/IgniteCacheLockFailoverSelfTest.java | 11 +
...eAtomicInvalidPartitionHandlingSelfTest.java | 6 +-
...unctionExcludeNeighborsAbstractSelfTest.java | 184 -
.../near/GridCacheNearTxExceptionSelfTest.java | 1 +
...CachePartitionedTxMultiThreadedSelfTest.java | 15 +-
...ffinityFunctionExcludeNeighborsSelfTest.java | 32 -
...xcludeNeighborsMultiNodeFullApiSelfTest.java | 36 +
...tedFairAffinityMultiNodeFullApiSelfTest.java | 35 +
...xcludeNeighborsMultiNodeFullApiSelfTest.java | 36 +
...dezvousAffinityMultiNodeFullApiSelfTest.java | 36 +
.../DataStreamerUpdateAfterLoadTest.java | 184 +
.../loadtests/hashmap/GridHashMapLoadTest.java | 6 +-
.../inmemory/GridTestSwapSpaceSpi.java | 8 +
.../ignite/testframework/GridTestUtils.java | 19 +-
.../junits/common/GridCommonAbstractTest.java | 19 +-
.../IgniteCacheFullApiSelfTestSuite.java | 8 +
.../ignite/testsuites/IgniteCacheTestSuite.java | 20 +-
.../testsuites/IgniteCacheTestSuite2.java | 14 +-
.../testsuites/IgniteCacheTestSuite5.java | 40 +
.../cache/IgniteCacheAbstractQuerySelfTest.java | 4 +
modules/jms11/pom.xml | 9 +-
.../stream/jms11/IgniteJmsStreamerTest.java | 9 +-
.../apache/ignite/stream/mqtt/MqttStreamer.java | 386 +-
.../stream/mqtt/IgniteMqttStreamerTest.java | 142 +-
.../mqtt/IgniteMqttStreamerTestSuite.java | 4 +-
.../config/benchmark-multicast.properties | 5 +-
.../IgniteAccountSerializableTxBenchmark.java | 81 +
.../cache/IgniteAccountTxAbstractBenchmark.java | 61 +
.../cache/IgniteAccountTxBenchmark.java | 74 +
.../cache/IgniteCacheAbstractBenchmark.java | 7 +-
.../IgnitePutAllSerializableTxBenchmark.java | 77 +
.../ignite/yardstick/cache/model/Account.java | 42 +
132 files changed, 11827 insertions(+), 3907 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/2a7d8865/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
index 0000000,0b32320..ef67495
mode 000000,100644..100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
@@@ -1,0 -1,97 +1,99 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ package org.apache.ignite.cache.affinity.fair;
+
+ import java.util.concurrent.Callable;
+ import org.apache.ignite.IgniteCache;
+ import org.apache.ignite.cache.CacheAtomicityMode;
+ import org.apache.ignite.cache.CacheMode;
+ import org.apache.ignite.configuration.CacheConfiguration;
+ import org.apache.ignite.configuration.IgniteConfiguration;
+ import org.apache.ignite.internal.IgniteInternalFuture;
+ import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+ import org.apache.ignite.testframework.GridTestUtils;
+ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+ /**
+ *
+ */
+ public class FairAffinityDynamicCacheSelfTest extends GridCommonAbstractTest {
+ /** */
+ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ public FairAffinityDynamicCacheSelfTest(){
+ super(false);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+ disco.setIpFinder(IP_FINDER);
+
+ cfg.getTransactionConfiguration().setTxSerializableEnabled(true);
+
+ cfg.setDiscoverySpi(disco);
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ startGridsMultiThreaded(3);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ stopAllGrids();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testStartStopCache() throws Exception {
++ fail("https://issues.apache.org/jira/browse/IGNITE-647");
++
+ CacheConfiguration<Integer, Integer> cacheCfg = new CacheConfiguration<>();
+
+ cacheCfg.setCacheMode(CacheMode.PARTITIONED);
+ cacheCfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
+ cacheCfg.setBackups(1);
+ cacheCfg.setName("test");
+ cacheCfg.setAffinity(new FairAffinityFunction());
+
+ final IgniteCache<Integer, Integer> cache = ignite(0).createCache(cacheCfg);
+
+ for (int i = 0; i < 10_000; i++)
+ cache.put(i, i);
+
+ IgniteInternalFuture<Object> destFut = GridTestUtils.runAsync(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ ignite(0).destroyCache(cache.getName());
+
+ return null;
+ }
+ });
+
+ destFut.get(2000L);
+ }
+ }
[19/23] ignite git commit: Muted test
Posted by yz...@apache.org.
Muted test
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a5d50a60
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a5d50a60
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a5d50a60
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: a5d50a60025559435673a066d61799d1aafe3b29
Parents: df931bd
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Oct 28 17:10:55 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Oct 28 17:10:55 2015 +0300
----------------------------------------------------------------------
.../affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/a5d50a60/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java
index eb1c455..f95265d 100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java
@@ -71,6 +71,8 @@ public class IgniteFairAffinityDynamicCacheSelfTest extends GridCommonAbstractTe
* @throws Exception If failed.
*/
public void testStartStopCache() throws Exception {
+ fail("https://issues.apache.org/jira/browse/IGNITE-647");
+
CacheConfiguration<Integer, Integer> cacheCfg = new CacheConfiguration<>();
cacheCfg.setCacheMode(CacheMode.PARTITIONED);
[10/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index 4074eee..c1e9202 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -25,12 +25,10 @@ import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteClientDisconnectedException;
@@ -64,7 +62,6 @@ import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.GridBoundedConcurrentOrderedMap;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.lang.GridFunc;
import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.X;
@@ -78,7 +75,6 @@ import org.apache.ignite.transactions.TransactionIsolation;
import org.apache.ignite.transactions.TransactionState;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
-import org.jsr166.ConcurrentLinkedDeque8;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_MAX_COMPLETED_TX_COUNT;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_SLOW_TX_WARN_TIMEOUT;
@@ -131,16 +127,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
/** TX handler. */
private IgniteTxHandler txHandler;
- /** All transactions. */
- private final Queue<IgniteInternalTx> committedQ = new ConcurrentLinkedDeque8<>();
-
- /** Preparing transactions. */
- private final Queue<IgniteInternalTx> prepareQ = new ConcurrentLinkedDeque8<>();
-
- /** Minimum start version. */
- private final ConcurrentNavigableMap<GridCacheVersion, AtomicInt> startVerCnts =
- new ConcurrentSkipListMap<>();
-
/** Committed local transactions. */
private final GridBoundedConcurrentOrderedMap<GridCacheVersion, Boolean> completedVers =
new GridBoundedConcurrentOrderedMap<>(Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT));
@@ -308,41 +294,10 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
* USE ONLY FOR MEMORY PROFILING DURING TESTS.
*/
@Override public void printMemoryStats() {
- IgniteInternalTx firstTx = committedQ.peek();
-
- int committedSize = committedQ.size();
-
- Map.Entry<GridCacheVersion, AtomicInt> startVerEntry = startVerCnts.firstEntry();
-
- GridCacheVersion minStartVer = null;
- long dur = 0;
-
- if (committedSize > 3000) {
- minStartVer = new GridCacheVersion(Integer.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Integer.MAX_VALUE, 0);
-
- IgniteInternalTx stuck = null;
-
- for (IgniteInternalTx tx : txs())
- if (tx.startVersion().isLess(minStartVer)) {
- minStartVer = tx.startVersion();
- dur = U.currentTimeMillis() - tx.startTime();
-
- stuck = tx;
- }
-
- X.println("Stuck transaction: " + stuck);
- }
-
X.println(">>> ");
X.println(">>> Transaction manager memory stats [grid=" + cctx.gridName() + ']');
X.println(">>> threadMapSize: " + threadMap.size());
- X.println(">>> idMap [size=" + idMap.size() + ", minStartVer=" + minStartVer + ", dur=" + dur + "ms]");
- X.println(">>> committedQueue [size=" + committedSize +
- ", firstStartVersion=" + (firstTx == null ? "null" : firstTx.startVersion()) +
- ", firstEndVersion=" + (firstTx == null ? "null" : firstTx.endVersion()) + ']');
- X.println(">>> prepareQueueSize: " + prepareQ.size());
- X.println(">>> startVerCntsSize [size=" + startVerCnts.size() +
- ", firstVer=" + startVerEntry + ']');
+ X.println(">>> idMap [size=" + idMap.size() + ']');
X.println(">>> completedVersSize: " + completedVers.size());
}
@@ -361,27 +316,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
}
/**
- * @return Committed queue size.
- */
- public int commitQueueSize() {
- return committedQ.size();
- }
-
- /**
- * @return Prepare queue size.
- */
- public int prepareQueueSize() {
- return prepareQ.size();
- }
-
- /**
- * @return Start version counts.
- */
- public int startVersionCountsSize() {
- return startVerCnts.size();
- }
-
- /**
* @return Committed versions size.
*/
public int completedVersionsSize() {
@@ -493,42 +427,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
return null;
}
- if (cctx.txConfig().isTxSerializableEnabled()) {
- AtomicInt next = new AtomicInt(1);
-
- boolean loop = true;
-
- while (loop) {
- AtomicInt prev = startVerCnts.putIfAbsent(tx.startVersion(), next);
-
- if (prev == null)
- break; // Put succeeded - exit.
-
- // Previous value was 0, which means that it will be deleted
- // by another thread in "decrementStartVersionCount(..)" method.
- // In that case, we delete here too, so we can safely try again.
- for (;;) {
- int p = prev.get();
-
- assert p >= 0 : p;
-
- if (p == 0) {
- if (startVerCnts.remove(tx.startVersion(), prev))
- if (log.isDebugEnabled())
- log.debug("Removed count from onCreated callback: " + tx);
-
- break; // Retry outer loop.
- }
-
- if (prev.compareAndSet(p, p + 1)) {
- loop = false; // Increment succeeded - exit outer loop.
-
- break;
- }
- }
- }
- }
-
if (tx.timeout() > 0) {
cctx.time().addTimeoutObject(tx);
@@ -822,117 +720,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
throw new IgniteTxTimeoutCheckedException("Transaction timed out: " + this);
}
- boolean txSerEnabled = cctx.txConfig().isTxSerializableEnabled();
-
- // Clean up committed transactions queue.
- if (tx.pessimistic() && tx.local()) {
- if (tx.enforceSerializable() && txSerEnabled) {
- for (Iterator<IgniteInternalTx> it = committedQ.iterator(); it.hasNext();) {
- IgniteInternalTx committedTx = it.next();
-
- assert committedTx != tx;
-
- // Clean up.
- if (isSafeToForget(committedTx))
- it.remove();
- }
- }
-
- // Nothing else to do in pessimistic mode.
- return;
- }
-
- if (txSerEnabled && tx.optimistic() && tx.enforceSerializable()) {
- Set<IgniteTxKey> readSet = tx.readSet();
- Set<IgniteTxKey> writeSet = tx.writeSet();
-
- GridCacheVersion startTn = tx.startVersion();
-
- GridCacheVersion finishTn = cctx.versions().last();
-
- // Add future to prepare queue only on first prepare call.
- if (tx.markPreparing())
- prepareQ.offer(tx);
-
- // Check that our read set does not intersect with write set
- // of all transactions that completed their write phase
- // while our transaction was in read phase.
- for (Iterator<IgniteInternalTx> it = committedQ.iterator(); it.hasNext();) {
- IgniteInternalTx committedTx = it.next();
-
- assert committedTx != tx;
-
- // Clean up.
- if (isSafeToForget(committedTx)) {
- it.remove();
-
- continue;
- }
-
- GridCacheVersion tn = committedTx.endVersion();
-
- // We only care about transactions
- // with tn > startTn and tn <= finishTn
- if (tn.compareTo(startTn) <= 0 || tn.compareTo(finishTn) > 0)
- continue;
-
- if (tx.serializable()) {
- if (GridFunc.intersects(committedTx.writeSet(), readSet)) {
- tx.setRollbackOnly();
-
- throw new IgniteTxOptimisticCheckedException("Failed to prepare transaction " +
- "(committed vs. read-set conflict): " + tx);
- }
- }
- }
-
- // Check that our read and write sets do not intersect with write
- // sets of all active transactions.
- for (Iterator<IgniteInternalTx> iter = prepareQ.iterator(); iter.hasNext();) {
- IgniteInternalTx prepareTx = iter.next();
-
- if (prepareTx == tx)
- // Skip yourself.
- continue;
-
- // Optimistically remove completed transactions.
- if (prepareTx.done()) {
- iter.remove();
-
- if (log.isDebugEnabled())
- log.debug("Removed finished transaction from active queue: " + prepareTx);
-
- continue;
- }
-
- // Check if originating node left.
- if (cctx.discovery().node(prepareTx.nodeId()) == null) {
- iter.remove();
-
- rollbackTx(prepareTx);
-
- if (log.isDebugEnabled())
- log.debug("Removed and rolled back transaction because sender node left grid: " +
- CU.txString(prepareTx));
-
- continue;
- }
-
- if (tx.serializable() && !prepareTx.isRollbackOnly()) {
- Set<IgniteTxKey> prepareWriteSet = prepareTx.writeSet();
-
- if (GridFunc.intersects(prepareWriteSet, readSet, writeSet)) {
- // Remove from active set.
- iter.remove();
-
- tx.setRollbackOnly();
-
- throw new IgniteTxOptimisticCheckedException(
- "Failed to prepare transaction (read-set/write-set conflict): " + tx);
- }
- }
- }
- }
+ if (tx.pessimistic() && tx.local())
+ return; // Nothing else to do in pessimistic mode.
// Optimistic.
assert tx.optimistic() || !tx.local();
@@ -945,40 +734,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
}
/**
- * @param tx Transaction to check.
- * @return {@code True} if transaction can be discarded.
- */
- private boolean isSafeToForget(IgniteInternalTx tx) {
- Map.Entry<GridCacheVersion, AtomicInt> e = startVerCnts.firstEntry();
-
- if (e == null)
- return true;
-
- assert e.getValue().get() >= 0;
-
- return tx.endVersion().compareTo(e.getKey()) <= 0;
- }
-
- /**
- * Decrement start version count.
- *
- * @param tx Cache transaction.
- */
- private void decrementStartVersionCount(IgniteInternalTx tx) {
- AtomicInt cnt = startVerCnts.get(tx.startVersion());
-
- assert cnt != null : "Failed to find start version count for transaction [startVerCnts=" + startVerCnts +
- ", tx=" + tx + ']';
-
- assert cnt.get() > 0;
-
- if (cnt.decrementAndGet() == 0)
- if (startVerCnts.remove(tx.startVersion(), cnt))
- if (log.isDebugEnabled())
- log.debug("Removed start version for transaction: " + tx);
- }
-
- /**
* @param tx Transaction.
*/
private void removeObsolete(IgniteInternalTx tx) {
@@ -1237,6 +992,17 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
}
/**
+ * @param tx Transaction.
+ * @return {@code True} if transaction read entries should be unlocked.
+ */
+ private boolean unlockReadEntries(IgniteInternalTx tx) {
+ if (tx.pessimistic())
+ return !tx.readCommitted();
+ else
+ return tx.serializable();
+ }
+
+ /**
* Commits a transaction.
*
* @param tx Transaction to commit.
@@ -1290,8 +1056,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
// 4. Unlock write resources.
unlockMultiple(tx, tx.writeEntries());
- // 5. For pessimistic transaction, unlock read resources if required.
- if (tx.pessimistic() && !tx.readCommitted())
+ // 5. Unlock read resources if required.
+ if (unlockReadEntries(tx))
unlockMultiple(tx, tx.readEntries());
// 6. Notify evictions.
@@ -1303,25 +1069,16 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
// 8. Assign transaction number at the end of transaction.
tx.endVersion(cctx.versions().next(tx.topologyVersion()));
- // 9. Clean start transaction number for this transaction.
- if (cctx.txConfig().isTxSerializableEnabled())
- decrementStartVersionCount(tx);
-
- // 10. Add to committed queue only if it is possible
- // that this transaction can affect other ones.
- if (cctx.txConfig().isTxSerializableEnabled() && tx.enforceSerializable() && !isSafeToForget(tx))
- committedQ.add(tx);
-
- // 11. Remove from per-thread storage.
+ // 9. Remove from per-thread storage.
clearThreadMap(tx);
- // 12. Unregister explicit locks.
+ // 10. Unregister explicit locks.
if (!tx.alternateVersions().isEmpty()) {
for (GridCacheVersion ver : tx.alternateVersions())
idMap.remove(ver);
}
- // 13. Remove Near-2-DHT mappings.
+ // 11. Remove Near-2-DHT mappings.
if (tx instanceof GridCacheMappedVersion) {
GridCacheVersion mapped = ((GridCacheMappedVersion)tx).mappedVersion();
@@ -1329,10 +1086,10 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
mappedVers.remove(mapped);
}
- // 14. Clear context.
+ // 12. Clear context.
resetContext();
- // 15. Update metrics.
+ // 14. Update metrics.
if (!tx.dht() && tx.local()) {
if (!tx.system())
cctx.txMetrics().onTxCommit();
@@ -1378,8 +1135,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
// 2. Unlock write resources.
unlockMultiple(tx, tx.writeEntries());
- // 3. For pessimistic transaction, unlock read resources if required.
- if (tx.pessimistic() && !tx.readCommitted())
+ // 3. Unlock read resources if required.
+ if (unlockReadEntries(tx))
unlockMultiple(tx, tx.readEntries());
// 4. Notify evictions.
@@ -1388,26 +1145,22 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
// 5. Remove obsolete entries.
removeObsolete(tx);
- // 6. Clean start transaction number for this transaction.
- if (cctx.txConfig().isTxSerializableEnabled())
- decrementStartVersionCount(tx);
-
- // 7. Remove from per-thread storage.
+ // 6. Remove from per-thread storage.
clearThreadMap(tx);
- // 8. Unregister explicit locks.
+ // 7. Unregister explicit locks.
if (!tx.alternateVersions().isEmpty())
for (GridCacheVersion ver : tx.alternateVersions())
idMap.remove(ver);
- // 9. Remove Near-2-DHT mappings.
+ // 8. Remove Near-2-DHT mappings.
if (tx instanceof GridCacheMappedVersion)
mappedVers.remove(((GridCacheMappedVersion)tx).mappedVersion());
- // 10. Clear context.
+ // 9. Clear context.
resetContext();
- // 11. Update metrics.
+ // 10. Update metrics.
if (!tx.dht() && tx.local()) {
if (!tx.system())
cctx.txMetrics().onTxRollback();
@@ -1445,30 +1198,26 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
// 1. Unlock write resources.
unlockMultiple(tx, tx.writeEntries());
- // 2. For pessimistic transaction, unlock read resources if required.
- if (tx.pessimistic() && !tx.readCommitted())
+ // 2. Unlock read resources if required.
+ if (unlockReadEntries(tx))
unlockMultiple(tx, tx.readEntries());
// 3. Notify evictions.
notifyEvitions(tx);
- // 4. Clean start transaction number for this transaction.
- if (cctx.txConfig().isTxSerializableEnabled())
- decrementStartVersionCount(tx);
-
- // 5. Remove from per-thread storage.
+ // 4. Remove from per-thread storage.
clearThreadMap(tx);
- // 6. Unregister explicit locks.
+ // 5. Unregister explicit locks.
if (!tx.alternateVersions().isEmpty())
for (GridCacheVersion ver : tx.alternateVersions())
idMap.remove(ver);
- // 7. Remove Near-2-DHT mappings.
+ // 6. Remove Near-2-DHT mappings.
if (tx instanceof GridCacheMappedVersion)
mappedVers.remove(((GridCacheMappedVersion)tx).mappedVersion());
- // 8. Clear context.
+ // 7. Clear context.
resetContext();
if (log.isDebugEnabled())
@@ -1635,6 +1384,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
// we wait for the lock.
long timeout = tx.timeout() == 0 ? 0 : remainingTime;
+ GridCacheVersion serOrder = (tx.serializable() && tx.optimistic()) ? tx.nearXidVersion() : null;
+
for (IgniteTxEntry txEntry1 : entries) {
// Check if this entry was prepared before.
if (!txEntry1.markPrepared() || txEntry1.explicitVersion() != null)
@@ -1649,7 +1400,11 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
assert !entry1.detached() : "Expected non-detached entry for near transaction " +
"[locNodeId=" + cctx.localNodeId() + ", entry=" + entry1 + ']';
- if (!entry1.tmLock(tx, timeout)) {
+ GridCacheVersion serReadVer = txEntry1.serializableReadVersion();
+
+ assert serReadVer == null || (tx.optimistic() && tx.serializable()) : txEntry1;
+
+ if (!entry1.tmLock(tx, timeout, serOrder, serReadVer)) {
// Unlock locks locked so far.
for (IgniteTxEntry txEntry2 : entries) {
if (txEntry2 == txEntry1)
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
index 36f1c36..68d03cd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
@@ -53,9 +53,6 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
/** Last version. */
private volatile GridCacheVersion last;
- /** Serializable transaction flag. */
- private boolean txSerEnabled;
-
/** Data center ID. */
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
private byte dataCenterId;
@@ -64,6 +61,9 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
private long gridStartTime;
/** */
+ private GridCacheVersion ISOLATED_STREAMER_VER;
+
+ /** */
private final GridLocalEventListener discoLsnr = new GridLocalEventListener() {
@Override public void onEvent(Event evt) {
assert evt.type() == EVT_NODE_METRICS_UPDATED;
@@ -79,8 +79,6 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
/** {@inheritDoc} */
@Override public void start0() throws IgniteCheckedException {
- txSerEnabled = cctx.gridConfig().getTransactionConfiguration().isTxSerializableEnabled();
-
last = new GridCacheVersion(0, 0, order.get(), 0, dataCenterId);
cctx.gridEvents().addLocalEventListener(discoLsnr, EVT_NODE_METRICS_UPDATED);
@@ -154,6 +152,27 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
}
/**
+ * Version for entries loaded with isolated streamer, should be less than any version generated
+ * for entries update.
+ *
+ * @return Version for entries loaded with isolated streamer.
+ */
+ public GridCacheVersion isolatedStreamerVersion() {
+ if (ISOLATED_STREAMER_VER == null) {
+ long topVer = 1;
+
+ if (gridStartTime == 0)
+ gridStartTime = cctx.kernalContext().discovery().gridStartTime();
+
+ topVer += (gridStartTime - TOP_VER_BASE_TIME) / 1000;
+
+ ISOLATED_STREAMER_VER = new GridCacheVersion((int)topVer, 0, 0, 1, dataCenterId);
+ }
+
+ return ISOLATED_STREAMER_VER;
+ }
+
+ /**
* @return Next version based on current topology.
*/
public GridCacheVersion next() {
@@ -235,36 +254,18 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
int locNodeOrder = (int)cctx.localNode().order();
- if (txSerEnabled) {
- synchronized (this) {
- long ord = forLoad ? loadOrder.incrementAndGet() : order.incrementAndGet();
-
- GridCacheVersion next = new GridCacheVersion(
- (int)topVer,
- globalTime,
- ord,
- locNodeOrder,
- dataCenterId);
-
- last = next;
+ long ord = forLoad ? loadOrder.incrementAndGet() : order.incrementAndGet();
- return next;
- }
- }
- else {
- long ord = forLoad ? loadOrder.incrementAndGet() : order.incrementAndGet();
-
- GridCacheVersion next = new GridCacheVersion(
- (int)topVer,
- globalTime,
- ord,
- locNodeOrder,
- dataCenterId);
+ GridCacheVersion next = new GridCacheVersion(
+ (int)topVer,
+ globalTime,
+ ord,
+ locNodeOrder,
+ dataCenterId);
- last = next;
+ last = next;
- return next;
- }
+ return next;
}
/**
@@ -273,12 +274,6 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
* @return Last generated version.
*/
public GridCacheVersion last() {
- if (txSerEnabled) {
- synchronized (this) {
- return last;
- }
- }
- else
- return last;
+ return last;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
index ab2a6e8..2190bf6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
@@ -1556,7 +1556,7 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
AffinityTopologyVersion topVer = cctx.affinity().affinityTopologyVersion();
- GridCacheVersion ver = cctx.versions().next(topVer);
+ GridCacheVersion ver = cctx.versions().isolatedStreamerVersion();
long ttl = CU.TTL_ETERNAL;
long expiryTime = CU.EXPIRE_TIME_ETERNAL;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java b/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
index a6e960d..6c4e894 100644
--- a/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
+++ b/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
@@ -54,7 +54,7 @@ import org.apache.ignite.lang.IgniteUuid;
* Read access with this level happens the same way as with {@link TransactionIsolation#REPEATABLE_READ} level.
* However, in {@link TransactionConcurrency#OPTIMISTIC} mode, if some transactions cannot be serially isolated
* from each other, then one winner will be picked and the other transactions in conflict will result in
- * {@link org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException} being thrown.
+ * {@link TransactionOptimisticException} being thrown.
* </li>
* </ul>
* <p>
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
index d7671f0..c3be3c5 100644
--- a/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
+++ b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
@@ -42,8 +42,7 @@ public enum TransactionIsolation {
* @param ord Ordinal value.
* @return Enumerated value or {@code null} if ordinal out of range.
*/
- @Nullable
- public static TransactionIsolation fromOrdinal(int ord) {
+ @Nullable public static TransactionIsolation fromOrdinal(int ord) {
return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java
new file mode 100644
index 0000000..c2f9fab
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java
@@ -0,0 +1,388 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.cache.Cache;
+import javax.cache.configuration.Factory;
+import javax.cache.integration.CacheLoaderException;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.store.CacheStore;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.spi.swapspace.inmemory.GridTestSwapSpaceSpi;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.jsr166.ConcurrentHashMap8;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class CacheNearReaderUpdateTest extends GridCommonAbstractTest {
+ /** */
+ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ private boolean client;
+
+ /** */
+ private static final int SRVS = 4;
+
+ /** */
+ private static final int CLIENTS = 3;
+
+ /** */
+ private static Map<Integer, Integer> storeMap = new ConcurrentHashMap8<>();
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ cfg.setPeerClassLoadingEnabled(false);
+
+ ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
+
+ cfg.setClientMode(client);
+
+ cfg.setSwapSpaceSpi(new GridTestSwapSpaceSpi());
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGridsMultiThreaded(SRVS);
+
+ client = true;
+
+ startGridsMultiThreaded(SRVS, CLIENTS);
+
+ client = false;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected long getTestTimeout() {
+ return 10 * 60_000;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testGetUpdateMultithreaded() throws Exception {
+ List<CacheConfiguration<Integer, Integer>> cfgs = new ArrayList<>();
+
+ cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 0, false, false));
+ cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+ cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, true));
+ cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, true, false));
+
+ {
+ CacheConfiguration<Integer, Integer> ccfg = cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
+
+ GridTestUtils.setMemoryMode(null, ccfg, GridTestUtils.TestMemoryMode.OFFHEAP_TIERED, 0, 0);
+
+ cfgs.add(ccfg);
+ }
+
+ final List<Ignite> putNodes = new ArrayList<>();
+
+ for (int i = 0; i < SRVS + CLIENTS - 1; i++)
+ putNodes.add(ignite(i));
+
+ final List<Ignite> getNodes = new ArrayList<>();
+
+ getNodes.add(ignite(SRVS + CLIENTS - 1));
+ getNodes.add(ignite(0));
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cfgs) {
+ logCacheInfo(ccfg);
+
+ getUpdateMultithreaded(ccfg, putNodes, getNodes, null, null);
+
+ if (ccfg.getAtomicityMode() == TRANSACTIONAL) {
+ getUpdateMultithreaded(ccfg, putNodes, getNodes, PESSIMISTIC, REPEATABLE_READ);
+
+ getUpdateMultithreaded(ccfg, putNodes, getNodes, OPTIMISTIC, REPEATABLE_READ);
+
+ getUpdateMultithreaded(ccfg, putNodes, getNodes, OPTIMISTIC, SERIALIZABLE);
+ }
+ }
+ }
+
+ /**
+ * @param ccfg Cache configuration.
+ * @param putNodes Nodes executing updates.
+ * @param getNodes Nodes executing gets.
+ * @param concurrency Transaction concurrency.
+ * @param isolation Transaction isolation.
+ * @throws Exception If failed.
+ */
+ private void getUpdateMultithreaded(CacheConfiguration<Integer, Integer> ccfg,
+ final List<Ignite> putNodes,
+ final List<Ignite> getNodes,
+ final TransactionConcurrency concurrency,
+ final TransactionIsolation isolation) throws Exception {
+ log.info("Execute updates [concurrency=" + concurrency + ", isolation=" + isolation + ']');
+
+ final Ignite ignite0 = ignite(0);
+
+ final String cacheName = ignite0.createCache(ccfg).getName();
+
+ try {
+ for (int i = 0; i < 5; i++) {
+ final Integer key = i;
+
+ final AtomicInteger putThreadIdx = new AtomicInteger();
+ final AtomicInteger getThreadIdx = new AtomicInteger();
+
+ final int PUT_THREADS = 20;
+ final int GET_THREAD = 20;
+
+ final CyclicBarrier barrier = new CyclicBarrier(PUT_THREADS + GET_THREAD);
+
+ final IgniteInternalFuture<?> updateFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ int idx = putThreadIdx.getAndIncrement() % putNodes.size();
+
+ Ignite ignite = putNodes.get(idx);
+
+ IgniteCache<Integer, Integer> cache = ignite.cache(cacheName);
+
+ IgniteTransactions txs = ignite.transactions();
+
+ Thread.currentThread().setName("update-thread-" + ignite.name());
+
+ barrier.await();
+
+ for (int i = 0; i < 100; i++) {
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ if (concurrency != null) {
+ try (Transaction tx = txs.txStart(concurrency, isolation)) {
+ cache.put(key, rnd.nextInt());
+
+ tx.commit();
+ }
+ catch (TransactionOptimisticException ignore) {
+ assertEquals(concurrency, OPTIMISTIC);
+ assertEquals(isolation, SERIALIZABLE);
+ }
+ }
+ else
+ cache.put(key, rnd.nextInt());
+ }
+
+ return null;
+ }
+ }, PUT_THREADS, "update-thread");
+
+ IgniteInternalFuture<?> getFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ int idx = getThreadIdx.getAndIncrement() % getNodes.size();
+
+ Ignite ignite = getNodes.get(idx);
+
+ IgniteCache<Integer, Integer> cache;
+
+ if (ignite.configuration().isClientMode())
+ cache = ignite.createNearCache(cacheName, new NearCacheConfiguration<Integer, Integer>());
+ else
+ cache = ignite.cache(cacheName);
+
+ Thread.currentThread().setName("get-thread-" + ignite.name());
+
+ barrier.await();
+
+ while (!updateFut.isDone())
+ cache.get(key);
+
+ return null;
+ }
+ }, GET_THREAD, "get-thread");
+
+ updateFut.get();
+ getFut.get();
+
+ Integer val = (Integer)ignite0.cache(cacheName).get(key);
+
+ log.info("Iteration [iter=" + i + ", val=" + val + ']');
+
+ for (Ignite getNode : getNodes) {
+ IgniteCache<Integer, Integer> cache = getNode.cache(cacheName);
+
+ if (getNode.configuration().isClientMode() ||
+ cache.getConfiguration(CacheConfiguration.class).getNearConfiguration() != null)
+ assertNotNull(getNode.cache(cacheName).localPeek(key));
+ }
+
+ checkValue(key, val, cacheName);
+
+ for (int n = 0; n < SRVS + CLIENTS; n++) {
+ val = n;
+
+ ignite(n).cache(cacheName).put(key, val);
+
+ checkValue(key, val, cacheName);
+ }
+ }
+ }
+ finally {
+ destroyCache(ignite0, cacheName);
+ }
+ }
+
+ /**
+ * @param key Key.
+ * @param expVal Expected value.
+ * @param cacheName Cache name.
+ */
+ private void checkValue(Object key, Object expVal, String cacheName) {
+ for (int i = 0; i < SRVS + CLIENTS; i++) {
+ IgniteCache<Object, Object> cache = ignite(i).cache(cacheName);
+
+ assertEquals(expVal, cache.get(key));
+ }
+ }
+
+ /**
+ * @param ccfg Cache configuration.
+ */
+ private void logCacheInfo(CacheConfiguration<?, ?> ccfg) {
+ log.info("Test cache [mode=" + ccfg.getCacheMode() +
+ ", sync=" + ccfg.getWriteSynchronizationMode() +
+ ", backups=" + ccfg.getBackups() +
+ ", memMode=" + ccfg.getMemoryMode() +
+ ", near=" + (ccfg.getNearConfiguration() != null) +
+ ", store=" + ccfg.isWriteThrough() +
+ ", evictPlc=" + (ccfg.getEvictionPolicy() != null) +
+ ", swap=" + ccfg.isSwapEnabled() +
+ ", maxOffheap=" + ccfg.getOffHeapMaxMemory() +
+ ']');
+ }
+
+ /**
+ * @param ignite Node.
+ * @param cacheName Cache name.
+ */
+ private void destroyCache(Ignite ignite, String cacheName) {
+ storeMap.clear();
+
+ ignite.destroyCache(cacheName);
+
+ for (Ignite ignite0 : G.allGrids()) {
+ GridTestSwapSpaceSpi spi = (GridTestSwapSpaceSpi)ignite0.configuration().getSwapSpaceSpi();
+
+ spi.clearAll();
+ }
+ }
+
+ /**
+ * @param cacheMode Cache mode.
+ * @param syncMode Write synchronization mode.
+ * @param backups Number of backups.
+ * @param storeEnabled If {@code true} adds cache store.
+ * @param nearCache If {@code true} near cache is enabled.
+ * @return Cache configuration.
+ */
+ private CacheConfiguration<Integer, Integer> cacheConfiguration(
+ CacheMode cacheMode,
+ CacheWriteSynchronizationMode syncMode,
+ int backups,
+ boolean storeEnabled,
+ boolean nearCache) {
+ CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+
+ ccfg.setCacheMode(cacheMode);
+ ccfg.setAtomicityMode(TRANSACTIONAL);
+ ccfg.setWriteSynchronizationMode(syncMode);
+
+ if (cacheMode == PARTITIONED)
+ ccfg.setBackups(backups);
+
+ if (storeEnabled) {
+ ccfg.setCacheStoreFactory(new TestStoreFactory());
+ ccfg.setWriteThrough(true);
+ ccfg.setReadThrough(true);
+ }
+
+ if (nearCache)
+ ccfg.setNearConfiguration(new NearCacheConfiguration<Integer, Integer>());
+
+ return ccfg;
+ }
+
+ /**
+ *
+ */
+ private static class TestStoreFactory implements Factory<CacheStore<Integer, Integer>> {
+ /** {@inheritDoc} */
+ @Override public CacheStore<Integer, Integer> create() {
+ return new CacheStoreAdapter<Integer, Integer>() {
+ @Override public Integer load(Integer key) throws CacheLoaderException {
+ return storeMap.get(key);
+ }
+
+ @Override public void write(Cache.Entry<? extends Integer, ? extends Integer> entry) {
+ storeMap.put(entry.getKey(), entry.getValue());
+ }
+
+ @Override public void delete(Object key) {
+ storeMap.remove(key);
+ }
+ };
+ }
+ }
+}
[17/23] ignite git commit: Ignite JMS 1.1 Streamer tests: Remove
dependency on KahaDB & persistence.
Posted by yz...@apache.org.
Ignite JMS 1.1 Streamer tests: Remove dependency on KahaDB & persistence.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/7f0b3fce
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/7f0b3fce
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/7f0b3fce
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 7f0b3fce5ae6ed0652f3dbf64f0482e63d36c38d
Parents: e769c3a
Author: Raul Kripalani <ra...@apache.org>
Authored: Wed Oct 28 12:37:38 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Wed Oct 28 12:37:38 2015 +0000
----------------------------------------------------------------------
modules/jms11/pom.xml | 7 -------
.../apache/ignite/stream/jms11/IgniteJmsStreamerTest.java | 9 +++++++--
2 files changed, 7 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/7f0b3fce/modules/jms11/pom.xml
----------------------------------------------------------------------
diff --git a/modules/jms11/pom.xml b/modules/jms11/pom.xml
index 72a643b..3c37e7f 100644
--- a/modules/jms11/pom.xml
+++ b/modules/jms11/pom.xml
@@ -66,13 +66,6 @@
</dependency>
<dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>activemq-kahadb-store</artifactId>
- <version>${activemq.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-log4j</artifactId>
<version>${project.version}</version>
http://git-wip-us.apache.org/repos/asf/ignite/blob/7f0b3fce/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java b/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
index 0e110a5..238d939 100644
--- a/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
+++ b/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
@@ -83,14 +83,19 @@ public class IgniteJmsStreamerTest extends GridCommonAbstractTest {
grid().<Integer, String>getOrCreateCache(defaultCacheConfiguration());
broker = new BrokerService();
- broker.deleteAllMessages();
+ broker.setDeleteAllMessagesOnStartup(true);
broker.setPersistent(false);
+ broker.setPersistenceAdapter(null);
+ broker.setPersistenceFactory(null);
PolicyMap policyMap = new PolicyMap();
PolicyEntry policy = new PolicyEntry();
+
policy.setQueuePrefetch(1);
+
broker.setDestinationPolicy(policyMap);
broker.getDestinationPolicy().setDefaultEntry(policy);
+ broker.setSchedulerSupport(false);
broker.start(true);
@@ -102,8 +107,8 @@ public class IgniteJmsStreamerTest extends GridCommonAbstractTest {
public void afterTest() throws Exception {
grid().cache(null).clear();
- broker.deleteAllMessages();
broker.stop();
+ broker.deleteAllMessages();
}
public void testQueueFromName() throws Exception {
[11/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index f22e753..82e5f2a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -31,12 +31,12 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.expiry.Duration;
import javax.cache.expiry.ExpiryPolicy;
import javax.cache.processor.EntryProcessor;
import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -57,7 +57,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.GridCacheUpdateTxResult;
import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
+import org.apache.ignite.internal.processors.cache.distributed.dht.colocated.GridDhtDetachedCacheEntry;
import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo;
import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -73,6 +73,7 @@ import org.apache.ignite.internal.util.future.GridEmbeddedFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.lang.GridClosureException;
+import org.apache.ignite.internal.util.lang.GridInClosure3;
import org.apache.ignite.internal.util.lang.GridTuple;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -85,10 +86,8 @@ import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.CU;
-import org.apache.ignite.internal.util.typedef.internal.GPC;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiClosure;
-import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteClosure;
import org.apache.ignite.plugin.security.SecurityPermission;
@@ -105,6 +104,8 @@ import static org.apache.ignite.internal.processors.cache.GridCacheOperation.REA
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.RELOAD;
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE;
+import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER;
+import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry.SER_READ_NOT_EMPTY_VER;
import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
import static org.apache.ignite.internal.processors.dr.GridDrType.DR_PRIMARY;
import static org.apache.ignite.transactions.TransactionState.COMMITTED;
@@ -424,46 +425,126 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/** {@inheritDoc} */
- @Override public IgniteInternalFuture<Boolean> loadMissing(
+ @Override public IgniteInternalFuture<Void> loadMissing(
final GridCacheContext cacheCtx,
final boolean readThrough,
boolean async,
final Collection<KeyCacheObject> keys,
- boolean deserializePortable,
boolean skipVals,
- final IgniteBiInClosure<KeyCacheObject, Object> c
+ boolean needVer,
+ final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c
) {
- if (!async) {
- try {
- if (!readThrough || !cacheCtx.readThrough()) {
- for (KeyCacheObject key : keys)
- c.apply(key, null);
+ assert cacheCtx.isLocal() : cacheCtx.name();
- return new GridFinishedFuture<>(false);
- }
+ if (!readThrough || !cacheCtx.readThrough()) {
+ for (KeyCacheObject key : keys)
+ c.apply(key, null, SER_READ_EMPTY_ENTRY_VER);
- return new GridFinishedFuture<>(
- cacheCtx.store().loadAll(this, keys, c));
- }
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(e);
- }
+ return new GridFinishedFuture<>();
}
- else {
- return cctx.kernalContext().closure().callLocalSafe(
- new GPC<Boolean>() {
- @Override public Boolean call() throws Exception {
- if (!readThrough || !cacheCtx.readThrough()) {
- for (KeyCacheObject key : keys)
- c.apply(key, null);
-
- return false;
+
+ try {
+ IgniteCacheExpiryPolicy expiryPlc = accessPolicy(cacheCtx, keys);
+
+ Map<KeyCacheObject, GridCacheVersion> misses = null;
+
+ for (KeyCacheObject key : keys) {
+ while (true) {
+ IgniteTxEntry txEntry = entry(cacheCtx.txKey(key));
+
+ GridCacheEntryEx entry = txEntry == null ? cacheCtx.cache().entryEx(key) :
+ txEntry.cached();
+
+ if (entry == null)
+ continue;
+
+ try {
+ T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(this,
+ /*readSwap*/true,
+ /*unmarshal*/true,
+ /*update-metrics*/!skipVals,
+ /*event*/!skipVals,
+ CU.subjectId(this, cctx),
+ null,
+ resolveTaskName(),
+ expiryPlc);
+
+ if (res == null) {
+ if (misses == null)
+ misses = new LinkedHashMap<>();
+
+ misses.put(key, entry.version());
}
+ else
+ c.apply(key, skipVals ? true : res.get1(), res.get2());
- return cacheCtx.store().loadAll(IgniteTxLocalAdapter.this, keys, c);
+ break;
}
- },
- true);
+ catch (GridCacheEntryRemovedException ignore) {
+ if (log.isDebugEnabled())
+ log.debug("Got removed entry, will retry: " + key);
+
+ if (txEntry != null)
+ txEntry.cached(cacheCtx.cache().entryEx(key));
+ }
+ }
+ }
+
+ if (misses != null) {
+ final Map<KeyCacheObject, GridCacheVersion> misses0 = misses;
+
+ cacheCtx.store().loadAll(this, misses.keySet(), new CI2<KeyCacheObject, Object>() {
+ @Override public void apply(KeyCacheObject key, Object val) {
+ GridCacheVersion ver = misses0.remove(key);
+
+ assert ver != null : key;
+
+ if (val != null) {
+ CacheObject cacheVal = cacheCtx.toCacheObject(val);
+
+ while (true) {
+ GridCacheEntryEx entry = cacheCtx.cache().entryEx(key);
+
+ try {
+ GridCacheVersion setVer = entry.versionedValue(cacheVal, ver, null);
+
+ boolean set = setVer != null;
+
+ if (set)
+ ver = setVer;
+
+ if (log.isDebugEnabled())
+ log.debug("Set value loaded from store into entry [set=" + set +
+ ", curVer=" + ver + ", newVer=" + setVer + ", " +
+ "entry=" + entry + ']');
+
+ break;
+ }
+ catch (GridCacheEntryRemovedException ignore) {
+ if (log.isDebugEnabled())
+ log.debug("Got removed entry, (will retry): " + entry);
+ }
+ catch (IgniteCheckedException e) {
+ // Wrap errors (will be unwrapped).
+ throw new GridClosureException(e);
+ }
+ }
+ }
+ else
+ ver = SER_READ_EMPTY_ENTRY_VER;
+
+ c.apply(key, val, ver);
+ }
+ });
+
+ for (KeyCacheObject key : misses0.keySet())
+ c.apply(key, null, SER_READ_EMPTY_ENTRY_VER);
+ }
+
+ return new GridFinishedFuture<>();
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(e);
}
}
@@ -834,13 +915,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
IgniteBiTuple<GridCacheOperation, CacheObject> res = applyTransformClosures(txEntry,
true);
+ GridCacheVersion dhtVer = null;
+
// For near local transactions we must record DHT version
// in order to keep near entries on backup nodes until
// backup remote transaction completes.
if (cacheCtx.isNear()) {
if (txEntry.op() == CREATE || txEntry.op() == UPDATE ||
txEntry.op() == DELETE || txEntry.op() == TRANSFORM)
- ((GridNearCacheEntry)cached).recordDhtVersion(txEntry.dhtVersion());
+ dhtVer = txEntry.dhtVersion();
if ((txEntry.op() == CREATE || txEntry.op() == UPDATE) &&
txEntry.conflictExpireTime() == CU.EXPIRE_TIME_CALCULATE) {
@@ -921,6 +1004,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
txEntry.conflictVersion(explicitVer);
}
+ if (dhtVer == null)
+ dhtVer = explicitVer != null ? explicitVer : writeVersion();
+
if (op == CREATE || op == UPDATE) {
GridCacheUpdateTxResult updRes = cached.innerSet(
this,
@@ -938,9 +1024,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
txEntry.conflictExpireTime(),
cached.isNear() ? null : explicitVer,
CU.subjectId(this, cctx),
- resolveTaskName());
+ resolveTaskName(),
+ dhtVer);
- if (nearCached != null && updRes.success())
+ if (nearCached != null && updRes.success()) {
nearCached.innerSet(
null,
eventNodeId(),
@@ -957,7 +1044,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
txEntry.conflictExpireTime(),
null,
CU.subjectId(this, cctx),
- resolveTaskName());
+ resolveTaskName(),
+ dhtVer);
+ }
}
else if (op == DELETE) {
GridCacheUpdateTxResult updRes = cached.innerRemove(
@@ -973,9 +1062,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
cached.detached() ? DR_NONE : drType,
cached.isNear() ? null : explicitVer,
CU.subjectId(this, cctx),
- resolveTaskName());
+ resolveTaskName(),
+ dhtVer);
- if (nearCached != null && updRes.success())
+ if (nearCached != null && updRes.success()) {
nearCached.innerRemove(
null,
eventNodeId(),
@@ -989,7 +1079,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
DR_NONE,
null,
CU.subjectId(this, cctx),
- resolveTaskName());
+ resolveTaskName(),
+ dhtVer);
+ }
}
else if (op == RELOAD) {
cached.innerReload();
@@ -1180,14 +1272,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
commitErr.get());
}
+ if (near()) {
+ // Must evict near entries before rolling back from
+ // transaction manager, so they will be removed from cache.
+ for (IgniteTxEntry e : allEntries())
+ evictNearEntry(e, false);
+ }
+
if (doneFlag.compareAndSet(false, true)) {
try {
- if (near())
- // Must evict near entries before rolling back from
- // transaction manager, so they will be removed from cache.
- for (IgniteTxEntry e : allEntries())
- evictNearEntry(e, false);
-
cctx.tm().rollbackTx(this);
if (!internal()) {
@@ -1228,12 +1321,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @param entry Entry.
+ * @return {@code True} if local node is current primary for given entry.
+ */
+ private boolean primaryLocal(GridCacheEntryEx entry) {
+ return entry.context().affinity().primary(cctx.localNode(), entry.partition(), AffinityTopologyVersion.NONE);
+ }
+
+ /**
* Checks if there is a cached or swapped value for
- * {@link #getAllAsync(GridCacheContext, Collection, GridCacheEntryEx, boolean, boolean, boolean, boolean)} method.
+ * {@link #getAllAsync(GridCacheContext, Collection, boolean, boolean, boolean, boolean)} method.
*
* @param cacheCtx Cache context.
* @param keys Key to enlist.
- * @param cached Cached entry, if called from entry wrapper.
* @param expiryPlc Explicitly specified expiry policy for entry.
* @param map Return map.
* @param missed Map of missed keys.
@@ -1249,7 +1349,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
private <K, V> Collection<KeyCacheObject> enlistRead(
final GridCacheContext cacheCtx,
Collection<KeyCacheObject> keys,
- @Nullable GridCacheEntryEx cached,
@Nullable ExpiryPolicy expiryPlc,
Map<K, V> map,
Map<KeyCacheObject, GridCacheVersion> missed,
@@ -1261,7 +1360,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
) throws IgniteCheckedException {
assert !F.isEmpty(keys);
assert keysCnt == keys.size();
- assert cached == null || F.first(keys).equals(cached.key());
cacheCtx.checkSecurity(SecurityPermission.CACHE_READ);
@@ -1271,11 +1369,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
AffinityTopologyVersion topVer = topologyVersion();
+ boolean needReadVer = serializable() && optimistic();
+
// In this loop we cover only read-committed or optimistic transactions.
// Transactions that are pessimistic and not read-committed are covered
// outside of this loop.
for (KeyCacheObject key : keys) {
- if (pessimistic() && !readCommitted() && !skipVals)
+ if ((pessimistic() || needReadVer) && !readCommitted() && !skipVals)
addActiveCache(cacheCtx);
IgniteTxKey txKey = cacheCtx.txKey(key);
@@ -1337,13 +1437,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
break;
}
- catch (GridCacheFilterFailedException e) {
- if (log.isDebugEnabled())
- log.debug("Filter validation failed for entry: " + txEntry);
-
- if (!readCommitted())
- txEntry.readValue(e.<V>value());
- }
catch (GridCacheEntryRemovedException ignored) {
txEntry.cached(entryEx(cacheCtx, txEntry.txKey(), topVer));
}
@@ -1359,38 +1452,49 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
lockKeys.add(key);
while (true) {
- GridCacheEntryEx entry;
-
- if (cached != null) {
- entry = cached;
-
- cached = null;
- }
- else
- entry = entryEx(cacheCtx, txKey, topVer);
+ GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topVer);
try {
GridCacheVersion ver = entry.version();
CacheObject val = null;
+ GridCacheVersion readVer = null;
if (!pessimistic() || readCommitted() && !skipVals) {
IgniteCacheExpiryPolicy accessPlc =
optimistic() ? accessPolicy(cacheCtx, txKey, expiryPlc) : null;
- // This call will check for filter.
- val = entry.innerGet(this,
- /*swap*/true,
- /*no read-through*/false,
- /*fail-fast*/true,
- /*unmarshal*/true,
- /*metrics*/true,
- /*event*/true,
- /*temporary*/false,
- CU.subjectId(this, cctx),
- null,
- resolveTaskName(),
- accessPlc);
+ if (needReadVer) {
+ T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
+ entry.innerGetVersioned(this,
+ /*swap*/true,
+ /*unmarshal*/true,
+ /*metrics*/true,
+ /*event*/true,
+ CU.subjectId(this, cctx),
+ null,
+ resolveTaskName(),
+ accessPlc) : null;
+
+ if (res != null) {
+ val = res.get1();
+ readVer = res.get2();
+ }
+ }
+ else {
+ val = entry.innerGet(this,
+ /*swap*/true,
+ /*no read-through*/false,
+ /*fail-fast*/true,
+ /*unmarshal*/true,
+ /*metrics*/true,
+ /*event*/true,
+ /*temporary*/false,
+ CU.subjectId(this, cctx),
+ null,
+ resolveTaskName(),
+ accessPlc);
+ }
if (val != null) {
cacheCtx.addResult(map,
@@ -1424,8 +1528,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
// As optimization, mark as checked immediately
// for non-pessimistic if value is not null.
- if (val != null && !pessimistic())
+ if (val != null && !pessimistic()) {
txEntry.markValid();
+
+ if (needReadVer) {
+ assert readVer != null;
+
+ txEntry.serializableReadVersion(readVer);
+ }
+ }
}
break; // While.
@@ -1434,34 +1545,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (log.isDebugEnabled())
log.debug("Got removed entry in transaction getAllAsync(..) (will retry): " + key);
}
- catch (GridCacheFilterFailedException e) {
- if (log.isDebugEnabled())
- log.debug("Filter validation failed for entry: " + entry);
-
- if (!readCommitted()) {
- // Value for which failure occurred.
- CacheObject val = e.value();
-
- txEntry = addEntry(READ,
- val,
- null,
- null,
- entry,
- expiryPlc,
- CU.empty0(),
- false,
- -1L,
- -1L,
- null,
- skipStore);
-
- // Mark as checked immediately for non-pessimistic.
- if (val != null && !pessimistic())
- txEntry.markValid();
- }
-
- break; // While loop.
- }
finally {
if (cacheCtx.isNear() && entry != null && readCommitted()) {
if (cacheCtx.affinity().belongs(cacheCtx.localNode(), entry.partition(), topVer)) {
@@ -1492,6 +1575,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @param cacheCtx Cache context.
+ * @param keys Keys.
+ * @return Expiry policy.
+ */
+ protected IgniteCacheExpiryPolicy accessPolicy(GridCacheContext cacheCtx, Collection<KeyCacheObject> keys) {
+ return null;
+ }
+
+ /**
* Adds skipped key.
*
* @param skipped Skipped set (possibly {@code null}).
@@ -1512,12 +1604,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/**
* Loads all missed keys for
- * {@link #getAllAsync(GridCacheContext, Collection, GridCacheEntryEx, boolean, boolean, boolean, boolean)} method.
+ * {@link #getAllAsync(GridCacheContext, Collection, boolean, boolean, boolean, boolean)} method.
*
* @param cacheCtx Cache context.
* @param map Return map.
* @param missedMap Missed keys.
- * @param redos Keys to retry.
* @param deserializePortable Deserialize portable flag.
* @param skipVals Skip values flag.
* @param keepCacheObjects Keep cache objects flag.
@@ -1528,55 +1619,25 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
final GridCacheContext cacheCtx,
final Map<K, V> map,
final Map<KeyCacheObject, GridCacheVersion> missedMap,
- @Nullable final Collection<KeyCacheObject> redos,
final boolean deserializePortable,
final boolean skipVals,
final boolean keepCacheObjects,
final boolean skipStore
) {
- assert redos != null || pessimistic();
-
if (log.isDebugEnabled())
log.debug("Loading missed values for missed map: " + missedMap);
- final Collection<KeyCacheObject> loaded = new HashSet<>();
+ final boolean needReadVer = serializable() && optimistic();
return new GridEmbeddedFuture<>(
- new C2<Boolean, Exception, Map<K, V>>() {
- @Override public Map<K, V> apply(Boolean b, Exception e) {
+ new C2<Void, Exception, Map<K, V>>() {
+ @Override public Map<K, V> apply(Void v, Exception e) {
if (e != null) {
setRollbackOnly();
throw new GridClosureException(e);
}
- if (!b && !readCommitted()) {
- // There is no store - we must mark the entries.
- for (KeyCacheObject key : missedMap.keySet()) {
- IgniteTxEntry txEntry = entry(cacheCtx.txKey(key));
-
- if (txEntry != null)
- txEntry.markValid();
- }
- }
-
- if (readCommitted()) {
- Collection<KeyCacheObject> notFound = new HashSet<>(missedMap.keySet());
-
- notFound.removeAll(loaded);
-
- // In read-committed mode touch entries that have just been read.
- for (KeyCacheObject key : notFound) {
- IgniteTxEntry txEntry = entry(cacheCtx.txKey(key));
-
- GridCacheEntryEx entry = txEntry == null ? cacheCtx.cache().peekEx(key) :
- txEntry.cached();
-
- if (entry != null)
- cacheCtx.evicts().touch(entry, topologyVersion());
- }
- }
-
return map;
}
},
@@ -1585,13 +1646,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
!skipStore,
false,
missedMap.keySet(),
- deserializePortable,
skipVals,
- new CI2<KeyCacheObject, Object>() {
- /** */
- private GridCacheVersion nextVer;
-
- @Override public void apply(KeyCacheObject key, Object val) {
+ needReadVer,
+ new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
+ @Override public void apply(KeyCacheObject key, Object val, GridCacheVersion loadVer) {
if (isRollbackOnly()) {
if (log.isDebugEnabled())
log.debug("Ignoring loaded value for read because transaction was rolled back: " +
@@ -1600,15 +1658,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
return;
}
- GridCacheVersion ver = missedMap.get(key);
-
- if (ver == null) {
- if (log.isDebugEnabled())
- log.debug("Value from storage was never asked for [key=" + key + ", val=" + val + ']');
-
- return;
- }
-
CacheObject cacheVal = cacheCtx.toCacheObject(val);
CacheObject visibleVal = cacheVal;
@@ -1625,90 +1674,42 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
visibleVal = txEntry.applyEntryProcessors(visibleVal);
}
- // In pessimistic mode we hold the lock, so filter validation
- // should always be valid.
- if (pessimistic())
- ver = null;
-
- // Initialize next version.
- if (nextVer == null)
- nextVer = cctx.versions().next(topologyVersion());
-
- while (true) {
- assert txEntry != null || readCommitted() || skipVals;
-
- GridCacheEntryEx e = txEntry == null ? entryEx(cacheCtx, txKey) : txEntry.cached();
-
- try {
- // Must initialize to true since even if filter didn't pass,
- // we still record the transaction value.
- boolean set;
-
- try {
- set = e.versionedValue(cacheVal, ver, nextVer);
- }
- catch (GridCacheEntryRemovedException ignore) {
- if (log.isDebugEnabled())
- log.debug("Got removed entry in transaction getAll method " +
- "(will try again): " + e);
-
- if (pessimistic() && !readCommitted() && !isRollbackOnly()) {
- U.error(log, "Inconsistent transaction state (entry got removed while " +
- "holding lock) [entry=" + e + ", tx=" + IgniteTxLocalAdapter.this + "]");
-
- setRollbackOnly();
-
- return;
- }
-
- if (txEntry != null)
- txEntry.cached(entryEx(cacheCtx, txKey));
-
- continue; // While loop.
- }
-
- // In pessimistic mode, we should always be able to set.
- assert set || !pessimistic();
-
- if (readCommitted() || skipVals) {
- cacheCtx.evicts().touch(e, topologyVersion());
+ assert txEntry != null || readCommitted() || skipVals;
- if (visibleVal != null) {
- cacheCtx.addResult(map,
- key,
- visibleVal,
- skipVals,
- keepCacheObjects,
- deserializePortable,
- false);
- }
- }
- else {
- assert txEntry != null;
+ GridCacheEntryEx e = txEntry == null ? entryEx(cacheCtx, txKey) : txEntry.cached();
- txEntry.setAndMarkValid(cacheVal);
+ if (readCommitted() || skipVals) {
+ cacheCtx.evicts().touch(e, topologyVersion());
- if (visibleVal != null) {
- cacheCtx.addResult(map,
- key,
- visibleVal,
- skipVals,
- keepCacheObjects,
- deserializePortable,
- false);
- }
- }
+ if (visibleVal != null) {
+ cacheCtx.addResult(map,
+ key,
+ visibleVal,
+ skipVals,
+ keepCacheObjects,
+ deserializePortable,
+ false);
+ }
+ }
+ else {
+ assert txEntry != null;
- loaded.add(key);
+ txEntry.setAndMarkValid(cacheVal);
- if (log.isDebugEnabled())
- log.debug("Set value loaded from store into entry from transaction [set=" + set +
- ", matchVer=" + ver + ", newVer=" + nextVer + ", entry=" + e + ']');
+ if (needReadVer) {
+ assert loadVer != null;
- break; // While loop.
+ txEntry.serializableReadVersion(loadVer);
}
- catch (IgniteCheckedException ex) {
- throw new IgniteException("Failed to put value for cache entry: " + e, ex);
+
+ if (visibleVal != null) {
+ cacheCtx.addResult(map,
+ key,
+ visibleVal,
+ skipVals,
+ keepCacheObjects,
+ deserializePortable,
+ false);
}
}
}
@@ -1720,7 +1721,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
@Override public <K, V> IgniteInternalFuture<Map<K, V>> getAllAsync(
final GridCacheContext cacheCtx,
Collection<KeyCacheObject> keys,
- @Nullable GridCacheEntryEx cached,
final boolean deserializePortable,
final boolean skipVals,
final boolean keepCacheObjects,
@@ -1747,7 +1747,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
final Collection<KeyCacheObject> lockKeys = enlistRead(cacheCtx,
keys,
- cached,
expiryPlc,
retMap,
missed,
@@ -1850,20 +1849,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
txEntry.cached(entryEx(cacheCtx, txKey));
}
- catch (GridCacheFilterFailedException e) {
- // Failed value for the filter.
- CacheObject val = e.value();
-
- if (val != null) {
- // If filter fails after lock is acquired, we don't reload,
- // regardless if value is null or not.
- missed.remove(cacheKey);
-
- txEntry.setAndMarkValid(val);
- }
-
- break; // While.
- }
}
}
@@ -1871,7 +1856,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
return checkMissed(cacheCtx,
retMap,
missed,
- null,
deserializePortable,
skipVals,
keepCacheObjects,
@@ -1920,8 +1904,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
else {
assert optimistic() || readCommitted() || skipVals;
- final Collection<KeyCacheObject> redos = new ArrayList<>();
-
if (!missed.isEmpty()) {
if (!readCommitted())
for (Iterator<KeyCacheObject> it = missed.keySet().iterator(); it.hasNext(); ) {
@@ -1937,67 +1919,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (missed.isEmpty())
return new GridFinishedFuture<>(retMap);
- IgniteInternalFuture<Map<K, V>> fut0 = checkMissed(cacheCtx,
+ return checkMissed(cacheCtx,
retMap,
missed,
- redos,
deserializePortable,
skipVals,
keepCacheObjects,
skipStore);
-
- return new GridEmbeddedFuture<>(
- // First future.
- fut0,
- // Closure that returns another future, based on result from first.
- new PMC<Map<K, V>>() {
- @Override public IgniteInternalFuture<Map<K, V>> postMiss(Map<K, V> map) {
- if (redos.isEmpty())
- return new GridFinishedFuture<>(
- Collections.<K, V>emptyMap());
-
- if (log.isDebugEnabled())
- log.debug("Starting to future-recursively get values for keys: " + redos);
-
- // Future recursion.
- return getAllAsync(cacheCtx,
- redos,
- null,
- deserializePortable,
- skipVals,
- true,
- skipStore);
- }
- },
- // Finalize.
- new FinishClosure<Map<K, V>>() {
- @Override Map<K, V> finish(Map<K, V> loaded) {
- for (Map.Entry<K, V> entry : loaded.entrySet()) {
- KeyCacheObject cacheKey = (KeyCacheObject)entry.getKey();
-
- IgniteTxEntry txEntry = entry(cacheCtx.txKey(cacheKey));
-
- CacheObject val = (CacheObject)entry.getValue();
-
- if (!readCommitted())
- txEntry.readValue(val);
-
- if (!F.isEmpty(txEntry.entryProcessors()))
- val = txEntry.applyEntryProcessors(val);
-
- cacheCtx.addResult(retMap,
- cacheKey,
- val,
- skipVals,
- keepCacheObjects,
- deserializePortable,
- false);
- }
-
- return retMap;
- }
- }
- );
}
return new GridFinishedFuture<>(retMap);
@@ -2016,8 +1944,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
GridCacheContext cacheCtx,
Map<? extends K, ? extends V> map,
boolean retval,
- @Nullable GridCacheEntryEx cached,
- long ttl,
CacheEntryPredicate[] filter
) {
return (IgniteInternalFuture<GridCacheReturn>)putAllAsync0(cacheCtx,
@@ -2026,7 +1952,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
null,
null,
retval,
- cached,
filter);
}
@@ -2041,7 +1966,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
null,
drMap,
false,
- null,
null);
}
@@ -2058,7 +1982,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
invokeArgs,
null,
true,
- null,
null);
}
@@ -2067,20 +1990,24 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
GridCacheContext cacheCtx,
Map<KeyCacheObject, GridCacheVersion> drMap
) {
- return removeAllAsync0(cacheCtx, null, drMap, null, false, null);
+ return removeAllAsync0(cacheCtx, null, drMap, false, null, false);
}
/**
* Checks filter for non-pessimistic transactions.
*
- * @param cached Cached entry.
+ * @param cctx Cache context.
+ * @param key Key.
+ * @param val Value.
* @param filter Filter to check.
* @return {@code True} if passed or pessimistic.
- * @throws IgniteCheckedException If failed.
*/
- private <K, V> boolean filter(GridCacheEntryEx cached,
- CacheEntryPredicate[] filter) throws IgniteCheckedException {
- return pessimistic() || (optimistic() && implicit()) || cached.context().isAll(cached, filter);
+ private boolean filter(
+ GridCacheContext cctx,
+ KeyCacheObject key,
+ CacheObject val,
+ CacheEntryPredicate[] filter) {
+ return pessimistic() || (optimistic() && implicit()) || isAll(cctx, key, val, filter);
}
/**
@@ -2088,7 +2015,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
*
* @param cacheCtx Cache context.
* @param keys Keys to enlist.
- * @param cached Cached entry.
* @param expiryPlc Explicitly specified expiry policy for entry.
* @param implicit Implicit flag.
* @param lookup Value lookup map ({@code null} for remove).
@@ -2102,28 +2028,28 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @param drPutMap DR put map (optional).
* @param drRmvMap DR remove map (optional).
* @param skipStore Skip store flag.
+ * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
* @return Future with skipped keys (the ones that didn't pass filter for pessimistic transactions).
*/
- protected <K, V> IgniteInternalFuture<Set<KeyCacheObject>> enlistWrite(
+ private <K, V> IgniteInternalFuture<Set<KeyCacheObject>> enlistWrite(
final GridCacheContext cacheCtx,
Collection<?> keys,
- @Nullable GridCacheEntryEx cached,
@Nullable ExpiryPolicy expiryPlc,
boolean implicit,
@Nullable Map<?, ?> lookup,
@Nullable Map<?, EntryProcessor<K, V, Object>> invokeMap,
@Nullable Object[] invokeArgs,
- boolean retval,
+ final boolean retval,
boolean lockOnly,
- CacheEntryPredicate[] filter,
+ final CacheEntryPredicate[] filter,
final GridCacheReturn ret,
Collection<KeyCacheObject> enlisted,
@Nullable Map<KeyCacheObject, GridCacheDrInfo> drPutMap,
@Nullable Map<KeyCacheObject, GridCacheVersion> drRmvMap,
- boolean skipStore
+ boolean skipStore,
+ final boolean singleRmv
) {
- assert cached == null || keys.size() == 1;
- assert cached == null || F.first(keys).equals(cached.key());
+ assert retval || invokeMap == null;
try {
addActiveCache(cacheCtx);
@@ -2138,6 +2064,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
Set<KeyCacheObject> missedForLoad = null;
+ final boolean hasFilters = !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
+ final boolean needVal = singleRmv || retval || hasFilters;
+ final boolean needReadVer = needVal && (serializable() && optimistic());
+
try {
// Set transform flag for transaction.
if (invokeMap != null)
@@ -2194,19 +2124,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
// First time access.
if (txEntry == null) {
while (true) {
- GridCacheEntryEx entry = null;
+ GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topologyVersion());
try {
- if (cached != null) {
- entry = cached;
-
- cached = null;
- }
- else {
- entry = entryEx(cacheCtx, txKey, topologyVersion());
-
- entry.unswap(false);
- }
+ entry.unswap(false);
// Check if lock is being explicitly acquired by the same thread.
if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() &&
@@ -2217,45 +2138,57 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
", locNodeId=" + cctx.localNodeId() + ']');
CacheObject old = null;
-
- boolean readThrough = !skipStore && !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
+ GridCacheVersion readVer = null;
if (optimistic() && !implicit()) {
try {
- // Should read through if filter is specified.
- old = entry.innerGet(this,
- /*swap*/false,
- /*read-through*/readThrough && cacheCtx.loadPreviousValue(),
- /*fail-fast*/false,
- /*unmarshal*/retval,
- /*metrics*/retval,
- /*events*/retval,
- /*temporary*/false,
- CU.subjectId(this, cctx),
- entryProcessor,
- resolveTaskName(),
- null);
+ if (needReadVer) {
+ T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
+ entry.innerGetVersioned(this,
+ /*swap*/false,
+ /*unmarshal*/retval,
+ /*metrics*/retval,
+ /*events*/retval,
+ CU.subjectId(this, cctx),
+ entryProcessor,
+ resolveTaskName(),
+ null) : null;
+
+ if (res != null) {
+ old = res.get1();
+ readVer = res.get2();
+ }
+ }
+ else {
+ old = entry.innerGet(this,
+ /*swap*/false,
+ /*read-through*/false,
+ /*fail-fast*/false,
+ /*unmarshal*/retval,
+ /*metrics*/retval,
+ /*events*/retval,
+ /*temporary*/false,
+ CU.subjectId(this, cctx),
+ entryProcessor,
+ resolveTaskName(),
+ null);
+ }
}
catch (ClusterTopologyCheckedException e) {
entry.context().evicts().touch(entry, topologyVersion());
throw e;
}
- catch (GridCacheFilterFailedException e) {
- e.printStackTrace();
-
- assert false : "Empty filter failed: " + e;
- }
}
else
old = retval ? entry.rawGetOrUnmarshal(false) : entry.rawGet();
- if (!filter(entry, filter)) {
+ if (old != null && hasFilters && !filter(entry.context(), cacheKey, old, filter)) {
skipped = skip(skipped, cacheKey);
ret.set(cacheCtx, old, false);
- if (!readCommitted() && old != null) {
+ if (!readCommitted()) {
// Enlist failed filters as reads for non-read-committed mode,
// so future ops will get the same values.
txEntry = addEntry(READ,
@@ -2272,9 +2205,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
skipStore);
txEntry.markValid();
+
+ if (needReadVer) {
+ assert readVer != null;
+
+ txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
+ }
}
- if (readCommitted() || old == null)
+ if (readCommitted())
cacheCtx.evicts().touch(entry, topologyVersion());
break; // While.
@@ -2305,9 +2244,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
txEntry.markValid();
if (old == null) {
- boolean load = retval && !readThrough;
-
- if (load) {
+ if (needVal) {
if (missedForLoad == null)
missedForLoad = new HashSet<>();
@@ -2324,6 +2261,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
}
else {
+ if (needReadVer) {
+ assert readVer != null;
+
+ txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
+ }
+
if (retval && !transform)
ret.set(cacheCtx, old, true);
else {
@@ -2369,7 +2312,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
else {
if (entryProcessor == null && txEntry.op() == TRANSFORM)
throw new IgniteCheckedException("Failed to enlist write value for key (cannot have update value in " +
- "transaction after transform closure is applied): " + key);
+ "transaction after EntryProcessor is applied): " + key);
GridCacheEntryEx entry = txEntry.cached();
@@ -2378,7 +2321,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
boolean del = txEntry.op() == DELETE && rmv;
if (!del) {
- if (!filter(entry, filter)) {
+ if (hasFilters && !filter(entry.context(), cacheKey, v, filter)) {
skipped = skip(skipped, cacheKey);
ret.set(cacheCtx, v, false);
@@ -2439,15 +2382,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
if (missedForLoad != null) {
- IgniteInternalFuture<Boolean> fut = loadMissing(
+ final boolean skipVals = singleRmv;
+
+ IgniteInternalFuture<Void> fut = loadMissing(
cacheCtx,
/*read through*/cacheCtx.config().isLoadPreviousValue() && !skipStore,
/*async*/true,
missedForLoad,
- deserializePortables(cacheCtx),
- /*skip values*/false,
- new CI2<KeyCacheObject, Object>() {
- @Override public void apply(KeyCacheObject key, Object val) {
+ skipVals,
+ needReadVer,
+ new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
+ @Override public void apply(KeyCacheObject key,
+ @Nullable Object val,
+ @Nullable GridCacheVersion loadVer) {
if (log.isDebugEnabled())
log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
@@ -2455,33 +2402,50 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
assert e != null;
- CacheObject cacheVal = cacheCtx.toCacheObject(val);
+ if (needReadVer) {
+ assert loadVer != null;
- if (e.op() == TRANSFORM) {
- GridCacheVersion ver;
+ e.serializableReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
+ }
- try {
- ver = e.cached().version();
- }
- catch (GridCacheEntryRemovedException ex) {
- assert optimistic() : e;
+ if (singleRmv) {
+ assert !hasFilters && !retval;
+ assert val == null || Boolean.TRUE.equals(val) : val;
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
+ ret.set(cacheCtx, null, val != null);
+ }
+ else {
+ CacheObject cacheVal = cacheCtx.toCacheObject(val);
- ver = null;
+ if (e.op() == TRANSFORM) {
+ GridCacheVersion ver;
+
+ try {
+ ver = e.cached().version();
+ }
+ catch (GridCacheEntryRemovedException ex) {
+ assert optimistic() : e;
+
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
+
+ ver = null;
+ }
+
+ addInvokeResult(e, cacheVal, ret, ver);
}
+ else {
+ boolean success = !hasFilters || isAll(e.context(), key, cacheVal, filter);
- addInvokeResult(e, cacheVal, ret, ver);
+ ret.set(cacheCtx, cacheVal, success);
+ }
}
- else
- ret.set(cacheCtx, cacheVal, true);
}
});
return new GridEmbeddedFuture<>(
- new C2<Boolean, Exception, Set<KeyCacheObject>>() {
- @Override public Set<KeyCacheObject> apply(Boolean b, Exception e) {
+ new C2<Void, Exception, Set<KeyCacheObject>>() {
+ @Override public Set<KeyCacheObject> apply(Void b, Exception e) {
if (e != null)
throw new GridClosureException(e);
@@ -2495,6 +2459,31 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @param cctx Cache context.
+ * @param key Key.
+ * @param val Value.
+ * @param filter Filter.
+ * @return {@code True} if filter passed.
+ */
+ private boolean isAll(GridCacheContext cctx,
+ KeyCacheObject key,
+ CacheObject val,
+ CacheEntryPredicate[] filter) {
+ GridCacheEntryEx e = new GridDhtDetachedCacheEntry(cctx, key, 0, val, null, 0) {
+ @Nullable @Override public CacheObject peekVisibleValue() {
+ return rawGet();
+ }
+ };
+
+ for (CacheEntryPredicate p0 : filter) {
+ if (p0 != null && !p0.apply(e))
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
* Post lock processing for put or remove.
*
* @param cacheCtx Context.
@@ -2555,29 +2544,22 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (retval || invoke) {
if (!cacheCtx.isNear()) {
- try {
- if (!hasPrevVal) {
- boolean readThrough =
- (invoke || cacheCtx.loadPreviousValue()) && !txEntry.skipStore();
-
- v = cached.innerGet(this,
- /*swap*/true,
- readThrough,
- /*failFast*/false,
- /*unmarshal*/true,
- /*metrics*/!invoke,
- /*event*/!invoke && !dht(),
- /*temporary*/false,
- CU.subjectId(this, cctx),
- null,
- resolveTaskName(),
- null);
- }
- }
- catch (GridCacheFilterFailedException e) {
- e.printStackTrace();
-
- assert false : "Empty filter failed: " + e;
+ if (!hasPrevVal) {
+ boolean readThrough =
+ (invoke || cacheCtx.loadPreviousValue()) && !txEntry.skipStore();
+
+ v = cached.innerGet(this,
+ /*swap*/true,
+ readThrough,
+ /*failFast*/false,
+ /*unmarshal*/true,
+ /*metrics*/!invoke,
+ /*event*/!invoke && !dht(),
+ /*temporary*/false,
+ CU.subjectId(this, cctx),
+ null,
+ resolveTaskName(),
+ null);
}
}
else {
@@ -2725,7 +2707,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @param invokeArgs Optional arguments for EntryProcessor.
* @param drMap DR map.
* @param retval Key-transform value map to store.
- * @param cached Cached entry, if any.
* @param filter Filter.
* @return Operation future.
*/
@@ -2737,7 +2718,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
@Nullable final Object[] invokeArgs,
@Nullable final Map<KeyCacheObject, GridCacheDrInfo> drMap,
final boolean retval,
- @Nullable GridCacheEntryEx cached,
@Nullable final CacheEntryPredicate[] filter
) {
assert filter == null || invokeMap == null;
@@ -2778,8 +2758,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
log.debug("Called putAllAsync(...) [tx=" + this + ", map=" + map0 + ", retval=" + retval + "]");
assert map0 != null || invokeMap0 != null;
- assert cached == null ||
- (map0 != null && map0.size() == 1) || (invokeMap0 != null && invokeMap0.size() == 1);
try {
checkValid();
@@ -2814,7 +2792,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
cacheCtx,
keySet,
- cached,
opCtx != null ? opCtx.expiry() : null,
implicit,
map0,
@@ -2827,7 +2804,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
enlisted,
drMap,
null,
- opCtx != null && opCtx.skipStore());
+ opCtx != null && opCtx.skipStore(),
+ false);
if (pessimistic()) {
// Loose all skipped.
@@ -2921,8 +2899,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
else
return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Set<KeyCacheObject>>, GridCacheReturn>() {
- @Override
- public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f) throws IgniteCheckedException {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f) throws IgniteCheckedException {
f.get();
return ret;
@@ -2951,11 +2928,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
@Override public <K, V> IgniteInternalFuture<GridCacheReturn> removeAllAsync(
GridCacheContext cacheCtx,
Collection<? extends K> keys,
- @Nullable GridCacheEntryEx cached,
boolean retval,
- CacheEntryPredicate[] filter
+ CacheEntryPredicate[] filter,
+ boolean singleRmv
) {
- return removeAllAsync0(cacheCtx, keys, null, cached, retval, filter);
+ return removeAllAsync0(cacheCtx, keys, null, retval, filter, singleRmv);
}
/**
@@ -2963,8 +2940,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @param keys Keys to remove.
* @param drMap DR map.
* @param retval Flag indicating whether a value should be returned.
- * @param cached Cached entry, if any. Will be provided only if size of keys collection is 1.
* @param filter Filter.
+ * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
* @return Future for asynchronous remove.
*/
@SuppressWarnings("unchecked")
@@ -2972,9 +2949,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
final GridCacheContext cacheCtx,
@Nullable final Collection<? extends K> keys,
@Nullable Map<KeyCacheObject, GridCacheVersion> drMap,
- @Nullable GridCacheEntryEx cached,
final boolean retval,
- @Nullable final CacheEntryPredicate[] filter) {
+ @Nullable final CacheEntryPredicate[] filter,
+ boolean singleRmv) {
try {
checkUpdatesAllowed(cacheCtx);
}
@@ -2998,7 +2975,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
keys0 = keys;
assert keys0 != null;
- assert cached == null || keys0.size() == 1;
if (log.isDebugEnabled())
log.debug("Called removeAllAsync(...) [tx=" + this + ", keys=" + keys0 + ", implicit=" + implicit +
@@ -3043,7 +3019,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
cacheCtx,
keys0,
- /** cached entry */null,
plc,
implicit,
/** lookup map */null,
@@ -3056,7 +3031,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
enlisted,
null,
drMap,
- opCtx != null && opCtx.skipStore()
+ opCtx != null && opCtx.skipStore(),
+ singleRmv
);
if (log.isDebugEnabled())
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
index 6f72290..0d83338 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
@@ -19,17 +19,17 @@ package org.apache.ignite.internal.processors.cache.transactions;
import java.util.Collection;
import java.util.Map;
+import javax.cache.Cache;
import javax.cache.processor.EntryProcessor;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheReturn;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
-import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.internal.util.lang.GridInClosure3;
import org.jetbrains.annotations.Nullable;
/**
@@ -64,8 +64,6 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
/**
* @param cacheCtx Cache context.
* @param keys Keys to get.
- * @param cached Cached entry if this method is called from entry wrapper
- * Cached entry is passed if and only if there is only one key in collection of keys.
* @param deserializePortable Deserialize portable flag.
* @param skipVals Skip values flag.
* @param keepCacheObjects Keep cache objects
@@ -75,7 +73,6 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
public <K, V> IgniteInternalFuture<Map<K, V>> getAllAsync(
GridCacheContext cacheCtx,
Collection<KeyCacheObject> keys,
- @Nullable GridCacheEntryEx cached,
boolean deserializePortable,
boolean skipVals,
boolean keepCacheObjects,
@@ -85,17 +82,13 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
* @param cacheCtx Cache context.
* @param map Map to put.
* @param retval Flag indicating whether a value should be returned.
- * @param cached Cached entry, if any. Will be provided only if map has size 1.
* @param filter Filter.
- * @param ttl Time to live for entry. If negative, leave unchanged.
* @return Future for put operation.
*/
public <K, V> IgniteInternalFuture<GridCacheReturn> putAllAsync(
GridCacheContext cacheCtx,
Map<? extends K, ? extends V> map,
boolean retval,
- @Nullable GridCacheEntryEx cached,
- long ttl,
CacheEntryPredicate[] filter);
/**
@@ -113,16 +106,16 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
* @param cacheCtx Cache context.
* @param keys Keys to remove.
* @param retval Flag indicating whether a value should be returned.
- * @param cached Cached entry, if any. Will be provided only if size of keys collection is 1.
* @param filter Filter.
+ * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
* @return Future for asynchronous remove.
*/
public <K, V> IgniteInternalFuture<GridCacheReturn> removeAllAsync(
GridCacheContext cacheCtx,
Collection<? extends K> keys,
- @Nullable GridCacheEntryEx cached,
boolean retval,
- CacheEntryPredicate[] filter);
+ CacheEntryPredicate[] filter,
+ boolean singleRmv);
/**
* @param cacheCtx Cache context.
@@ -161,17 +154,17 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
* @param readThrough Read through flag.
* @param async if {@code True}, then loading will happen in a separate thread.
* @param keys Keys.
- * @param c Closure.
- * @param deserializePortable Deserialize portable flag.
* @param skipVals Skip values flag.
+ * @param needVer If {@code true} version is required for loaded values.
+ * @param c Closure to be applied for loaded values.
* @return Future with {@code True} value if loading took place.
*/
- public IgniteInternalFuture<Boolean> loadMissing(
+ public IgniteInternalFuture<Void> loadMissing(
GridCacheContext cacheCtx,
boolean readThrough,
boolean async,
Collection<KeyCacheObject> keys,
- boolean deserializePortable,
boolean skipVals,
- IgniteBiInClosure<KeyCacheObject, Object> c);
+ boolean needVer,
+ GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c);
}
\ No newline at end of file
[09/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
new file mode 100644
index 0000000..70ddfa0
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
@@ -0,0 +1,4295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.cache.Cache;
+import javax.cache.CacheException;
+import javax.cache.configuration.Factory;
+import javax.cache.integration.CacheLoaderException;
+import javax.cache.processor.EntryProcessor;
+import javax.cache.processor.EntryProcessorResult;
+import javax.cache.processor.MutableEntry;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.store.CacheStore;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteClosure;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.spi.swapspace.inmemory.GridTestSwapSpaceSpi;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.jsr166.ConcurrentHashMap8;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheMode.REPLICATED;
+import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.testframework.GridTestUtils.TestMemoryMode;
+import static org.apache.ignite.testframework.GridTestUtils.runMultiThreadedAsync;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
+ /** */
+ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ private static final boolean FAST = false;
+
+ /** */
+ private static Map<Integer, Integer> storeMap = new ConcurrentHashMap8<>();
+
+ /** */
+ private static final int SRVS = 4;
+
+ /** */
+ private static final int CLIENTS = 3;
+
+ /** */
+ private boolean client;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ cfg.setPeerClassLoadingEnabled(false);
+
+ ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
+
+ cfg.setClientMode(client);
+
+ cfg.setSwapSpaceSpi(new GridTestSwapSpaceSpi());
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGridsMultiThreaded(SRVS);
+
+ client = true;
+
+ startGridsMultiThreaded(SRVS, CLIENTS);
+
+ client = false;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected long getTestTimeout() {
+ return 5 * 60_000;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxStreamerLoad() throws Exception {
+ txStreamerLoad(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxStreamerLoadAllowOverwrite() throws Exception {
+ txStreamerLoad(true);
+ }
+
+ /**
+ * @param allowOverwrite Streamer flag.
+ * @throws Exception If failed.
+ */
+ private void txStreamerLoad(boolean allowOverwrite) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ if (ccfg.getCacheStoreFactory() == null)
+ continue;
+
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys)
+ txStreamerLoad(ignite0, key, cache.getName(), allowOverwrite);
+
+ txStreamerLoad(ignite(SRVS), 10_000, cache.getName(), allowOverwrite);
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @param ignite Node.
+ * @param key Key.
+ * @param cacheName Cache name.
+ * @param allowOverwrite Streamer flag.
+ * @throws Exception If failed.
+ */
+ private void txStreamerLoad(Ignite ignite,
+ Integer key,
+ String cacheName,
+ boolean allowOverwrite) throws Exception {
+ IgniteCache<Integer, Integer> cache = ignite.cache(cacheName);
+
+ log.info("Test key: " + key);
+
+ Integer loadVal = -1;
+
+ IgniteTransactions txs = ignite.transactions();
+
+ try (IgniteDataStreamer<Integer, Integer> streamer = ignite.dataStreamer(cache.getName())) {
+ streamer.allowOverwrite(allowOverwrite);
+
+ streamer.addData(key, loadVal);
+ }
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertEquals(loadVal, val);
+
+ tx.commit();
+ }
+
+ checkValue(key, loadVal, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertEquals(loadVal, val);
+
+ cache.put(key, 0);
+
+ tx.commit();
+ }
+
+ checkValue(key, 0, cache.getName());
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxLoadFromStore() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ if (ccfg.getCacheStoreFactory() == null)
+ continue;
+
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ Integer storeVal = -1;
+
+ storeMap.put(key, storeVal);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertEquals(storeVal, val);
+
+ tx.commit();
+ }
+
+ checkValue(key, storeVal, cache.getName());
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertNull(val);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxCommitReadOnly1() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertNull(val);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertNull(val);
+
+ tx.rollback();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 1);
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertNull(val);
+
+ tx.commit();
+ }
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxCommitReadOnly2() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (final Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertNull(val);
+
+ txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.get(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertNull(val);
+
+ txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.get(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxCommit() throws Exception {
+ Ignite ignite0 = ignite(0);
+ Ignite ignite1 = ignite(1);
+
+ final IgniteTransactions txs0 = ignite0.transactions();
+ final IgniteTransactions txs1 = ignite1.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache0 = ignite0.createCache(ccfg);
+ IgniteCache<Integer, Integer> cache1 = ignite1.cache(ccfg.getName());
+
+ List<Integer> keys = testKeys(cache0);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ Integer expVal = null;
+
+ for (int i = 0; i < 100; i++) {
+ try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache0.get(key);
+
+ assertEquals(expVal, val);
+
+ cache0.put(key, i);
+
+ tx.commit();
+
+ expVal = i;
+ }
+
+ try (Transaction tx = txs1.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache1.get(key);
+
+ assertEquals(expVal, val);
+
+ cache1.put(key, val);
+
+ tx.commit();
+ }
+
+ try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache0.get(key);
+
+ assertEquals(expVal, val);
+
+ cache0.put(key, val);
+
+ tx.commit();
+ }
+ }
+
+ checkValue(key, expVal, cache0.getName());
+
+ cache0.remove(key);
+
+ try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache0.get(key);
+
+ assertNull(val);
+
+ cache0.put(key, expVal + 1);
+
+ tx.commit();
+ }
+
+ checkValue(key, expVal + 1, cache0.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxRollback() throws Exception {
+ Ignite ignite0 = ignite(0);
+ Ignite ignite1 = ignite(1);
+
+ final IgniteTransactions txs0 = ignite0.transactions();
+ final IgniteTransactions txs1 = ignite1.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache0 = ignite0.createCache(ccfg);
+ IgniteCache<Integer, Integer> cache1 = ignite1.cache(ccfg.getName());
+
+ List<Integer> keys = testKeys(cache0);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ Integer expVal = null;
+
+ for (int i = 0; i < 100; i++) {
+ try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache0.get(key);
+
+ assertEquals(expVal, val);
+
+ cache0.put(key, i);
+
+ tx.rollback();
+ }
+
+ try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache0.get(key);
+
+ assertEquals(expVal, val);
+
+ cache0.put(key, i);
+
+ tx.commit();
+
+ expVal = i;
+ }
+
+ try (Transaction tx = txs1.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache1.get(key);
+
+ assertEquals(expVal, val);
+
+ cache1.put(key, val);
+
+ tx.commit();
+ }
+ }
+
+ checkValue(key, expVal, cache0.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxCommitReadOnlyGetAll() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ Set<Integer> keys = new HashSet<>();
+
+ for (int i = 0; i < 100; i++)
+ keys.add(i);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Map<Integer, Integer> map = cache.getAll(keys);
+
+ assertTrue(map.isEmpty());
+
+ tx.commit();
+ }
+
+ for (Integer key : keys)
+ checkValue(key, null, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Map<Integer, Integer> map = cache.getAll(keys);
+
+ assertTrue(map.isEmpty());
+
+ tx.rollback();
+ }
+
+ for (Integer key : keys)
+ checkValue(key, null, cache.getName());
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxCommitReadWriteTwoNodes() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ Integer key0 = primaryKey(ignite(0).cache(null));
+ Integer key1 = primaryKey(ignite(1).cache(null));
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key0, key0);
+
+ cache.get(key1);
+
+ tx.commit();
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictRead1() throws Exception {
+ txConflictRead(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictRead2() throws Exception {
+ txConflictRead(false);
+ }
+
+ /**
+ * @param noVal If {@code true} there is no cache value when read in tx.
+ * @throws Exception If failed.
+ */
+ private void txConflictRead(boolean noVal) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ Integer expVal = null;
+
+ if (!noVal) {
+ expVal = -1;
+
+ cache.put(key, expVal);
+ }
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertEquals(expVal, val);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object val = cache.get(key);
+
+ assertEquals(1, val);
+
+ tx.commit();
+ }
+
+ checkValue(key, 1, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictReadWrite1() throws Exception {
+ txConflictReadWrite(true, false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictReadWrite2() throws Exception {
+ txConflictReadWrite(false, false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictReadRemove1() throws Exception {
+ txConflictReadWrite(true, true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictReadRemove2() throws Exception {
+ txConflictReadWrite(false, true);
+ }
+
+ /**
+ * @param noVal If {@code true} there is no cache value when read in tx.
+ * @param rmv If {@code true} tests remove, otherwise put.
+ * @throws Exception If failed.
+ */
+ private void txConflictReadWrite(boolean noVal, boolean rmv) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ Integer expVal = null;
+
+ if (!noVal) {
+ expVal = -1;
+
+ cache.put(key, expVal);
+ }
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertEquals(expVal, val);
+
+ updateKey(cache, key, 1);
+
+ if (rmv)
+ cache.remove(key);
+ else
+ cache.put(key, 2);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.get(key);
+
+ assertEquals(1, (Object) val);
+
+ if (rmv)
+ cache.remove(key);
+ else
+ cache.put(key, 2);
+
+ tx.commit();
+ }
+
+ checkValue(key, rmv ? null : 2, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictGetAndPut1() throws Exception {
+ txConflictGetAndPut(true, false);
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictGetAndPut2() throws Exception {
+ txConflictGetAndPut(false, false);
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictGetAndRemove1() throws Exception {
+ txConflictGetAndPut(true, true);
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictGetAndRemove2() throws Exception {
+ txConflictGetAndPut(false, true);
+ }
+
+ /**
+ * @param noVal If {@code true} there is no cache value when read in tx.
+ * @param rmv If {@code true} tests remove, otherwise put.
+ * @throws Exception If failed.
+ */
+ private void txConflictGetAndPut(boolean noVal, boolean rmv) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ Integer expVal = null;
+
+ if (!noVal) {
+ expVal = -1;
+
+ cache.put(key, expVal);
+ }
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = rmv ? cache.getAndRemove(key) : cache.getAndPut(key, 2);
+
+ assertEquals(expVal, val);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object val = rmv ? cache.getAndRemove(key) : cache.getAndPut(key, 2);
+
+ assertEquals(1, val);
+
+ tx.commit();
+ }
+
+ checkValue(key, rmv ? null : 2, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictInvoke1() throws Exception {
+ txConflictInvoke(true, false);
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictInvoke2() throws Exception {
+ txConflictInvoke(false, false);
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictInvoke3() throws Exception {
+ txConflictInvoke(true, true);
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictInvoke4() throws Exception {
+ txConflictInvoke(false, true);
+ }
+
+ /**
+ * @param noVal If {@code true} there is no cache value when read in tx.
+ * @param rmv If {@code true} invoke does remove value, otherwise put.
+ * @throws Exception If failed.
+ */
+ private void txConflictInvoke(boolean noVal, boolean rmv) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ Integer expVal = null;
+
+ if (!noVal) {
+ expVal = -1;
+
+ cache.put(key, expVal);
+ }
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Integer val = cache.invoke(key, new SetValueProcessor(rmv ? null : 2));
+
+ assertEquals(expVal, val);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object val = cache.invoke(key, new SetValueProcessor(rmv ? null : 2));
+
+ assertEquals(1, val);
+
+ tx.commit();
+ }
+
+ checkValue(key, rmv ? null : 2, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed
+ */
+ public void testTxConflictInvokeAll() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache0 = ignite0.createCache(ccfg);
+
+ final Integer key1 = primaryKey(ignite(0).cache(cache0.getName()));
+ final Integer key2 = primaryKey(ignite(1).cache(cache0.getName()));
+
+ Map<Integer, Integer> vals = new HashMap<>();
+
+ int newVal = 0;
+
+ for (Ignite ignite : G.allGrids()) {
+ log.info("Test node: " + ignite.name());
+
+ IgniteTransactions txs = ignite.transactions();
+
+ IgniteCache<Integer, Integer> cache = ignite.cache(cache0.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Map<Integer, EntryProcessorResult<Integer>> res =
+ cache.invokeAll(F.asSet(key1, key2), new SetValueProcessor(newVal));
+
+ if (!vals.isEmpty()) {
+ EntryProcessorResult<Integer> res1 = res.get(key1);
+
+ assertNotNull(res1);
+ assertEquals(vals.get(key1), res1.get());
+
+ EntryProcessorResult<Integer> res2 = res.get(key2);
+
+ assertNotNull(res2);
+ assertEquals(vals.get(key2), res2.get());
+ }
+ else
+ assertTrue(res.isEmpty());
+
+ tx.commit();
+ }
+
+ checkValue(key1, newVal, cache.getName());
+ checkValue(key2, newVal, cache.getName());
+
+ vals.put(key1, newVal);
+ vals.put(key2, newVal);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Map<Integer, EntryProcessorResult<Integer>> res =
+ cache.invokeAll(F.asSet(key1, key2), new SetValueProcessor(newVal + 1));
+
+ EntryProcessorResult<Integer> res1 = res.get(key1);
+
+ assertNotNull(res1);
+ assertEquals(vals.get(key1), res1.get());
+
+ EntryProcessorResult<Integer> res2 = res.get(key2);
+
+ assertNotNull(res2);
+ assertEquals(vals.get(key2), res2.get());
+
+ updateKey(cache0, key1, -1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key1, -1, cache.getName());
+ checkValue(key2, newVal, cache.getName());
+
+ vals.put(key1, -1);
+ vals.put(key2, newVal);
+
+ newVal++;
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictPutIfAbsent() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean put = cache.putIfAbsent(key, 2);
+
+ assertTrue(put);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean put = cache.putIfAbsent(key, 2);
+
+ assertFalse(put);
+
+ tx.commit();
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean put = cache.putIfAbsent(key, 2);
+
+ assertTrue(put);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean put = cache.putIfAbsent(key, 2);
+
+ assertFalse(put);
+
+ updateKey(cache, key, 3);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 3, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictGetAndPutIfAbsent() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndPutIfAbsent(key, 2);
+
+ assertNull(old);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndPutIfAbsent(key, 2);
+
+ assertEquals(1, old);
+
+ tx.commit();
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndPutIfAbsent(key, 2);
+
+ assertNull(old);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndPutIfAbsent(key, 4);
+
+ assertEquals(2, old);
+
+ updateKey(cache, key, 3);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 3, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictReplace() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (final Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2);
+
+ assertFalse(replace);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2);
+
+ assertTrue(replace);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2);
+
+ assertFalse(replace);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2);
+
+ assertFalse(replace);
+
+ updateKey(cache, key, 3);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 3, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2);
+
+ assertTrue(replace);
+
+ txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.remove(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 1);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2);
+
+ assertTrue(replace);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictGetAndReplace() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (final Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndReplace(key, 2);
+
+ assertNull(old);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndReplace(key, 2);
+
+ assertEquals(1, old);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndReplace(key, 2);
+
+ assertNull(old);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndReplace(key, 2);
+
+ assertNull(old);
+
+ updateKey(cache, key, 3);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 3, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndReplace(key, 2);
+
+ assertEquals(3, old);
+
+ txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.remove(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 1);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object old = cache.getAndReplace(key, 2);
+
+ assertEquals(1, old);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictRemoveWithOldValue() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (final Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean rmv = cache.remove(key, 2);
+
+ assertFalse(rmv);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean rmv = cache.remove(key, 1);
+
+ assertTrue(rmv);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean rmv = cache.remove(key, 2);
+
+ assertFalse(rmv);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 2);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean rmv = cache.remove(key, 2);
+
+ assertTrue(rmv);
+
+ updateKey(cache, key, 3);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 3, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean rmv = cache.remove(key, 3);
+
+ assertTrue(rmv);
+
+ txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.remove(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 1);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean rmv = cache.remove(key, 2);
+
+ assertFalse(rmv);
+
+ tx.commit();
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean rmv = cache.remove(key, 1);
+
+ assertTrue(rmv);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictCasReplace() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (final Integer key : keys) {
+ log.info("Test key: " + key);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 1, 2);
+
+ assertFalse(replace);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 1, 2);
+
+ assertTrue(replace);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 1, 2);
+
+ assertFalse(replace);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 2);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2, 1);
+
+ assertTrue(replace);
+
+ updateKey(cache, key, 3);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, 3, cache.getName());
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 3, 4);
+
+ assertTrue(replace);
+
+ txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.remove(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 1);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 2, 3);
+
+ assertFalse(replace);
+
+ tx.commit();
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean replace = cache.replace(key, 1, 3);
+
+ assertTrue(replace);
+
+ tx.commit();
+ }
+
+ checkValue(key, 3, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictRemoveReturnBoolean1() throws Exception {
+ txConflictRemoveReturnBoolean(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictRemoveReturnBoolean2() throws Exception {
+ txConflictRemoveReturnBoolean(true);
+ }
+
+ /**
+ * @param noVal If {@code true} there is no cache value when do update in tx.
+ * @throws Exception If failed.
+ */
+ private void txConflictRemoveReturnBoolean(boolean noVal) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (final Integer key : keys) {
+ log.info("Test key: " + key);
+
+ if (!noVal)
+ cache.put(key, -1);
+
+ if (noVal) {
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.remove(key);
+
+ assertFalse(res);
+
+ updateKey(cache, key, -1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, -1, cache.getName());
+ }
+ else {
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.remove(key);
+
+ assertTrue(res);
+
+ txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.remove(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, -1);
+ }
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.remove(key);
+
+ assertTrue(res);
+
+ updateKey(cache, key, 2);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ // Check no conflict for removeAll with single key.
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.removeAll(Collections.singleton(key));
+
+ txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ cache.remove(key);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ cache.put(key, 2);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.remove(key);
+
+ assertTrue(res);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.remove(key);
+
+ assertFalse(res);
+
+ tx.commit();
+ }
+
+ checkValue(key, null, cache.getName());
+
+ try {
+ cache.put(key, 1);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object val = cache.get(key);
+
+ assertEquals(1, val);
+
+ boolean res = cache.remove(key);
+
+ assertTrue(res);
+
+ updateKey(cache, key, 2);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictPut1() throws Exception {
+ txNoConflictUpdate(true, false, false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictPut2() throws Exception {
+ txNoConflictUpdate(false, false, false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictPut3() throws Exception {
+ txNoConflictUpdate(false, false, true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictRemove1() throws Exception {
+ txNoConflictUpdate(true, true, false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictRemove2() throws Exception {
+ txNoConflictUpdate(false, true, false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictRemove3() throws Exception {
+ txNoConflictUpdate(false, true, true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ * @param noVal If {@code true} there is no cache value when do update in tx.
+ * @param rmv If {@code true} tests remove, otherwise put.
+ * @param getAfterUpdate If {@code true} tries to get value in tx after update.
+ */
+ private void txNoConflictUpdate(boolean noVal, boolean rmv, boolean getAfterUpdate) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ if (!noVal)
+ cache.put(key, -1);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ if (rmv)
+ cache.remove(key);
+ else
+ cache.put(key, 2);
+
+ if (getAfterUpdate) {
+ Object val = cache.get(key);
+
+ if (rmv)
+ assertNull(val);
+ else
+ assertEquals(2, val);
+ }
+
+ if (!rmv)
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ checkValue(key, rmv ? null : 2, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key, 3);
+
+ tx.commit();
+ }
+
+ checkValue(key, 3, cache.getName());
+ }
+
+ Map<Integer, Integer> map = new HashMap<>();
+
+ for (int i = 0; i < 100; i++)
+ map.put(i, i);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ if (rmv)
+ cache.removeAll(map.keySet());
+ else
+ cache.putAll(map);
+
+ if (getAfterUpdate) {
+ Map<Integer, Integer> res = cache.getAll(map.keySet());
+
+ if (rmv) {
+ for (Integer key : map.keySet())
+ assertNull(res.get(key));
+ }
+ else {
+ for (Integer key : map.keySet())
+ assertEquals(map.get(key), res.get(key));
+ }
+ }
+
+ txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+ new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+ @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+ Map<Integer, Integer> map = new HashMap<>();
+
+ for (int i = 0; i < 100; i++)
+ map.put(i, -1);
+
+ cache.putAll(map);
+
+ return null;
+ }
+ }
+ );
+
+ tx.commit();
+ }
+
+ for (int i = 0; i < 100; i++)
+ checkValue(i, rmv ? null : i, cache.getName());
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictContainsKey1() throws Exception {
+ txNoConflictContainsKey(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxNoConflictContainsKey2() throws Exception {
+ txNoConflictContainsKey(true);
+ }
+
+ /**
+ * @param noVal If {@code true} there is no cache value when do update in tx.
+ * @throws Exception If failed.
+ */
+ private void txNoConflictContainsKey(boolean noVal) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ if (!noVal)
+ cache.put(key, -1);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.containsKey(key);
+
+ assertEquals(!noVal, res);
+
+ updateKey(cache, key, 1);
+
+ tx.commit();
+ }
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.containsKey(key);
+
+ assertTrue(res);
+
+ updateKey(cache, key, 2);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.containsKey(key);
+
+ assertTrue(res);
+
+ tx.commit();
+ }
+
+ cache.remove(key);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ boolean res = cache.containsKey(key);
+
+ assertFalse(res);
+
+ updateKey(cache, key, 3);
+
+ tx.commit();
+ }
+
+ checkValue(key, 3, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxRollbackIfLocked1() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> keys = testKeys(cache);
+
+ for (Integer key : keys) {
+ log.info("Test key: " + key);
+
+ CountDownLatch latch = new CountDownLatch(1);
+
+ IgniteInternalFuture<?> fut = lockKey(latch, cache, key);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key, 2);
+
+ log.info("Commit");
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ latch.countDown();
+
+ fut.get();
+
+ checkValue(key, 1, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key, 2);
+
+ tx.commit();
+ }
+
+ checkValue(key, 2, cache.getName());
+ }
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxRollbackIfLocked2() throws Exception {
+ rollbackIfLockedPartialLock(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxRollbackIfLocked3() throws Exception {
+ rollbackIfLockedPartialLock(true);
+ }
+
+ /**
+ * @param locKey If {@code true} gets lock for local key.
+ * @throws Exception If failed.
+ */
+ private void rollbackIfLockedPartialLock(boolean locKey) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ final Integer key1 = primaryKey(ignite(1).cache(cache.getName()));
+ final Integer key2 = locKey ? primaryKey(cache) : primaryKey(ignite(2).cache(cache.getName()));
+
+ CountDownLatch latch = new CountDownLatch(1);
+
+ IgniteInternalFuture<?> fut = lockKey(latch, cache, key1);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key1, 2);
+ cache.put(key2, 2);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ latch.countDown();
+
+ fut.get();
+
+ checkValue(key1, 1, cache.getName());
+ checkValue(key2, null, cache.getName());
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key1, 2);
+ cache.put(key2, 2);
+
+ tx.commit();
+ }
+
+ checkValue(key1, 2, cache.getName());
+ checkValue(key2, 2, cache.getName());
+ }
+ finally {
+ destroyCache(ignite0, ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testNearCacheReaderUpdate() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ IgniteCache<Integer, Integer> cache0 =
+ ignite0.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+
+ final String cacheName = cache0.getName();
+
+ try {
+ Ignite client1 = ignite(SRVS);
+ Ignite client2 = ignite(SRVS + 1);
+
+ IgniteCache<Integer, Integer> cache1 = client1.createNearCache(cacheName,
+ new NearCacheConfiguration<Integer, Integer>());
+ IgniteCache<Integer, Integer> cache2 = client2.createNearCache(cacheName,
+ new NearCacheConfiguration<Integer, Integer>());
+
+ Integer key = primaryKey(ignite(0).cache(cacheName));
+
+ try (Transaction tx = client1.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ assertNull(cache1.get(key));
+ cache1.put(key, 1);
+
+ tx.commit();
+ }
+
+ try (Transaction tx = client2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ assertEquals(1, (Object) cache2.get(key));
+ cache2.put(key, 2);
+
+ tx.commit();
+ }
+
+ try (Transaction tx = client1.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ assertEquals(2, (Object)cache1.get(key));
+ cache1.put(key, 3);
+
+ tx.commit();
+ }
+ }
+ finally {
+ ignite0.destroyCache(cacheName);
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRollbackNearCache1() throws Exception {
+ rollbackNearCacheWrite(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRollbackNearCache2() throws Exception {
+ rollbackNearCacheWrite(false);
+ }
+
+ /**
+ * @param near If {@code true} locks entry using the same near cache.
+ * @throws Exception If failed.
+ */
+ private void rollbackNearCacheWrite(boolean near) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ IgniteCache<Integer, Integer> cache0 =
+ ignite0.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+
+ final String cacheName = cache0.getName();
+
+ try {
+ Ignite ignite = ignite(SRVS);
+
+ IgniteCache<Integer, Integer> cache = ignite.createNearCache(cacheName,
+ new NearCacheConfiguration<Integer, Integer>());
+
+ IgniteTransactions txs = ignite.transactions();
+
+ Integer key1 = primaryKey(ignite(0).cache(cacheName));
+ Integer key2 = primaryKey(ignite(1).cache(cacheName));
+ Integer key3 = primaryKey(ignite(2).cache(cacheName));
+
+ CountDownLatch latch = new CountDownLatch(1);
+
+ IgniteInternalFuture<?> fut = null;
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key1, key1);
+ cache.put(key2, key2);
+ cache.put(key3, key3);
+
+ fut = lockKey(latch, near ? cache : cache0, key2);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ latch.countDown();
+
+ assert fut != null;
+
+ fut.get();
+
+ checkValue(key1, null, cacheName);
+ checkValue(key2, 1, cacheName);
+ checkValue(key3, null, cacheName);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key1, key1);
+ cache.put(key2, key2);
+ cache.put(key3, key3);
+
+ tx.commit();
+ }
+
+ checkValue(key1, key1, cacheName);
+ checkValue(key2, key2, cacheName);
+ checkValue(key3, key3, cacheName);
+ }
+ finally {
+ ignite0.destroyCache(cacheName);
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRollbackNearCache3() throws Exception {
+ rollbackNearCacheRead(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRollbackNearCache4() throws Exception {
+ rollbackNearCacheRead(false);
+ }
+
+ /**
+ * @param near If {@code true} updates entry using the same near cache.
+ * @throws Exception If failed.
+ */
+ private void rollbackNearCacheRead(boolean near) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ IgniteCache<Integer, Integer> cache0 =
+ ignite0.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+
+ final String cacheName = cache0.getName();
+
+ try {
+ Ignite ignite = ignite(SRVS);
+
+ IgniteCache<Integer, Integer> cache = ignite.createNearCache(cacheName,
+ new NearCacheConfiguration<Integer, Integer>());
+
+ IgniteTransactions txs = ignite.transactions();
+
+ Integer key1 = primaryKey(ignite(0).cache(cacheName));
+ Integer key2 = primaryKey(ignite(1).cache(cacheName));
+ Integer key3 = primaryKey(ignite(2).cache(cacheName));
+
+ cache0.put(key1, -1);
+ cache0.put(key2, -1);
+ cache0.put(key3, -1);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.get(key1);
+ cache.get(key2);
+ cache.get(key3);
+
+ updateKey(near ? cache : cache0, key2, -2);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ checkValue(key1, -1, cacheName);
+ checkValue(key2, -2, cacheName);
+ checkValue(key3, -1, cacheName);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(key1, key1);
+ cache.put(key2, key2);
+ cache.put(key3, key3);
+
+ tx.commit();
+ }
+
+ checkValue(key1, key1, cacheName);
+ checkValue(key2, key2, cacheName);
+ checkValue(key3, key3, cacheName);
+ }
+ finally {
+ ignite0.destroyCache(cacheName);
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testCrossCacheTx() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final String CACHE1 = "cache1";
+ final String CACHE2 = "cache2";
+
+ try {
+ CacheConfiguration<Integer, Integer> ccfg1 =
+ cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
+
+ ccfg1.setName(CACHE1);
+
+ ignite0.createCache(ccfg1);
+
+ CacheConfiguration<Integer, Integer> ccfg2=
+ cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
+
+ ccfg2.setName(CACHE2);
+
+ ignite0.createCache(ccfg2);
+
+ Integer newVal = 0;
+
+ List<Integer> keys = testKeys(ignite0.<Integer, Integer>cache(CACHE1));
+
+ for (Ignite ignite : G.allGrids()) {
+ log.info("Test node: " + ignite.name());
+
+ IgniteCache<Integer, Integer> cache1 = ignite.cache(CACHE1);
+ IgniteCache<Integer, Integer> cache2 = ignite.cache(CACHE2);
+
+ IgniteTransactions txs = ignite.transactions();
+
+ for (Integer key : keys) {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache1.put(key, newVal);
+ cache2.put(key, newVal);
+
+ tx.commit();
+ }
+
+ checkValue(key, newVal, CACHE1);
+ checkValue(key, newVal, CACHE2);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object val1 = cache1.get(key);
+ Object val2 = cache2.get(key);
+
+ assertEquals(newVal, val1);
+ assertEquals(newVal, val2);
+
+ tx.commit();
+ }
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache1.put(key, newVal + 1);
+ cache2.put(key, newVal + 1);
+
+ tx.rollback();
+ }
+
+ checkValue(key, newVal, CACHE1);
+ checkValue(key, newVal, CACHE2);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object val1 = cache1.get(key);
+ Object val2 = cache2.get(key);
+
+ assertEquals(newVal, val1);
+ assertEquals(newVal, val2);
+
+ cache1.put(key, newVal + 1);
+ cache2.put(key, newVal + 1);
+
+ tx.commit();
+ }
+
+ newVal++;
+
+ checkValue(key, newVal, CACHE1);
+ checkValue(key, newVal, CACHE2);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache1.put(key, newVal);
+ cache2.put(-key, newVal);
+
+ tx.commit();
+ }
+
+ checkValue(key, newVal, CACHE1);
+ checkValue(-key, null, CACHE1);
+
+ checkValue(key, newVal, CACHE2);
+ checkValue(-key, newVal, CACHE2);
+ }
+
+ newVal++;
+
+ Integer key1 = primaryKey(ignite(0).cache(CACHE1));
+ Integer key2 = primaryKey(ignite(1).cache(CACHE1));
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache1.put(key1, newVal);
+ cache1.put(key2, newVal);
+
+ cache2.put(key1, newVal);
+ cache2.put(key2, newVal);
+
+ tx.commit();
+ }
+
+ checkValue(key1, newVal, CACHE1);
+ checkValue(key2, newVal, CACHE1);
+ checkValue(key1, newVal, CACHE2);
+ checkValue(key2, newVal, CACHE2);
+
+ CountDownLatch latch = new CountDownLatch(1);
+
+ IgniteInternalFuture<?> fut = lockKey(latch, cache1, key1);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache1.put(key1, newVal + 1);
+ cache2.put(key1, newVal + 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ latch.countDown();
+
+ fut.get();
+
+ checkValue(key1, 1, CACHE1);
+ checkValue(key1, newVal, CACHE2);
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache1.put(key1, newVal + 1);
+ cache2.put(key1, newVal + 1);
+
+ tx.commit();
+ }
+
+ newVal++;
+
+ cache1.put(key2, newVal);
+ cache2.put(key2, newVal);
+
+ checkValue(key1, newVal, CACHE1);
+ checkValue(key1, newVal, CACHE2);
+
+ latch = new CountDownLatch(1);
+
+ fut = lockKey(latch, cache1, key1);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache1.put(key1, newVal + 1);
+ cache2.put(key2, newVal + 1);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ latch.countDown();
+
+ fut.get();
+
+ checkValue(key1, 1, CACHE1);
+ checkValue(key2, newVal, CACHE2);
+
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Object val1 = cache1.get(key1);
+
<TRUNCATED>
[22/23] ignite git commit: Merge branches
'ignite-1.4-slow-server-debug' and 'master' of
https://git-wip-us.apache.org/repos/asf/ignite into
ignite-1.4-slow-server-debug
Posted by yz...@apache.org.
Merge branches 'ignite-1.4-slow-server-debug' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-1.4-slow-server-debug
Conflicts:
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/502223a8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/502223a8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/502223a8
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 502223a8a5e9d88b90f402298013b503817181e7
Parents: 10956be 215b0cd
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Wed Oct 28 18:21:51 2015 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Wed Oct 28 18:21:51 2015 +0300
----------------------------------------------------------------------
.../configuration/TransactionConfiguration.java | 6 +-
.../apache/ignite/internal/IgniteKernal.java | 69 +-
.../processors/cache/CacheMetricsImpl.java | 12 +-
.../processors/cache/GridCacheAdapter.java | 459 +-
.../processors/cache/GridCacheEntryEx.java | 62 +-
.../processors/cache/GridCacheMapEntry.java | 137 +-
.../processors/cache/GridCacheMvcc.java | 143 +-
.../cache/GridCacheMvccCandidate.java | 26 +-
.../processors/cache/GridCacheProcessor.java | 13 -
.../distributed/GridDistributedCacheEntry.java | 12 +-
.../GridDistributedTxRemoteAdapter.java | 59 +-
.../dht/CacheDistributedGetFutureAdapter.java | 158 +
.../distributed/dht/GridDhtCacheAdapter.java | 17 +-
.../distributed/dht/GridDhtCacheEntry.java | 23 +-
.../cache/distributed/dht/GridDhtGetFuture.java | 199 +-
.../distributed/dht/GridDhtLockFuture.java | 5 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 105 +-
.../cache/distributed/dht/GridDhtTxLocal.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 109 +-
.../dht/GridPartitionedGetFuture.java | 179 +-
.../dht/atomic/GridDhtAtomicCache.java | 16 +-
.../dht/colocated/GridDhtColocatedCache.java | 130 +-
.../colocated/GridDhtColocatedLockFuture.java | 6 +-
.../distributed/near/GridNearAtomicCache.java | 2 -
.../distributed/near/GridNearCacheAdapter.java | 32 +-
.../distributed/near/GridNearCacheEntry.java | 81 +-
.../distributed/near/GridNearGetFuture.java | 340 +-
.../distributed/near/GridNearGetRequest.java | 3 -
...arOptimisticSerializableTxPrepareFuture.java | 930 ++++
.../near/GridNearOptimisticTxPrepareFuture.java | 252 +-
...ridNearOptimisticTxPrepareFutureAdapter.java | 222 +
.../GridNearPessimisticTxPrepareFuture.java | 8 +-
.../near/GridNearTransactionalCache.java | 14 +-
.../near/GridNearTxFinishFuture.java | 16 +-
.../cache/distributed/near/GridNearTxLocal.java | 157 +-
.../near/GridNearTxPrepareFutureAdapter.java | 13 +-
.../cache/local/GridLocalCacheEntry.java | 23 +-
.../cache/local/GridLocalLockFuture.java | 2 +
.../local/atomic/GridLocalAtomicCache.java | 9 -
.../transactions/IgniteTransactionsImpl.java | 6 -
.../cache/transactions/IgniteTxAdapter.java | 123 +-
.../cache/transactions/IgniteTxEntry.java | 51 +-
.../cache/transactions/IgniteTxHandler.java | 4 +-
.../transactions/IgniteTxLocalAdapter.java | 832 ++--
.../cache/transactions/IgniteTxLocalEx.java | 27 +-
.../cache/transactions/IgniteTxManager.java | 325 +-
.../cache/version/GridCacheVersionManager.java | 73 +-
.../datastreamer/DataStreamerImpl.java | 2 +-
.../apache/ignite/transactions/Transaction.java | 2 +-
.../transactions/TransactionIsolation.java | 3 +-
.../fair/FairAffinityDynamicCacheSelfTest.java | 2 +
.../GridDiscoveryManagerAttributesSelfTest.java | 23 +-
.../cache/CacheNearReaderUpdateTest.java | 388 ++
.../CacheSerializableTransactionsTest.java | 4297 ++++++++++++++++++
.../cache/CrossCacheTxRandomOperationsTest.java | 6 +
.../GridCacheAbstractFailoverSelfTest.java | 14 +-
.../cache/GridCacheAbstractFullApiSelfTest.java | 4 +-
.../GridCacheAbstractRemoveFailureTest.java | 94 +-
.../GridCacheConcurrentTxMultiNodeTest.java | 3 -
.../cache/GridCacheMvccFlagsTest.java | 6 +-
.../cache/GridCacheMvccPartitionedSelfTest.java | 164 +
.../processors/cache/GridCacheMvccSelfTest.java | 3 +-
.../processors/cache/GridCacheTestEntryEx.java | 53 +-
.../processors/cache/IgniteTxAbstractTest.java | 42 +-
.../IgniteTxMultiThreadedAbstractTest.java | 106 +-
...onedNearDisabledTxMultiThreadedSelfTest.java | 31 +
...niteCacheClientNodeChangingTopologyTest.java | 170 +-
.../IgniteCacheCrossCacheTxFailoverTest.java | 19 +
.../dht/IgniteCacheLockFailoverSelfTest.java | 11 +
...eAtomicInvalidPartitionHandlingSelfTest.java | 6 +-
.../near/GridCacheNearTxExceptionSelfTest.java | 1 +
...CachePartitionedTxMultiThreadedSelfTest.java | 15 +-
.../DataStreamerUpdateAfterLoadTest.java | 184 +
.../loadtests/hashmap/GridHashMapLoadTest.java | 6 +-
.../inmemory/GridTestSwapSpaceSpi.java | 8 +
.../junits/common/GridCommonAbstractTest.java | 19 +-
.../ignite/testsuites/IgniteCacheTestSuite.java | 4 +-
.../testsuites/IgniteCacheTestSuite2.java | 2 +
.../testsuites/IgniteCacheTestSuite5.java | 40 +
modules/jms11/pom.xml | 9 +-
.../stream/jms11/IgniteJmsStreamerTest.java | 9 +-
.../apache/ignite/stream/mqtt/MqttStreamer.java | 386 +-
.../stream/mqtt/IgniteMqttStreamerTest.java | 142 +-
.../mqtt/IgniteMqttStreamerTestSuite.java | 4 +-
.../config/benchmark-multicast.properties | 5 +-
.../IgniteAccountSerializableTxBenchmark.java | 81 +
.../cache/IgniteAccountTxAbstractBenchmark.java | 61 +
.../cache/IgniteAccountTxBenchmark.java | 74 +
.../cache/IgniteCacheAbstractBenchmark.java | 7 +-
.../IgnitePutAllSerializableTxBenchmark.java | 77 +
.../ignite/yardstick/cache/model/Account.java | 42 +
91 files changed, 9644 insertions(+), 2475 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index e164be0,fcbf58d..93303c8
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@@ -577,17 -579,37 +579,37 @@@ public class GridDistributedTxRemoteAda
if (op == CREATE || op == UPDATE) {
// Invalidate only for near nodes (backups cannot be invalidated).
if (isSystemInvalidate() || (isInvalidate() && cacheCtx.isNear()))
- cached.innerRemove(this, eventNodeId(), nodeId,
- false, true, true,
- topVer, null, replicate ? DR_BACKUP : DR_NONE,
- near() ? null : explicitVer, CU.subjectId(this, cctx),
- resolveTaskName());
+ cached.innerRemove(this,
+ eventNodeId(),
+ nodeId,
+ false,
- false,
+ true,
+ true,
+ topVer,
+ null,
+ replicate ? DR_BACKUP : DR_NONE,
- near() ? null : explicitVer, CU.subjectId(this, cctx),
++ near() ? null : explicitVer,
++ CU.subjectId(this, cctx),
+ resolveTaskName(),
+ dhtVer);
else {
- cached.innerSet(this, eventNodeId(), nodeId, val, false, false,
- txEntry.ttl(), true, true, topVer, null,
- replicate ? DR_BACKUP : DR_NONE, txEntry.conflictExpireTime(),
- near() ? null : explicitVer, CU.subjectId(this, cctx),
- resolveTaskName());
+ cached.innerSet(this,
+ eventNodeId(),
+ nodeId,
+ val,
+ false,
+ false,
+ txEntry.ttl(),
+ true,
+ true,
+ topVer,
+ null,
+ replicate ? DR_BACKUP : DR_NONE,
+ txEntry.conflictExpireTime(),
+ near() ? null : explicitVer,
+ CU.subjectId(this, cctx),
+ resolveTaskName(),
+ dhtVer);
// Keep near entry up to date.
if (nearCached != null) {
@@@ -603,10 -625,20 +625,19 @@@
}
}
else if (op == DELETE) {
- cached.innerRemove(this, eventNodeId(), nodeId,
- false, true, true,
- topVer, null, replicate ? DR_BACKUP : DR_NONE,
- near() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName());
+ cached.innerRemove(this,
+ eventNodeId(),
+ nodeId,
+ false,
- false,
+ true,
+ true,
+ topVer,
+ null,
+ replicate ? DR_BACKUP : DR_NONE,
+ near() ? null : explicitVer,
+ CU.subjectId(this, cctx),
+ resolveTaskName(),
+ dhtVer);
// Keep near entry up to date.
if (nearCached != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index 48fa133,d806801..612e2bb
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@@ -59,7 -56,9 +58,8 @@@ import org.apache.ignite.internal.proce
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.dr.GridDrType;
+ import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
import org.apache.ignite.internal.util.F0;
-import org.apache.ignite.internal.util.GridConcurrentHashSet;
import org.apache.ignite.internal.util.GridLeanSet;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index fd1453b,af43113..0002180
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@@ -17,11 -17,8 +17,10 @@@
package org.apache.ignite.internal.processors.cache.distributed.near;
+import java.util.ArrayDeque;
import java.util.Collection;
- import java.util.Collections;
import java.util.List;
+import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.ignite.IgniteCheckedException;
@@@ -59,9 -53,9 +55,8 @@@ import org.apache.ignite.internal.util.
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteClosure;
import org.apache.ignite.lang.IgniteUuid;
- import org.apache.ignite.transactions.TransactionOptimisticException;
import org.apache.ignite.transactions.TransactionTimeoutException;
import org.jetbrains.annotations.Nullable;
-import org.jsr166.ConcurrentLinkedDeque8;
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
import static org.apache.ignite.transactions.TransactionState.PREPARED;
@@@ -483,9 -293,9 +294,9 @@@ public class GridNearOptimisticTxPrepar
txMapping = new GridDhtTxMapping();
- ConcurrentLinkedDeque8<GridDistributedTxMapping> mappings = new ConcurrentLinkedDeque8<>();
+ Queue<GridDistributedTxMapping> mappings = new ArrayDeque<>();
- if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
+ if (!F.isEmpty(writes)) {
for (int cacheId : tx.activeCacheIds()) {
GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index c7cc3ae,46c9f3e..a9dbda2
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
@@@ -246,59 -265,44 +246,61 @@@ public final class GridNearTxFinishFutu
}
}
+ if (initialized() || err != null) {
+ if (tx.needCheckBackup()) {
+ assert tx.onePhaseCommit();
+
+ if (err != null)
+ err = new TransactionRollbackException("Failed to commit transaction.", err);
+
+ try {
+ tx.finish(err == null);
+ }
+ catch (IgniteCheckedException e) {
+ if (err != null)
+ err.addSuppressed(e);
+ else
+ err = e;
+ }
+ }
+
- if (tx.onePhaseCommit()) {
- finishOnePhase();
+ if (tx.onePhaseCommit()) {
+ boolean commit = this.commit && err == null;
- tx.tmFinish(commit && err == null);
- }
+ finishOnePhase(commit);
+
+ tx.tmFinish(commit);
+ }
- Throwable th = this.err.get();
+ if (super.onDone(tx0, err)) {
+ if (error() instanceof IgniteTxHeuristicCheckedException) {
+ AffinityTopologyVersion topVer = tx.topologyVersion();
- if (super.onDone(tx0, th != null ? th : err)) {
- if (error() instanceof IgniteTxHeuristicCheckedException) {
- AffinityTopologyVersion topVer = tx.topologyVersion();
+ for (IgniteTxEntry e : tx.writeMap().values()) {
+ GridCacheContext cacheCtx = e.context();
- for (IgniteTxEntry e : tx.writeMap().values()) {
- GridCacheContext cacheCtx = e.context();
-
- try {
- if (e.op() != NOOP && !cacheCtx.affinity().localNode(e.key(), topVer)) {
- GridCacheEntryEx entry = cacheCtx.cache().peekEx(e.key());
+ try {
+ if (e.op() != NOOP && !cacheCtx.affinity().localNode(e.key(), topVer)) {
+ GridCacheEntryEx entry = cacheCtx.cache().peekEx(e.key());
- if (entry != null)
- entry.invalidate(null, tx.xidVersion());
+ if (entry != null)
+ entry.invalidate(null, tx.xidVersion());
+ }
}
- }
- catch (Throwable t) {
- U.error(log, "Failed to invalidate entry.", t);
+ catch (Throwable t) {
+ U.error(log, "Failed to invalidate entry.", t);
- if (t instanceof Error)
- throw (Error)t;
+ if (t instanceof Error)
+ throw (Error)t;
+ }
}
}
- }
- // Don't forget to clean up.
- cctx.mvcc().removeFuture(this);
+ // Don't forget to clean up.
+ cctx.mvcc().removeFuture(this);
- return true;
+ return true;
+ }
}
}
@@@ -508,16 -512,9 +510,16 @@@
}
/**
- *
+ * @param commit Commit flag.
*/
- private void finishOnePhase() {
+ private void finishOnePhase(boolean commit) {
+ assert Thread.holdsLock(this);
+
+ if (finishOnePhaseCalled)
+ return;
+
+ finishOnePhaseCalled = true;
+
// No need to send messages as transaction was already committed on remote node.
// Finish local mapping only as we need send commit message to backups.
for (GridDistributedTxMapping m : mappings.values()) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index d97e648,c1e9202..05129bb
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@@ -24,8 -23,8 +24,7 @@@ import java.util.Collections
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.LinkedList;
import java.util.Map;
- import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
@@@ -134,29 -127,9 +132,19 @@@ public class IgniteTxManager extends Gr
/** TX handler. */
private IgniteTxHandler txHandler;
- /** All transactions. */
- private final Queue<IgniteInternalTx> committedQ = new ConcurrentLinkedDeque8<>();
-
- /** Preparing transactions. */
- private final Queue<IgniteInternalTx> prepareQ = new ConcurrentLinkedDeque8<>();
-
- /** Minimum start version. */
- private final ConcurrentNavigableMap<GridCacheVersion, AtomicInt> startVerCnts =
- new ConcurrentSkipListMap<>();
-
/** Committed local transactions. */
- private final GridBoundedConcurrentOrderedMap<GridCacheVersion, Boolean> completedVers =
- new GridBoundedConcurrentOrderedMap<>(Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT));
+ private final GridBoundedConcurrentOrderedMap<GridCacheVersion, Boolean> completedVersSorted =
+ new GridBoundedConcurrentOrderedMap<>(
+ Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT));
+
+ /** Committed local transactions. */
+ private final ConcurrentLinkedHashMap<GridCacheVersion, Boolean> completedVersHashMap =
+ new ConcurrentLinkedHashMap<>(
+ Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT),
+ 0.75f,
+ Runtime.getRuntime().availableProcessors() * 2,
+ Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT),
+ PER_SEGMENT_Q);
/** Transaction finish synchronizer. */
private GridCacheTxFinishSync txFinishSync;
@@@ -324,40 -297,8 +312,9 @@@
X.println(">>> ");
X.println(">>> Transaction manager memory stats [grid=" + cctx.gridName() + ']');
X.println(">>> threadMapSize: " + threadMap.size());
- X.println(">>> idMap [size=" + idMap.size() + ", minStartVer=" + minStartVer + ", dur=" + dur + "ms]");
- X.println(">>> committedQueue [size=" + committedSize +
- ", firstStartVersion=" + (firstTx == null ? "null" : firstTx.startVersion()) +
- ", firstEndVersion=" + (firstTx == null ? "null" : firstTx.endVersion()) + ']');
- X.println(">>> prepareQueueSize: " + prepareQ.size());
- X.println(">>> startVerCntsSize [size=" + startVerCnts.size() +
- ", firstVer=" + startVerEntry + ']');
+ X.println(">>> idMap [size=" + idMap.size() + ']');
- X.println(">>> completedVersSize: " + completedVers.size());
+ X.println(">>> completedVersSortedSize: " + completedVersSorted.size());
+ X.println(">>> completedVersHashMapSize: " + completedVersHashMap.sizex());
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
----------------------------------------------------------------------
[03/23] ignite git commit: IGNITE-1747 MQTT Streamer: remove
'connected' flag and add 2 tests.
Posted by yz...@apache.org.
IGNITE-1747 MQTT Streamer: remove 'connected' flag and add 2 tests.
MQTT Connection State can be checked by calling MqttClient#isConnected.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0e487226
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0e487226
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0e487226
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 0e48722679226a0845ff74dd447f77c2da50ece4
Parents: 056490d
Author: Raul Kripalani <ra...@apache.org>
Authored: Fri Oct 23 17:51:46 2015 +0100
Committer: Raul Kripalani <ra...@apache.org>
Committed: Fri Oct 23 17:51:46 2015 +0100
----------------------------------------------------------------------
.../apache/ignite/stream/mqtt/MqttStreamer.java | 43 +++++++----------
.../stream/mqtt/IgniteMqttStreamerTest.java | 50 +++++++++++++++++++-
2 files changed, 67 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0e487226/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
index a075695..e546da2 100644
--- a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
+++ b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
@@ -136,9 +136,6 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
/** State keeping. */
private volatile boolean stopped = true;
- /** State keeping. */
- private volatile boolean connected;
-
/** Cached log prefix for cache messages. */
private String cachedLogValues;
@@ -231,10 +228,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
stopped = false;
// Build retrier.
- Retryer<Boolean> retrier = RetryerBuilder.<Boolean>newBuilder()
- .retryIfResult(new Predicate<Boolean>() {
- @Override public boolean apply(Boolean connected) {
- return !connected;
+ Retryer<Void> retrier = RetryerBuilder.<Void>newBuilder()
+ .retryIfResult(new Predicate<Void>() {
+ @Override public boolean apply(Void v) {
+ return !client.isConnected() && !stopped;
}
})
.retryIfException().retryIfRuntimeException()
@@ -288,7 +285,6 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
client.close();
- connected = false;
stopped = true;
}
catch (Exception e) {
@@ -307,9 +303,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
* {@inheritDoc}
*/
@Override public void connectionLost(Throwable throwable) {
- connected = false;
-
- // if we have been stopped, we do not try to establish the connection again
+ // If we have been stopped, we do not try to establish the connection again.
if (stopped)
return;
@@ -623,12 +617,13 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
}
/**
- * Returns whether this streamer is connected.
+ * Returns whether this streamer is connected by delegating to the underlying {@link MqttClient#isConnected()}
*
* @return {@code true} if connected; {@code false} if not.
+ * @see MqttClient#isConnected()
*/
public boolean isConnected() {
- return connected;
+ return client.isConnected();
}
/**
@@ -637,17 +632,17 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
*/
private class MqttConnectionRetrier {
/** The guava-retrying retrier object. */
- private final Retryer<Boolean> retrier;
+ private final Retryer<Void> retrier;
/** Single-threaded pool. */
- private ExecutorService exec = Executors.newSingleThreadExecutor();
+ private final ExecutorService exec = Executors.newSingleThreadExecutor();
/**
* Constructor.
*
* @param retrier The retryier object.
*/
- public MqttConnectionRetrier(Retryer<Boolean> retrier) {
+ public MqttConnectionRetrier(Retryer<Void> retrier) {
this.retrier = retrier;
}
@@ -655,14 +650,14 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
* Method called by the streamer to ask us to (re-)connect.
*/
public void connect() {
- Callable<Boolean> callable = retrier.wrap(new Callable<Boolean>() {
- @Override public Boolean call() throws Exception {
+ Callable<Void> callable = retrier.wrap(new Callable<Void>() {
+ @Override public Void call() throws Exception {
// If we're already connected, return immediately.
- if (connected)
- return true;
+ if (client.isConnected())
+ return null;
if (stopped)
- return false;
+ return null;
// Connect to broker.
if (connectOptions == null)
@@ -686,13 +681,11 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
log.info("MQTT Streamer (re-)connected and subscribed " + cachedLogValues);
- connected = true;
-
- return true;
+ return null;
}
});
- Future<Boolean> result = exec.submit(callable);
+ Future<Void> result = exec.submit(callable);
if (blockUntilConnected) {
try {
http://git-wip-us.apache.org/repos/asf/ignite/blob/0e487226/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
index 6b07fde..891866d 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
@@ -172,6 +172,54 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
/**
* @throws Exception If failed.
*/
+ public void testConnectDisconnect() throws Exception {
+ // configure streamer
+ streamer.setSingleTupleExtractor(singleTupleExtractor());
+ streamer.setTopic(SINGLE_TOPIC_NAME);
+ streamer.setBlockUntilConnected(true);
+
+ // action time: repeat 10 times; make sure the connection state is kept correctly every time
+ for (int i = 0; i < 10; i++) {
+ streamer.start();
+
+ assertTrue(streamer.isConnected());
+
+ streamer.stop();
+
+ assertFalse(streamer.isConnected());
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testConnectionStatusWithBrokerDisconnection() throws Exception {
+ // configure streamer
+ streamer.setSingleTupleExtractor(singleTupleExtractor());
+ streamer.setTopic(SINGLE_TOPIC_NAME);
+ streamer.setBlockUntilConnected(true);
+ streamer.setRetryWaitStrategy(WaitStrategies.noWait());
+
+ streamer.start();
+
+ // action time: repeat 5 times; make sure the connection state is kept correctly every time
+ for (int i = 0; i < 5; i++) {
+ assertTrue(streamer.isConnected());
+
+ broker.stop();
+
+ assertFalse(streamer.isConnected());
+
+ broker.start(true);
+ broker.waitUntilStarted();
+
+ Thread.sleep(500);
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testSingleTopic_NoQoS_OneEntryPerMessage() throws Exception {
// configure streamer
streamer.setSingleTupleExtractor(singleTupleExtractor());
@@ -307,7 +355,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception If failed.
+ * @throws Exception
*/
public void testSingleTopic_NoQoS_Reconnect() throws Exception {
// configure streamer
[07/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java
new file mode 100644
index 0000000..200400e
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.yardstickframework.BenchmarkConfiguration;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class IgnitePutAllSerializableTxBenchmark extends IgniteCacheAbstractBenchmark {
+ /** */
+ private IgniteTransactions txs;
+
+ /** {@inheritDoc} */
+ @Override public void setUp(BenchmarkConfiguration cfg) throws Exception {
+ super.setUp(cfg);
+
+ txs = ignite().transactions();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+ ThreadRange r = threadRange();
+
+ Map<Integer, Integer> vals = new HashMap<>();
+
+ for (int i = 0; i < args.batch(); i++) {
+ int key = r.nextRandom();
+
+ vals.put(key, key);
+ }
+
+ while (true) {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.putAll(vals);
+
+ tx.commit();
+ }
+ catch (TransactionOptimisticException e) {
+ continue;
+ }
+
+ break;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteCache<Integer, Object> cache() {
+ return ignite().cache("tx");
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java
new file mode 100644
index 0000000..3d5d9f8
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache.model;
+
+import java.io.Serializable;
+
+/**
+ *
+ */
+public class Account implements Serializable {
+ /** */
+ private final int balance;
+
+ /**
+ * @param balance Balance.
+ */
+ public Account(int balance) {
+ this.balance = balance;
+ }
+
+ /**
+ * @return Balance.
+ */
+ public int balance() {
+ return balance;
+ }
+}
[05/23] ignite git commit: Merge branch 'master' into ignite-1747
Posted by yz...@apache.org.
Merge branch 'master' into ignite-1747
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6ca7a454
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6ca7a454
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6ca7a454
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 6ca7a454acf1ebc8d344fdd5242c5f7e18e04d7f
Parents: b12663f ef785cb
Author: Raul Kripalani <ra...@apache.org>
Authored: Mon Oct 26 16:35:38 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Mon Oct 26 16:35:38 2015 +0000
----------------------------------------------------------------------
DEVNOTES.txt | 2 +-
assembly/dependencies-fabric-lgpl.xml | 169 +++++++++++++
assembly/dependencies-fabric.xml | 3 +
assembly/release-fabric-base.xml | 107 ++++++++
assembly/release-fabric-lgpl.xml | 41 ++--
assembly/release-fabric.xml | 85 +------
assembly/release-hadoop-lgpl.xml | 39 ---
config/fabric-lgpl/default-config.xml | 29 +++
examples-lgpl/README.txt | 27 --
examples-lgpl/config/example-cache.xml | 73 ------
examples-lgpl/config/example-ignite.xml | 83 -------
examples-lgpl/config/hibernate/README.txt | 8 -
.../hibernate/example-hibernate-L2-cache.xml | 64 -----
examples-lgpl/pom-standalone.xml | 186 --------------
examples-lgpl/pom.xml | 128 ----------
.../hibernate/HibernateL2CacheExample.java | 245 -------------------
.../examples/datagrid/hibernate/Post.java | 130 ----------
.../examples/datagrid/hibernate/User.java | 154 ------------
.../datagrid/hibernate/package-info.java | 22 --
.../hibernate/CacheHibernatePersonStore.java | 122 ---------
.../hibernate/CacheHibernateStoreExample.java | 151 ------------
.../datagrid/store/hibernate/Person.hbm.xml | 34 ---
.../datagrid/store/hibernate/hibernate.cfg.xml | 41 ----
.../datagrid/store/hibernate/package-info.java | 22 --
.../misc/schedule/ComputeScheduleExample.java | 82 -------
.../examples/misc/schedule/package-info.java | 22 --
.../misc/schedule/ComputeScheduleExample.java | 68 -----
.../java8/misc/schedule/package-info.java | 22 --
.../ignite/examples/java8/package-info.java | 23 --
.../scalar/examples/ScalarScheduleExample.scala | 66 -----
...ibernateL2CacheExampleMultiNodeSelfTest.java | 31 ---
.../HibernateL2CacheExampleSelfTest.java | 33 ---
.../IgniteLgplExamplesSelfTestSuite.java | 48 ----
...ibernateL2CacheExampleMultiNodeSelfTest.java | 29 ---
.../HibernateL2CacheExampleSelfTest.java | 37 ---
.../IgniteLgplExamplesJ8SelfTestSuite.java | 46 ----
.../ScalarLgplExamplesMultiNodeSelfTest.scala | 33 ---
.../examples/ScalarLgplExamplesSelfTest.scala | 36 ---
.../ScalarLgplExamplesSelfTestSuite.scala | 37 ---
examples/README-LGPL.txt | 33 +++
examples/README.txt | 21 +-
examples/config/hibernate/README.txt | 8 +
.../hibernate/example-hibernate-L2-cache.xml | 64 +++++
examples/pom-standalone-lgpl.xml | 217 ++++++++++++++++
examples/pom-standalone.xml | 156 ++++++------
examples/pom.xml | 157 ++++++------
.../hibernate/HibernateL2CacheExample.java | 245 +++++++++++++++++++
.../examples/datagrid/hibernate/Post.java | 130 ++++++++++
.../examples/datagrid/hibernate/User.java | 154 ++++++++++++
.../datagrid/hibernate/package-info.java | 22 ++
.../hibernate/CacheHibernatePersonStore.java | 122 +++++++++
.../hibernate/CacheHibernateStoreExample.java | 151 ++++++++++++
.../datagrid/store/hibernate/Person.hbm.xml | 34 +++
.../datagrid/store/hibernate/hibernate.cfg.xml | 41 ++++
.../datagrid/store/hibernate/package-info.java | 22 ++
.../misc/schedule/ComputeScheduleExample.java | 82 +++++++
.../examples/misc/schedule/package-info.java | 22 ++
...ibernateL2CacheExampleMultiNodeSelfTest.java | 31 +++
.../HibernateL2CacheExampleSelfTest.java | 33 +++
.../IgniteLgplExamplesSelfTestSuite.java | 48 ++++
modules/core/src/test/config/tests.properties | 4 +-
modules/extdata/uri/pom.xml | 21 +-
.../ipfinder/zk/ZookeeperIpFinderTestSuite.java | 32 +++
pom.xml | 64 -----
64 files changed, 2022 insertions(+), 2470 deletions(-)
----------------------------------------------------------------------
[06/23] ignite git commit: IGNITE-1747 Merge coding style adjustments
in Ignite MQTT Streamer.
Posted by yz...@apache.org.
IGNITE-1747 Merge coding style adjustments in Ignite MQTT Streamer.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/db888607
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/db888607
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/db888607
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: db888607926d7ecc5bb54da7150c85013c56ee4e
Parents: 3ec52f3 6ca7a45
Author: Raul Kripalani <ra...@apache.org>
Authored: Tue Oct 27 16:04:27 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Tue Oct 27 16:05:02 2015 +0000
----------------------------------------------------------------------
.../apache/ignite/stream/mqtt/MqttStreamer.java | 386 ++++++++++++-------
.../stream/mqtt/IgniteMqttStreamerTest.java | 142 +++++--
.../mqtt/IgniteMqttStreamerTestSuite.java | 4 +-
3 files changed, 351 insertions(+), 181 deletions(-)
----------------------------------------------------------------------
[15/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
ignite-1607 Implemented deadlock-free optimistic serializable tx mode
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9d7543a8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9d7543a8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9d7543a8
Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 9d7543a8dedb85f1dc904b52be3673f4a151f8e7
Parents: db88860
Author: sboikov <sb...@gridgain.com>
Authored: Wed Oct 28 10:53:29 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Oct 28 10:53:30 2015 +0300
----------------------------------------------------------------------
.../configuration/TransactionConfiguration.java | 6 +-
.../processors/cache/CacheMetricsImpl.java | 12 +-
.../processors/cache/GridCacheAdapter.java | 459 +-
.../processors/cache/GridCacheEntryEx.java | 62 +-
.../processors/cache/GridCacheMapEntry.java | 137 +-
.../processors/cache/GridCacheMvcc.java | 143 +-
.../cache/GridCacheMvccCandidate.java | 26 +-
.../processors/cache/GridCacheProcessor.java | 13 -
.../distributed/GridDistributedCacheEntry.java | 12 +-
.../GridDistributedTxRemoteAdapter.java | 56 +-
.../dht/CacheDistributedGetFutureAdapter.java | 158 +
.../distributed/dht/GridDhtCacheAdapter.java | 17 +-
.../distributed/dht/GridDhtCacheEntry.java | 23 +-
.../cache/distributed/dht/GridDhtGetFuture.java | 199 +-
.../distributed/dht/GridDhtLockFuture.java | 5 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 105 +-
.../cache/distributed/dht/GridDhtTxLocal.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 109 +-
.../dht/GridPartitionedGetFuture.java | 179 +-
.../dht/atomic/GridDhtAtomicCache.java | 16 +-
.../dht/colocated/GridDhtColocatedCache.java | 130 +-
.../colocated/GridDhtColocatedLockFuture.java | 6 +-
.../distributed/near/GridNearAtomicCache.java | 2 -
.../distributed/near/GridNearCacheAdapter.java | 32 +-
.../distributed/near/GridNearCacheEntry.java | 81 +-
.../distributed/near/GridNearGetFuture.java | 340 +-
.../distributed/near/GridNearGetRequest.java | 3 -
...arOptimisticSerializableTxPrepareFuture.java | 930 ++++
.../near/GridNearOptimisticTxPrepareFuture.java | 252 +-
...ridNearOptimisticTxPrepareFutureAdapter.java | 222 +
.../GridNearPessimisticTxPrepareFuture.java | 8 +-
.../near/GridNearTransactionalCache.java | 14 +-
.../near/GridNearTxFinishFuture.java | 12 +-
.../cache/distributed/near/GridNearTxLocal.java | 157 +-
.../near/GridNearTxPrepareFutureAdapter.java | 13 +-
.../cache/local/GridLocalCacheEntry.java | 23 +-
.../cache/local/GridLocalLockFuture.java | 2 +
.../local/atomic/GridLocalAtomicCache.java | 9 -
.../transactions/IgniteTransactionsImpl.java | 6 -
.../cache/transactions/IgniteTxAdapter.java | 123 +-
.../cache/transactions/IgniteTxEntry.java | 51 +-
.../cache/transactions/IgniteTxHandler.java | 4 +-
.../transactions/IgniteTxLocalAdapter.java | 832 ++--
.../cache/transactions/IgniteTxLocalEx.java | 27 +-
.../cache/transactions/IgniteTxManager.java | 327 +-
.../cache/version/GridCacheVersionManager.java | 73 +-
.../datastreamer/DataStreamerImpl.java | 2 +-
.../apache/ignite/transactions/Transaction.java | 2 +-
.../transactions/TransactionIsolation.java | 3 +-
.../cache/CacheNearReaderUpdateTest.java | 388 ++
.../CacheSerializableTransactionsTest.java | 4295 ++++++++++++++++++
.../cache/CrossCacheTxRandomOperationsTest.java | 6 +
.../GridCacheAbstractFailoverSelfTest.java | 14 +-
.../cache/GridCacheAbstractFullApiSelfTest.java | 4 +-
.../GridCacheAbstractRemoveFailureTest.java | 94 +-
.../GridCacheConcurrentTxMultiNodeTest.java | 3 -
.../cache/GridCacheMvccFlagsTest.java | 6 +-
.../cache/GridCacheMvccPartitionedSelfTest.java | 164 +
.../processors/cache/GridCacheMvccSelfTest.java | 3 +-
.../processors/cache/GridCacheTestEntryEx.java | 53 +-
.../processors/cache/IgniteTxAbstractTest.java | 42 +-
.../IgniteTxMultiThreadedAbstractTest.java | 106 +-
...onedNearDisabledTxMultiThreadedSelfTest.java | 31 +
...niteCacheClientNodeChangingTopologyTest.java | 170 +-
.../IgniteCacheCrossCacheTxFailoverTest.java | 19 +
.../dht/IgniteCacheLockFailoverSelfTest.java | 11 +
...eAtomicInvalidPartitionHandlingSelfTest.java | 6 +-
.../near/GridCacheNearTxExceptionSelfTest.java | 1 +
...CachePartitionedTxMultiThreadedSelfTest.java | 15 +-
.../DataStreamerUpdateAfterLoadTest.java | 184 +
.../loadtests/hashmap/GridHashMapLoadTest.java | 6 +-
.../inmemory/GridTestSwapSpaceSpi.java | 8 +
.../junits/common/GridCommonAbstractTest.java | 19 +-
.../ignite/testsuites/IgniteCacheTestSuite.java | 4 +-
.../testsuites/IgniteCacheTestSuite2.java | 2 +
.../testsuites/IgniteCacheTestSuite5.java | 40 +
.../config/benchmark-multicast.properties | 5 +-
.../IgniteAccountSerializableTxBenchmark.java | 81 +
.../cache/IgniteAccountTxAbstractBenchmark.java | 61 +
.../cache/IgniteAccountTxBenchmark.java | 74 +
.../cache/IgniteCacheAbstractBenchmark.java | 7 +-
.../IgnitePutAllSerializableTxBenchmark.java | 77 +
.../ignite/yardstick/cache/model/Account.java | 42 +
83 files changed, 9229 insertions(+), 2239 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
index 7d3cebb..fc2a6cb 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
@@ -92,15 +92,17 @@ public class TransactionConfiguration implements Serializable {
*
* @return {@code True} if serializable transactions are enabled, {@code false} otherwise.
*/
+ @Deprecated
public boolean isTxSerializableEnabled() {
return txSerEnabled;
}
/**
- * Enables/disables serializable cache transactions. See {@link #isTxSerializableEnabled()} for more information.
- *
* @param txSerEnabled Flag to enable/disable serializable cache transactions.
+
+ * @deprecated This method has no effect, {@link TransactionIsolation#SERIALIZABLE} isolation is always enabled.
*/
+ @Deprecated
public void setTxSerializableEnabled(boolean txSerEnabled) {
this.txSerEnabled = txSerEnabled;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
index dfa0217..a60c22b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
@@ -351,7 +351,7 @@ public class CacheMetricsImpl implements CacheMetrics {
/** {@inheritDoc} */
@Override public int getTxCommitQueueSize() {
- return cctx.tm().commitQueueSize();
+ return 0;
}
/** {@inheritDoc} */
@@ -366,12 +366,12 @@ public class CacheMetricsImpl implements CacheMetrics {
/** {@inheritDoc} */
@Override public int getTxPrepareQueueSize() {
- return cctx.tm().prepareQueueSize();
+ return 0;
}
/** {@inheritDoc} */
@Override public int getTxStartVersionCountsSize() {
- return cctx.tm().startVersionCountsSize();
+ return 0;
}
/** {@inheritDoc} */
@@ -396,17 +396,17 @@ public class CacheMetricsImpl implements CacheMetrics {
/** {@inheritDoc} */
@Override public int getTxDhtCommitQueueSize() {
- return cctx.isNear() && dhtCtx != null ? dhtCtx.tm().commitQueueSize() : -1;
+ return 0;
}
/** {@inheritDoc} */
@Override public int getTxDhtPrepareQueueSize() {
- return cctx.isNear() && dhtCtx != null ? dhtCtx.tm().prepareQueueSize() : -1;
+ return 0;
}
/** {@inheritDoc} */
@Override public int getTxDhtStartVersionCountsSize() {
- return cctx.isNear() && dhtCtx != null ? dhtCtx.tm().startVersionCountsSize() : -1;
+ return 0;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 417b396..74951b5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -608,7 +608,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
Collections.singletonList(key),
/*force primary*/false,
/*skip tx*/false,
- /*entry*/null,
/*subj id*/null,
/*task name*/null,
/*deserialize portable*/false,
@@ -643,7 +642,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
keys,
/*force primary*/false,
/*skip tx*/false,
- /*entry*/null,
/*subj id*/null,
/*task name*/null,
/*deserialize portable*/false,
@@ -1273,7 +1271,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
F.asList(key),
/*force primary*/true,
/*skip tx*/false,
- /*cached entry*/null,
/*subject id*/null,
taskName,
/*deserialize cache objects*/true,
@@ -1291,7 +1288,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
/*force primary*/true,
/*skip tx*/false,
null,
- null,
taskName,
true,
false,
@@ -1317,7 +1313,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
F.asList(key),
/*force primary*/false,
/*skip tx*/false,
- /*cached entry*/null,
/*subject id*/null,
taskName,
/*deserialize cache objects*/true,
@@ -1339,7 +1334,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
!ctx.config().isReadFromBackup(),
/*skip tx*/true,
null,
- null,
taskName,
!ctx.keepPortable(),
/*skip values*/false,
@@ -1347,184 +1341,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
/**
- * @param keys Keys.
- * @param reload Reload flag.
- * @param tx Transaction.
- * @param subjId Subject ID.
- * @param taskName Task name.
- * @param vis Visitor.
- * @return Future.
- */
- public IgniteInternalFuture<Object> readThroughAllAsync(final Collection<KeyCacheObject> keys,
- boolean reload,
- boolean skipVals,
- @Nullable final IgniteInternalTx tx,
- @Nullable UUID subjId,
- String taskName,
- final IgniteBiInClosure<KeyCacheObject, Object> vis) {
- return ctx.closures().callLocalSafe(new GPC<Object>() {
- @Nullable @Override public Object call() {
- try {
- ctx.store().loadAll(tx, keys, vis);
- }
- catch (IgniteCheckedException e) {
- throw new GridClosureException(e);
- }
-
- return null;
- }
- }, true);
- }
-
- /**
- * @param keys Keys.
- * @param ret Return flag.
- * @param skipVals Skip values flag.
- * @param subjId Subject ID.
- * @param taskName Task name.
- * @return Future.
- */
- public IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> reloadAllAsync0(
- Collection<KeyCacheObject> keys,
- boolean ret,
- boolean skipVals,
- @Nullable UUID subjId,
- String taskName)
- {
- final AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
-
- if (!F.isEmpty(keys)) {
- final Map<KeyCacheObject, GridCacheVersion> keyVers = new HashMap();
-
- for (KeyCacheObject key : keys) {
- if (key == null)
- continue;
-
- // Skip primary or backup entries for near cache.
- if (ctx.isNear() && ctx.affinity().localNode(key, topVer))
- continue;
-
- while (true) {
- try {
- GridCacheEntryEx entry = entryExSafe(key, topVer);
-
- if (entry == null)
- break;
-
- GridCacheVersion ver = entry.version();
-
- keyVers.put(key, ver);
-
- break;
- }
- catch (GridCacheEntryRemovedException ignore) {
- if (log.isDebugEnabled())
- log.debug("Got removed entry for reload (will retry): " + key);
- }
- catch (GridDhtInvalidPartitionException ignore) {
- if (log.isDebugEnabled())
- log.debug("Got invalid partition for key (will skip): " + key);
-
- break;
- }
- }
- }
-
- final Map<KeyCacheObject, CacheObject> map =
- ret ? U.<KeyCacheObject, CacheObject>newHashMap(keys.size()) : null;
-
- final Collection<KeyCacheObject> absentKeys = F.view(keyVers.keySet());
-
- final Collection<KeyCacheObject> loadedKeys = new GridConcurrentHashSet<>();
-
- IgniteInternalFuture<Object> readFut = readThroughAllAsync(absentKeys, true, skipVals, null,
- subjId, taskName, new CI2<KeyCacheObject, Object>() {
- /** Version for all loaded entries. */
- private GridCacheVersion nextVer = ctx.versions().next();
-
- /** {@inheritDoc} */
- @Override public void apply(KeyCacheObject key, Object val) {
- loadedKeys.add(key);
-
- GridCacheEntryEx entry = peekEx(key);
-
- if (entry != null) {
- try {
- GridCacheVersion curVer = keyVers.get(key);
-
- if (curVer != null) {
- boolean wasNew = entry.isNewLocked();
-
- entry.unswap();
-
- CacheObject cacheVal = ctx.toCacheObject(val);
-
- boolean set = entry.versionedValue(cacheVal, curVer, nextVer);
-
- ctx.evicts().touch(entry, topVer);
-
- if (map != null) {
- if (set || wasNew)
- map.put(key, cacheVal);
- else {
- CacheObject v = entry.peek(true, false, false, null);
-
- if (v != null)
- map.put(key, v);
- }
- }
-
- if (log.isDebugEnabled()) {
- log.debug("Set value loaded from store into entry [set=" + set + ", " +
- "curVer=" +
- curVer + ", newVer=" + nextVer + ", entry=" + entry + ']');
- }
- }
- else {
- if (log.isDebugEnabled()) {
- log.debug("Current version was not found (either entry was removed or " +
- "validation was not passed: " + entry);
- }
- }
- }
- catch (GridCacheEntryRemovedException ignore) {
- if (log.isDebugEnabled()) {
- log.debug("Got removed entry for reload (will not store reloaded entry) " +
- "[entry=" + entry + ']');
- }
- }
- catch (IgniteCheckedException e) {
- throw new IgniteException(e);
- }
- }
- }
- });
-
- return readFut.chain(new CX1<IgniteInternalFuture<Object>, Map<KeyCacheObject, CacheObject>>() {
- @Override public Map<KeyCacheObject, CacheObject> applyx(IgniteInternalFuture<Object> e)
- throws IgniteCheckedException {
- // Touch all not loaded keys.
- for (KeyCacheObject key : absentKeys) {
- if (!loadedKeys.contains(key)) {
- GridCacheEntryEx entry = peekEx(key);
-
- if (entry != null)
- ctx.evicts().touch(entry, topVer);
- }
- }
-
- // Make sure there were no exceptions.
- e.get();
-
- return map;
- }
- });
- }
-
- return new GridFinishedFuture<>(Collections.<KeyCacheObject, CacheObject>emptyMap());
- }
-
- /**
* @param key Key.
* @param topVer Topology version.
* @return Entry.
@@ -1662,11 +1478,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
* @param keys Keys.
* @param forcePrimary Force primary.
* @param skipTx Skip tx.
- * @param entry Entry.
* @param subjId Subj Id.
* @param taskName Task name.
* @param deserializePortable Deserialize portable.
* @param skipVals Skip values.
+ * @param canRemap Can remap flag.
* @return Future for the get operation.
* @see GridCacheAdapter#getAllAsync(Collection)
*/
@@ -1674,7 +1490,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
@Nullable Collection<? extends K> keys,
boolean forcePrimary,
boolean skipTx,
- @Nullable GridCacheEntryEx entry,
@Nullable UUID subjId,
String taskName,
boolean deserializePortable,
@@ -1687,7 +1502,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return getAllAsync(keys,
opCtx == null || !opCtx.skipStore(),
- entry,
!skipTx,
subjId,
taskName,
@@ -1701,7 +1515,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
/**
* @param keys Keys.
* @param readThrough Read through.
- * @param cached Cached.
* @param checkTx Check tx.
* @param subjId Subj Id.
* @param taskName Task name.
@@ -1709,12 +1522,12 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
* @param forcePrimary Froce primary.
* @param expiry Expiry policy.
* @param skipVals Skip values.
+ * @param canRemap Can remap flag.
* @return Future for the get operation.
* @see GridCacheAdapter#getAllAsync(Collection)
*/
public IgniteInternalFuture<Map<K, V>> getAllAsync(@Nullable final Collection<? extends K> keys,
boolean readThrough,
- @Nullable GridCacheEntryEx cached,
boolean checkTx,
@Nullable final UUID subjId,
final String taskName,
@@ -1738,7 +1551,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
expiry,
skipVals,
false,
- canRemap);
+ canRemap,
+ false);
}
/**
@@ -1750,10 +1564,12 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
* @param deserializePortable Deserialize portable flag.
* @param expiry Expiry policy.
* @param skipVals Skip values flag.
- * @param keepCacheObjects Keep cache objects
+ * @param keepCacheObjects Keep cache objects.
+ * @param canRemap Can remap flag.
+ * @param needVer If {@code true} returns values as tuples containing value and version.
* @return Future.
*/
- public <K1, V1> IgniteInternalFuture<Map<K1, V1>> getAllAsync0(@Nullable final Collection<KeyCacheObject> keys,
+ public final <K1, V1> IgniteInternalFuture<Map<K1, V1>> getAllAsync0(@Nullable final Collection<KeyCacheObject> keys,
final boolean readThrough,
boolean checkTx,
@Nullable final UUID subjId,
@@ -1762,7 +1578,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
@Nullable IgniteCacheExpiryPolicy expiry,
final boolean skipVals,
final boolean keepCacheObjects,
- boolean canRemap
+ boolean canRemap,
+ final boolean needVer
) {
if (F.isEmpty(keys))
return new GridFinishedFuture<>(Collections.<K1, V1>emptyMap());
@@ -1782,14 +1599,14 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (tx == null || tx.implicit()) {
try {
- assert keys != null;
-
final AffinityTopologyVersion topVer = tx == null
? (canRemap ? ctx.affinity().affinityTopologyVersion(): ctx.shared().exchange().readyAffinityVersion())
: tx.topologyVersion();
final Map<K1, V1> map = new GridLeanMap<>(keys.size());
+ final boolean storeEnabled = !skipVals && readThrough && ctx.readThrough();
+
Map<KeyCacheObject, GridCacheVersion> misses = null;
for (KeyCacheObject key : keys) {
@@ -1797,29 +1614,43 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
GridCacheEntryEx entry = entryEx(key);
try {
- CacheObject val = entry.innerGet(null,
+ T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(null,
ctx.isSwapOrOffheapEnabled(),
- /*don't read-through*/false,
- /*fail-fast*/true,
/*unmarshal*/true,
/*update-metrics*/!skipVals,
/*event*/!skipVals,
- /*temporary*/false,
subjId,
null,
taskName,
expiry);
- if (val == null) {
- GridCacheVersion ver = entry.version();
+ if (res == null) {
+ if (storeEnabled) {
+ GridCacheVersion ver = entry.version();
- if (misses == null)
- misses = new GridLeanMap<>();
+ if (misses == null)
+ misses = new GridLeanMap<>();
- misses.put(key, ver);
+ misses.put(key, ver);
+ }
+ else
+ ctx.evicts().touch(entry, topVer);
}
else {
- ctx.addResult(map, key, val, skipVals, keepCacheObjects, deserializePortable, true);
+ if (needVer) {
+ assert keepCacheObjects;
+
+ map.put((K1)key, (V1)new T2<>(res.get1(), res.get2()));
+ }
+ else {
+ ctx.addResult(map,
+ key,
+ res.get1(),
+ skipVals,
+ keepCacheObjects,
+ deserializePortable,
+ true);
+ }
if (tx == null || (!tx.implicit() && tx.isolation() == READ_COMMITTED))
ctx.evicts().touch(entry, topVer);
@@ -1835,19 +1666,10 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (log.isDebugEnabled())
log.debug("Got removed entry in getAllAsync(..) method (will retry): " + key);
}
- catch (GridCacheFilterFailedException ignore) {
- if (log.isDebugEnabled())
- log.debug("Filter validation failed for entry: " + entry);
-
- if (tx == null || (!tx.implicit() && tx.isolation() == READ_COMMITTED))
- ctx.evicts().touch(entry, topVer);
-
- break; // While loop.
- }
}
}
- if (!skipVals && misses != null && readThrough && ctx.readThrough()) {
+ if (storeEnabled && misses != null) {
final Map<KeyCacheObject, GridCacheVersion> loadKeys = misses;
final IgniteTxLocalAdapter tx0 = tx;
@@ -1858,9 +1680,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
ctx.closures().callLocalSafe(ctx.projectSafe(new GPC<Map<K1, V1>>() {
@Override public Map<K1, V1> call() throws Exception {
ctx.store().loadAll(null/*tx*/, loadKeys.keySet(), new CI2<KeyCacheObject, Object>() {
- /** New version for all new entries. */
- private GridCacheVersion nextVer;
-
@Override public void apply(KeyCacheObject key, Object val) {
GridCacheVersion ver = loadKeys.get(key);
@@ -1872,10 +1691,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return;
}
- // Initialize next version.
- if (nextVer == null)
- nextVer = ctx.versions().next();
-
loaded.add(key);
CacheObject cacheVal = ctx.toCacheObject(val);
@@ -1884,22 +1699,33 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
GridCacheEntryEx entry = entryEx(key);
try {
- boolean set = entry.versionedValue(cacheVal, ver, nextVer);
+ GridCacheVersion verSet = entry.versionedValue(cacheVal, ver, null);
+
+ boolean set = verSet != null;
if (log.isDebugEnabled())
- log.debug("Set value loaded from store into entry [set=" + set +
- ", curVer=" + ver + ", newVer=" + nextVer + ", " +
+ log.debug("Set value loaded from store into entry [" +
+ "set=" + set +
+ ", curVer=" + ver +
+ ", newVer=" + verSet + ", " +
"entry=" + entry + ']');
// Don't put key-value pair into result map if value is null.
if (val != null) {
- ctx.addResult(map,
- key,
- cacheVal,
- skipVals,
- keepCacheObjects,
- deserializePortable,
- false);
+ if (needVer) {
+ assert keepCacheObjects;
+
+ map.put((K1)key, (V1)new T2<>(cacheVal, set ? verSet : ver));
+ }
+ else {
+ ctx.addResult(map,
+ key,
+ cacheVal,
+ skipVals,
+ keepCacheObjects,
+ deserializePortable,
+ false);
+ }
}
if (tx0 == null || (!tx0.implicit() &&
@@ -1992,9 +1818,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
}
else {
+ assert !needVer;
+
return asyncOp(tx, new AsyncOp<Map<K1, V1>>(keys) {
@Override public IgniteInternalFuture<Map<K1, V1>> op(IgniteTxLocalAdapter tx) {
- return tx.getAllAsync(ctx, keys, null, deserializePortable, skipVals, false, !readThrough);
+ return tx.getAllAsync(ctx, keys, deserializePortable, skipVals, false, !readThrough);
}
});
}
@@ -2028,7 +1856,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
V prevVal = syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, null, -1, filter).get().value();
+ return (V)tx.putAllAsync(ctx, F.t(key, val), true, filter).get().value();
}
@Override public String toString() {
@@ -2083,7 +1911,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, null, -1, filter)
+ return tx.putAllAsync(ctx, F.t(key, val), true, filter)
.chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@@ -2122,7 +1950,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
Boolean stored = syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, filter).get().success();
+ return tx.putAllAsync(ctx, F.t(key, val), false, filter).get().success();
}
@Override public String toString() {
@@ -2414,7 +2242,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, filter).chain(
+ return tx.putAllAsync(ctx, F.t(key, val), false, filter).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
}
@@ -2449,7 +2277,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.noValArray()).get().value();
+ return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray()).get().value();
}
@Override public String toString() {
@@ -2473,7 +2301,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.noValArray())
+ return tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray())
.chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>) RET2VAL);
}
@@ -2503,7 +2331,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
Boolean stored = syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.noValArray()).get().success();
+ return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).get().success();
}
@Override public String toString() {
@@ -2532,7 +2360,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<Boolean> fut = asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.noValArray()).chain(
+ return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -2558,7 +2386,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.hasValArray()).get().value();
+ return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).get().value();
}
@Override public String toString() {
@@ -2582,7 +2410,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.hasValArray()).chain(
+ return tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@@ -2608,7 +2436,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.hasValArray()).get().success();
+ return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).get().success();
}
@Override public String toString() {
@@ -2628,7 +2456,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.hasValArray()).chain(
+ return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
}
@@ -2655,7 +2483,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (ctx.deploymentEnabled())
ctx.deploy().registerClass(oldVal);
- return tx.putAllAsync(ctx, F.t(key, newVal), false, null, -1, ctx.equalsValArray(oldVal)).get()
+ return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).get()
.success();
}
@@ -2692,7 +2520,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
}
- return tx.putAllAsync(ctx, F.t(key, newVal), false, null, -1, ctx.equalsValArray(oldVal)).chain(
+ return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -2723,7 +2551,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
syncOp(new SyncInOp(m.size() == 1) {
@Override public void inOp(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- tx.putAllAsync(ctx, m, false, null, -1, CU.empty0()).get();
+ tx.putAllAsync(ctx, m, false, CU.empty0()).get();
}
@Override public String toString() {
@@ -2747,7 +2575,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncInOp(m.keySet()) {
@Override public IgniteInternalFuture<?> inOp(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, m, false, null, -1, CU.empty0()).chain(RET2NULL);
+ return tx.putAllAsync(ctx, m, false, CU.empty0()).chain(RET2NULL);
}
@Override public String toString() {
@@ -2769,7 +2597,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
V prevVal = syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- V ret = tx.removeAllAsync(ctx, Collections.singletonList(key), null, true, CU.empty0()).get().value();
+ V ret = tx.removeAllAsync(ctx,
+ Collections.singletonList(key),
+ /*retval*/true,
+ CU.empty0(),
+ /*singleRmv*/false).get().value();
if (ctx.config().getInterceptor() != null)
return (V)ctx.config().getInterceptor().onBeforeRemove(new CacheEntryImpl(key, ret)).get2();
@@ -2802,8 +2634,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
// TODO should we invoke interceptor here?
- return tx.removeAllAsync(ctx, Collections.singletonList(key), null, true, CU.empty0())
- .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>) RET2VAL);
+ return tx.removeAllAsync(ctx,
+ Collections.singletonList(key),
+ /*retval*/true,
+ CU.empty0(),
+ /*singleRmv*/false).chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@Override public String toString() {
@@ -2849,7 +2684,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
syncOp(new SyncInOp(keys.size() == 1) {
@Override public void inOp(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- tx.removeAllAsync(ctx, keys, null, false, CU.empty0()).get();
+ tx.removeAllAsync(ctx,
+ keys,
+ /*retval*/false,
+ CU.empty0(),
+ /*singleRmv*/false).get();
}
@Override public String toString() {
@@ -2875,7 +2714,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<Object> fut = asyncOp(new AsyncInOp(keys) {
@Override public IgniteInternalFuture<?> inOp(IgniteTxLocalAdapter tx) {
- return tx.removeAllAsync(ctx, keys, null, false, CU.empty0()).chain(RET2NULL);
+ return tx.removeAllAsync(ctx,
+ keys,
+ /*retval*/false,
+ CU.empty0(),
+ /*singleRmv*/false).chain(RET2NULL);
}
@Override public String toString() {
@@ -2902,7 +2745,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
boolean rmv = syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false, CU.empty0()).get().success();
+ return tx.removeAllAsync(ctx,
+ Collections.singletonList(key),
+ /*retval*/false,
+ CU.empty0(),
+ /*singleRmv*/true).get().success();
}
@Override public String toString() {
@@ -2940,7 +2787,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<Boolean> fut = asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false, filter).chain(
+ return tx.removeAllAsync(ctx,
+ Collections.singletonList(key),
+ /*retval*/false,
+ filter,
+ /*singleRmv*/true).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -2970,9 +2821,9 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return tx.removeAllAsync(ctx,
Collections.singletonList(key),
- null,
- true,
- ctx.equalsValArray(val)).get();
+ /*retval*/true,
+ ctx.equalsValArray(val),
+ /*singleRmv*/false).get();
}
@Override public String toString() {
@@ -3037,8 +2888,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return tx.putAllAsync(ctx,
F.t(key, newVal),
true,
- null,
- -1,
ctx.equalsValArray(oldVal)).get();
}
@@ -3066,13 +2915,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return new GridFinishedFuture<>(e);
}
- IgniteInternalFuture<GridCacheReturn> fut = (IgniteInternalFuture)tx.removeAllAsync(ctx,
+ return (IgniteInternalFuture)tx.removeAllAsync(ctx,
Collections.singletonList(key),
- null,
- true,
- ctx.equalsValArray(val));
-
- return fut;
+ /*retval*/true,
+ ctx.equalsValArray(val),
+ /*singleRmv*/false);
}
@Override public String toString() {
@@ -3100,14 +2947,10 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return new GridFinishedFuture<>(e);
}
- IgniteInternalFuture<GridCacheReturn> fut = (IgniteInternalFuture)tx.putAllAsync(ctx,
+ return (IgniteInternalFuture)tx.putAllAsync(ctx,
F.t(key, newVal),
true,
- null,
- -1,
ctx.equalsValArray(oldVal));
-
- return fut;
}
@Override public String toString() {
@@ -3135,8 +2978,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (ctx.deploymentEnabled())
ctx.deploy().registerClass(val);
- return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false,
- ctx.equalsValArray(val)).get().success();
+ return tx.removeAllAsync(ctx,
+ Collections.singletonList(key),
+ /*retval*/false,
+ ctx.equalsValArray(val),
+ /*singleRmv*/false).get().success();
}
@Override public String toString() {
@@ -3175,8 +3021,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
}
- return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false,
- ctx.equalsValArray(val)).chain(
+ return tx.removeAllAsync(ctx,
+ Collections.singletonList(key),
+ /*retval*/false,
+ ctx.equalsValArray(val),
+ /*singleRmv*/false).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -3200,7 +3049,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncInOp(keys) {
@Override public IgniteInternalFuture<?> inOp(IgniteTxLocalAdapter tx) {
- return tx.removeAllAsync(ctx, keys, null, false, null);
+ return tx.removeAllAsync(ctx,
+ keys,
+ /*retval*/false,
+ null,
+ /*singleRmv*/false);
}
@Override public String toString() {
@@ -4579,7 +4432,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
!ctx.config().isReadFromBackup(),
/*skip tx*/false,
null,
- null,
taskName,
deserializePortable,
false,
@@ -4741,41 +4593,34 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
boolean deserializePortable)
throws IgniteCheckedException, GridCacheEntryRemovedException
{
- try {
- CacheObject val = entry.innerGet(
- null,
- false,
- false,
- false,
- true,
- false,
- false,
- false,
- null,
- null,
- null,
- null);
-
- if (val == null)
- return null;
+ CacheObject val = entry.innerGet(
+ null,
+ false,
+ false,
+ false,
+ true,
+ false,
+ false,
+ false,
+ null,
+ null,
+ null,
+ null);
- KeyCacheObject key = entry.key();
+ if (val == null)
+ return null;
- Object key0 = key.value(ctx.cacheObjectContext(), true);
- Object val0 = val.value(ctx.cacheObjectContext(), true);
+ KeyCacheObject key = entry.key();
- if (deserializePortable) {
- key0 = ctx.unwrapPortableIfNeeded(key0, true);
- val0 = ctx.unwrapPortableIfNeeded(val0, true);
- }
+ Object key0 = key.value(ctx.cacheObjectContext(), true);
+ Object val0 = val.value(ctx.cacheObjectContext(), true);
- return new CacheEntryImpl<>((K)key0, (V)val0, entry.version());
+ if (deserializePortable) {
+ key0 = ctx.unwrapPortableIfNeeded(key0, true);
+ val0 = ctx.unwrapPortableIfNeeded(val0, true);
}
- catch (GridCacheFilterFailedException ignore) {
- assert false;
- return null;
- }
+ return new CacheEntryImpl<>((K)key0, (V)val0, entry.version());
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
index 430590a..50b01c8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
@@ -33,6 +33,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionedEntryEx;
import org.apache.ignite.internal.processors.dr.GridDrType;
import org.apache.ignite.internal.util.lang.GridTuple3;
+import org.apache.ignite.internal.util.typedef.T2;
import org.jetbrains.annotations.Nullable;
/**
@@ -286,12 +287,10 @@ public interface GridCacheEntryEx {
* @param subjId Subject ID initiated this read.
* @param transformClo Transform closure to record event.
* @param taskName Task name.
- * together with getting the value is an atomic operation.
* @param expiryPlc Expiry policy.
* @return Cached value.
* @throws IgniteCheckedException If loading value failed.
* @throws GridCacheEntryRemovedException If entry was removed.
- * @throws GridCacheFilterFailedException If filter failed.
*/
@Nullable public CacheObject innerGet(@Nullable IgniteInternalTx tx,
boolean readSwap,
@@ -305,7 +304,33 @@ public interface GridCacheEntryEx {
Object transformClo,
String taskName,
@Nullable IgniteCacheExpiryPolicy expiryPlc)
- throws IgniteCheckedException, GridCacheEntryRemovedException, GridCacheFilterFailedException;
+ throws IgniteCheckedException, GridCacheEntryRemovedException;
+
+ /**
+ * @param tx Cache transaction.
+ * @param readSwap Flag indicating whether to check swap memory.
+ * @param unmarshal Unmarshal flag.
+ * @param updateMetrics If {@code true} then metrics should be updated.
+ * @param evt Flag to signal event notification.
+ * @param subjId Subject ID initiated this read.
+ * @param transformClo Transform closure to record event.
+ * @param taskName Task name.
+ * @param expiryPlc Expiry policy.
+ * @return Cached value and entry version.
+ * @throws IgniteCheckedException If loading value failed.
+ * @throws GridCacheEntryRemovedException If entry was removed.
+ */
+ @Nullable public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+ IgniteInternalTx tx,
+ boolean readSwap,
+ boolean unmarshal,
+ boolean updateMetrics,
+ boolean evt,
+ UUID subjId,
+ Object transformClo,
+ String taskName,
+ @Nullable IgniteCacheExpiryPolicy expiryPlc)
+ throws IgniteCheckedException, GridCacheEntryRemovedException;
/**
* Reloads entry from underlying storage.
@@ -334,6 +359,7 @@ public interface GridCacheEntryEx {
* @param explicitVer Explicit version (if any).
* @param subjId Subject ID initiated this update.
* @param taskName Task name.
+ * @param dhtVer Dht version for near cache entry.
* @return Tuple containing success flag and old value. If success is {@code false},
* then value is {@code null}.
* @throws IgniteCheckedException If storing value failed.
@@ -355,7 +381,8 @@ public interface GridCacheEntryEx {
long drExpireTime,
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
- String taskName
+ String taskName,
+ @Nullable GridCacheVersion dhtVer
) throws IgniteCheckedException, GridCacheEntryRemovedException;
/**
@@ -372,6 +399,7 @@ public interface GridCacheEntryEx {
* @param explicitVer Explicit version (if any).
* @param subjId Subject ID initiated this update.
* @param taskName Task name.
+ * @param dhtVer Dht version for near cache entry.
* @return Tuple containing success flag and old value. If success is {@code false},
* then value is {@code null}.
* @throws IgniteCheckedException If remove failed.
@@ -390,7 +418,8 @@ public interface GridCacheEntryEx {
GridDrType drType,
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
- String taskName
+ String taskName,
+ @Nullable GridCacheVersion dhtVer
) throws IgniteCheckedException, GridCacheEntryRemovedException;
/**
@@ -409,6 +438,7 @@ public interface GridCacheEntryEx {
* @param primary If update is performed on primary node (the one which assigns version).
* @param checkVer Whether update should check current version and ignore update if current version is
* greater than passed in.
+ * @param topVer Topology version.
* @param filter Optional filter to check.
* @param drType DR type.
* @param conflictTtl Conflict TTL (if any).
@@ -510,12 +540,17 @@ public interface GridCacheEntryEx {
*
* @param tx Cache transaction.
* @param timeout Timeout for lock acquisition.
+ * @param serOrder Version for serializable transactions ordering.
+ * @param serReadVer Optional read entry version for optimistic serializable transaction.
* @return {@code True} if lock was acquired, {@code false} otherwise.
* @throws GridCacheEntryRemovedException If this entry is obsolete.
* @throws GridDistributedLockCancelledException If lock has been cancelled.
*/
- public boolean tmLock(IgniteInternalTx tx, long timeout) throws GridCacheEntryRemovedException,
- GridDistributedLockCancelledException;
+ public boolean tmLock(IgniteInternalTx tx,
+ long timeout,
+ @Nullable GridCacheVersion serOrder,
+ @Nullable GridCacheVersion serReadVer)
+ throws GridCacheEntryRemovedException, GridDistributedLockCancelledException;
/**
* Unlocks acquired lock.
@@ -566,6 +601,15 @@ public interface GridCacheEntryEx {
public GridCacheVersion version() throws GridCacheEntryRemovedException;
/**
+ * Checks if there was read/write conflict in serializable transaction.
+ *
+ * @param serReadVer Version read in serializable transaction.
+ * @return {@code True} if version check passed.
+ * @throws GridCacheEntryRemovedException If entry has been removed.
+ */
+ public boolean checkSerializableReadVersion(GridCacheVersion serReadVer) throws GridCacheEntryRemovedException;
+
+ /**
* Peeks into entry without loading value or updating statistics.
*
* @param heap Read from heap flag.
@@ -653,11 +697,11 @@ public interface GridCacheEntryEx {
* @param val New value.
* @param curVer Version to match or {@code null} if match is not required.
* @param newVer Version to set.
- * @return {@code True} if versioned matched.
+ * @return Non null version if value was set.
* @throws IgniteCheckedException If index could not be updated.
* @throws GridCacheEntryRemovedException If entry was removed.
*/
- public boolean versionedValue(CacheObject val,
+ public GridCacheVersion versionedValue(CacheObject val,
@Nullable GridCacheVersion curVer,
@Nullable GridCacheVersion newVer)
throws IgniteCheckedException, GridCacheEntryRemovedException;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 4bf0aa1..2111594 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -37,12 +37,14 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo;
import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
import org.apache.ignite.internal.processors.cache.extras.GridCacheEntryExtras;
import org.apache.ignite.internal.processors.cache.extras.GridCacheMvccEntryExtras;
import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntryExtras;
import org.apache.ignite.internal.processors.cache.extras.GridCacheTtlEntryExtras;
import org.apache.ignite.internal.processors.cache.query.GridCacheQueryManager;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalAdapter;
import org.apache.ignite.internal.processors.cache.version.GridCachePlainVersionedEntry;
@@ -59,6 +61,7 @@ import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.T3;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -673,7 +676,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
String taskName,
@Nullable IgniteCacheExpiryPolicy expirePlc)
throws IgniteCheckedException, GridCacheEntryRemovedException {
- return innerGet0(tx,
+ return (CacheObject)innerGet0(tx,
readSwap,
readThrough,
evt,
@@ -683,12 +686,39 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
subjId,
transformClo,
taskName,
- expirePlc);
+ expirePlc,
+ false);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+ IgniteInternalTx tx,
+ boolean readSwap,
+ boolean unmarshal,
+ boolean updateMetrics,
+ boolean evt,
+ UUID subjId,
+ Object transformClo,
+ String taskName,
+ @Nullable IgniteCacheExpiryPolicy expiryPlc)
+ throws IgniteCheckedException, GridCacheEntryRemovedException {
+ return (T2<CacheObject, GridCacheVersion>)innerGet0(tx,
+ readSwap,
+ false,
+ evt,
+ unmarshal,
+ updateMetrics,
+ false,
+ subjId,
+ transformClo,
+ taskName,
+ expiryPlc,
+ true);
}
/** {@inheritDoc} */
@SuppressWarnings({"unchecked", "RedundantTypeArguments", "TooBroadScope"})
- private CacheObject innerGet0(IgniteInternalTx tx,
+ private Object innerGet0(IgniteInternalTx tx,
boolean readSwap,
boolean readThrough,
boolean evt,
@@ -698,8 +728,11 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
UUID subjId,
Object transformClo,
String taskName,
- @Nullable IgniteCacheExpiryPolicy expiryPlc)
+ @Nullable IgniteCacheExpiryPolicy expiryPlc,
+ boolean retVer)
throws IgniteCheckedException, GridCacheEntryRemovedException {
+ assert !(retVer && readThrough);
+
// Disable read-through if there is no store.
if (readThrough && !cctx.readThrough())
readThrough = false;
@@ -710,6 +743,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CacheObject ret = null;
GridCacheVersion startVer;
+ GridCacheVersion resVer = null;
boolean expired = false;
@@ -840,11 +874,18 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (ret != null && expiryPlc != null)
updateTtl(expiryPlc);
+
+ if (retVer) {
+ resVer = isNear() ? ((GridNearCacheEntry)this).dhtVersion() : this.ver;
+
+ if (resVer == null)
+ ret = null;
+ }
}
if (ret != null)
// If return value is consistent, then done.
- return ret;
+ return retVer ? new T2<>(ret, resVer) : ret;
boolean loadedFromStore = false;
@@ -906,6 +947,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
}
+ assert ret == null || !retVer;
+
return ret;
}
@@ -1015,7 +1058,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
long drExpireTime,
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
- String taskName
+ String taskName,
+ @Nullable GridCacheVersion dhtVer
) throws IgniteCheckedException, GridCacheEntryRemovedException {
CacheObject old;
@@ -1035,6 +1079,14 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
synchronized (this) {
checkObsolete();
+ if (isNear()) {
+ assert dhtVer != null;
+
+ // It is possible that 'get' could load more recent value.
+ if (!((GridNearCacheEntry)this).recordDhtVersion(dhtVer))
+ return new GridCacheUpdateTxResult(false, null);
+ }
+
assert tx == null || (!tx.local() && tx.onePhaseCommit()) || tx.ownsLock(this) :
"Transaction does not own lock for update [entry=" + this + ", tx=" + tx + ']';
@@ -1169,8 +1221,9 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
GridDrType drType,
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
- String taskName
- ) throws IgniteCheckedException, GridCacheEntryRemovedException {
+ String taskName,
+ @Nullable GridCacheVersion dhtVer
+ ) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert cctx.transactional();
CacheObject old;
@@ -1194,6 +1247,14 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
synchronized (this) {
checkObsolete();
+ if (isNear()) {
+ assert dhtVer != null;
+
+ // It is possible that 'get' could load more recent value.
+ if (!((GridNearCacheEntry)this).recordDhtVersion(dhtVer))
+ return new GridCacheUpdateTxResult(false, null);
+ }
+
assert tx == null || (!tx.local() && tx.onePhaseCommit()) || tx.ownsLock(this) :
"Transaction does not own lock for remove[entry=" + this + ", tx=" + tx + ']';
@@ -2549,6 +2610,13 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
/**
+ * @return {@code True} if this entry should not be evicted from cache.
+ */
+ protected boolean evictionDisabled() {
+ return false;
+ }
+
+ /**
* <p>
* Note that {@link #onMarkedObsolete()} should always be called after this method
* returns {@code true}.
@@ -2560,6 +2628,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
protected final boolean markObsolete0(GridCacheVersion ver, boolean clear) {
assert Thread.holdsLock(this);
+ if (evictionDisabled()) {
+ assert !obsolete() : this;
+
+ return false;
+ }
+
GridCacheVersion obsoleteVer = obsoleteVersionExtras();
if (ver != null) {
@@ -2790,6 +2864,25 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
return ver;
}
+ /** {@inheritDoc} */
+ @Override public synchronized boolean checkSerializableReadVersion(GridCacheVersion serReadVer)
+ throws GridCacheEntryRemovedException {
+ checkObsolete();
+
+ if (!serReadVer.equals(ver)) {
+ boolean empty = isStartVersion() || deletedUnlocked();
+
+ if (serReadVer.equals(IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER))
+ return empty;
+ else if (serReadVer.equals(IgniteTxEntry.SER_READ_NOT_EMPTY_VER))
+ return !empty;
+
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Gets hash value for the entry key.
*
@@ -3115,16 +3208,22 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
/** {@inheritDoc} */
- @Override public synchronized boolean versionedValue(CacheObject val,
+ @Override public synchronized GridCacheVersion versionedValue(CacheObject val,
GridCacheVersion curVer,
GridCacheVersion newVer)
throws IgniteCheckedException, GridCacheEntryRemovedException {
+
checkObsolete();
if (curVer == null || curVer.equals(ver)) {
if (val != this.val) {
+ GridCacheMvcc mvcc = mvccExtras();
+
+ if (mvcc != null && !mvcc.isEmpty())
+ return null;
+
if (newVer == null)
- newVer = nextVersion();
+ newVer = cctx.versions().next();
CacheObject old = rawGetOrUnmarshalUnlocked(false);
@@ -3144,12 +3243,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
// Version does not change for load ops.
update(val, expTime, ttl, newVer);
- }
- return true;
+ return newVer;
+ }
}
- return false;
+ return null;
}
/**
@@ -3683,6 +3782,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
try {
if (F.isEmptyOrNulls(filter)) {
synchronized (this) {
+ if (evictionDisabled()) {
+ assert !obsolete();
+
+ return false;
+ }
+
if (obsoleteVersionExtras() != null)
return true;
@@ -3727,6 +3832,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
return false;
synchronized (this) {
+ if (evictionDisabled()) {
+ assert !obsolete();
+
+ return false;
+ }
+
if (obsoleteVersionExtras() != null)
return true;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
index c2102bd..12583ad 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.cache;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
@@ -53,6 +54,32 @@ public final class GridCacheMvcc {
/** Logger. */
private static volatile IgniteLogger log;
+ /** */
+ private static final Comparator<GridCacheVersion> SER_VER_COMPARATOR = new Comparator<GridCacheVersion>() {
+ @Override public int compare(GridCacheVersion ver1, GridCacheVersion ver2) {
+ long time1 = ver1.globalTime();
+ long time2 = ver2.globalTime();
+
+ if (time1 == time2) {
+ int nodeOrder1 = ver1.nodeOrder();
+ int nodeOrder2 = ver2.nodeOrder();
+
+ if (nodeOrder1 == nodeOrder2) {
+ long order1 = ver1.order();
+ long order2 = ver2.order();
+
+ assert order1 != order2;
+
+ return order1 > order2 ? 1 : -1;
+ }
+ else
+ return nodeOrder1 > nodeOrder2 ? 1 : -1;
+ }
+ else
+ return time1 > time2 ? 1 : -1;
+ }
+ };
+
/** Cache context. */
@GridToStringExclude
private final GridCacheContext<?, ?> cctx;
@@ -160,8 +187,9 @@ public final class GridCacheMvcc {
/**
* @param cand Candidate to add.
+ * @return {@code False} if failed to add candidate and transaction should be cancelled.
*/
- private void add0(GridCacheMvccCandidate cand) {
+ private boolean add0(GridCacheMvccCandidate cand) {
assert cand != null;
// Local.
@@ -171,31 +199,59 @@ public final class GridCacheMvcc {
if (!cand.nearLocal()) {
if (!locs.isEmpty()) {
- GridCacheMvccCandidate c = locs.getFirst();
+ if (cand.serializable()) {
+ GridCacheMvccCandidate last = locs.getLast();
+
+ if (!last.serializable())
+ return false;
+
+ GridCacheVersion lastOrder = last.serializableOrder();
+
+ assert lastOrder != null : last;
+
+ GridCacheVersion candOrder = cand.serializableOrder();
- if (c.owner()) {
+ assert candOrder != null : cand;
+
+ int cmp = SER_VER_COMPARATOR.compare(lastOrder, candOrder);
+
+ assert cmp != 0;
+
+ if (cmp > 0)
+ return false;
+
+ locs.addLast(cand);
+
+ return true;
+ }
+
+ GridCacheMvccCandidate first = locs.getFirst();
+
+ if (first.owner()) {
// If reentry, add at the beginning. Note that
// no reentry happens for DHT-local candidates.
- if (!cand.dhtLocal() && c.threadId() == cand.threadId()) {
+ if (!cand.dhtLocal() && first.threadId() == cand.threadId()) {
+ assert !first.serializable();
+
cand.setOwner();
cand.setReady();
cand.setReentry();
locs.addFirst(cand);
- return;
+ return true;
}
}
// Iterate in reverse order.
for (ListIterator<GridCacheMvccCandidate> it = locs.listIterator(locs.size()); it.hasPrevious(); ) {
- c = it.previous();
+ GridCacheMvccCandidate c = it.previous();
assert !c.version().equals(cand.version()) : "Versions can't match [existing=" + c +
", new=" + cand + ']';
- // Add after the owner.
- if (c.owner()) {
+ // Add after the owner or serializable tx.
+ if (c.owner() || c.serializable()) {
// Threads are checked above.
assert cand.dhtLocal() || c.threadId() != cand.threadId();
@@ -204,7 +260,7 @@ public final class GridCacheMvcc {
it.add(cand);
- return;
+ return true;
}
// If not the owner, add after the lesser version.
@@ -214,7 +270,7 @@ public final class GridCacheMvcc {
it.add(cand);
- return;
+ return true;
}
}
}
@@ -228,6 +284,8 @@ public final class GridCacheMvcc {
}
// Remote.
else {
+ assert !cand.serializable() : cand;
+
if (rmts == null)
rmts = new LinkedList<>();
@@ -241,12 +299,14 @@ public final class GridCacheMvcc {
if (cand.owner())
cur.setOwner();
- return;
+ return true;
}
// Either list is empty or candidate is last.
rmts.add(cand);
}
+
+ return true;
}
/**
@@ -456,6 +516,7 @@ public final class GridCacheMvcc {
threadId,
ver,
timeout,
+ /*serializable order*/null,
reenter,
tx,
implicitSingle,
@@ -470,6 +531,7 @@ public final class GridCacheMvcc {
* @param threadId Thread ID.
* @param ver Lock version.
* @param timeout Lock acquisition timeout.
+ * @param serOrder Version for serializable transactions ordering.
* @param reenter Reentry flag ({@code true} if reentry is allowed).
* @param tx Transaction flag.
* @param implicitSingle Implicit flag.
@@ -484,6 +546,7 @@ public final class GridCacheMvcc {
long threadId,
GridCacheVersion ver,
long timeout,
+ @Nullable GridCacheVersion serOrder,
boolean reenter,
boolean tx,
boolean implicitSingle,
@@ -528,12 +591,23 @@ public final class GridCacheMvcc {
tx,
implicitSingle,
/*near-local*/false,
- dhtLoc
+ dhtLoc,
+ serOrder
);
- cctx.mvcc().addLocal(cand);
+ if (serOrder == null) {
+ cctx.mvcc().addLocal(cand);
- add0(cand);
+ boolean add = add0(cand);
+
+ assert add : cand;
+ }
+ else {
+ if (!add0(cand))
+ return null;
+
+ cctx.mvcc().addLocal(cand);
+ }
return cand;
}
@@ -575,7 +649,8 @@ public final class GridCacheMvcc {
tx,
implicitSingle,
nearLoc,
- false
+ false,
+ null
);
addRemote(cand);
@@ -596,11 +671,28 @@ public final class GridCacheMvcc {
* @param implicitSingle Implicit flag.
* @return Add remote candidate.
*/
- public GridCacheMvccCandidate addNearLocal(GridCacheEntryEx parent, UUID nodeId,
- @Nullable UUID otherNodeId, long threadId, GridCacheVersion ver, long timeout, boolean tx,
+ public GridCacheMvccCandidate addNearLocal(GridCacheEntryEx parent,
+ UUID nodeId,
+ @Nullable UUID otherNodeId,
+ long threadId,
+ GridCacheVersion ver,
+ long timeout,
+ boolean tx,
boolean implicitSingle) {
- GridCacheMvccCandidate cand = new GridCacheMvccCandidate(parent, nodeId, otherNodeId, null, threadId, ver,
- timeout, /*local*/true, /*reentry*/false, tx, implicitSingle, /*near loc*/true, /*dht loc*/false);
+ GridCacheMvccCandidate cand = new GridCacheMvccCandidate(parent,
+ nodeId,
+ otherNodeId,
+ null,
+ threadId,
+ ver,
+ timeout,
+ /*local*/true,
+ /*reentry*/false,
+ tx,
+ implicitSingle,
+ /*near loc*/true,
+ /*dht loc*/false,
+ null);
add0(cand);
@@ -855,9 +947,22 @@ public final class GridCacheMvcc {
}
if (locs != null) {
+ boolean first = true;
+
for (ListIterator<GridCacheMvccCandidate> it = locs.listIterator(); it.hasNext(); ) {
GridCacheMvccCandidate cand = it.next();
+ if (first && cand.serializable()) {
+ if (cand.owner() || !cand.ready())
+ return;
+
+ cand.setOwner();
+
+ return;
+ }
+
+ first = false;
+
if (cand.owner())
return;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
index f19a054..aba8318 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
@@ -126,6 +126,9 @@ public class GridCacheMvccCandidate implements Externalizable,
@GridToStringInclude
private transient volatile GridCacheVersion ownerVer;
+ /** */
+ private GridCacheVersion serOrder;
+
/**
* Empty constructor required by {@link Externalizable}.
*/
@@ -147,6 +150,7 @@ public class GridCacheMvccCandidate implements Externalizable,
* @param singleImplicit Single-key-implicit-transaction flag.
* @param nearLoc Near-local flag.
* @param dhtLoc DHT local flag.
+ * @param serOrder Version for serializable transactions ordering.
*/
public GridCacheMvccCandidate(
GridCacheEntryEx parent,
@@ -161,7 +165,9 @@ public class GridCacheMvccCandidate implements Externalizable,
boolean tx,
boolean singleImplicit,
boolean nearLoc,
- boolean dhtLoc) {
+ boolean dhtLoc,
+ @Nullable GridCacheVersion serOrder
+ ) {
assert nodeId != null;
assert ver != null;
assert parent != null;
@@ -173,6 +179,7 @@ public class GridCacheMvccCandidate implements Externalizable,
this.threadId = threadId;
this.ver = ver;
this.timeout = timeout;
+ this.serOrder = serOrder;
mask(LOCAL, loc);
mask(REENTRY, reentry);
@@ -244,7 +251,8 @@ public class GridCacheMvccCandidate implements Externalizable,
tx(),
singleImplicit(),
nearLocal(),
- dhtLocal());
+ dhtLocal(),
+ serializableOrder());
reentry.topVer = topVer;
@@ -452,6 +460,20 @@ public class GridCacheMvccCandidate implements Externalizable,
}
/**
+ * @return Serializable transaction flag.
+ */
+ public boolean serializable() {
+ return serOrder != null;
+ }
+
+ /**
+ * @return Version for serializable transactions ordering.
+ */
+ @Nullable public GridCacheVersion serializableOrder() {
+ return serOrder;
+ }
+
+ /**
* @return {@code True} if this candidate is a reentry.
*/
public boolean reentry() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 578ad6c..5bf4ac7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -139,7 +139,6 @@ import static org.apache.ignite.internal.IgniteComponentType.JTA;
import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CONSISTENCY_CHECK_SKIPPED;
import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_TX_CONFIG;
import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isNearEnabled;
-import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
/**
* Cache processor.
@@ -398,15 +397,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
throw new IgniteCheckedException("Cannot start cache in PRIVATE or ISOLATED deployment mode: " +
ctx.config().getDeploymentMode());
- if (!c.getTransactionConfiguration().isTxSerializableEnabled() &&
- c.getTransactionConfiguration().getDefaultTxIsolation() == SERIALIZABLE)
- U.warn(log,
- "Serializable transactions are disabled while default transaction isolation is SERIALIZABLE " +
- "(most likely misconfiguration - either update 'isTxSerializableEnabled' or " +
- "'defaultTxIsolationLevel' properties) for cache: " + U.maskName(cc.getName()),
- "Serializable transactions are disabled while default transaction isolation is SERIALIZABLE " +
- "for cache: " + U.maskName(cc.getName()));
-
if (cc.isWriteBehindEnabled()) {
if (cfgStore == null)
throw new IgniteCheckedException("Cannot enable write-behind (writer or store is not provided) " +
@@ -619,9 +609,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
sharedCtx = createSharedContext(ctx, CU.startStoreSessionListeners(ctx,
ctx.config().getCacheStoreSessionListenerFactories()));
- ctx.performance().add("Disable serializable transactions (set 'txSerializableEnabled' to false)",
- !ctx.config().getTransactionConfiguration().isTxSerializableEnabled());
-
for (int i = 0; i < cfgs.length; i++) {
if (ctx.config().isDaemon() && !CU.isMarshallerCache(cfgs[i].getName()))
continue;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
index d4f0d6c..a138d30 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
@@ -742,7 +743,10 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry {
}
/** {@inheritDoc} */
- @Override public boolean tmLock(IgniteInternalTx tx, long timeout)
+ @Override public boolean tmLock(IgniteInternalTx tx,
+ long timeout,
+ @Nullable GridCacheVersion serOrder,
+ GridCacheVersion serReadVer)
throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
if (tx.local())
// Null is returned if timeout is negative and there is other lock owner.
@@ -751,8 +755,8 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry {
tx.xidVersion(),
tx.topologyVersion(),
timeout,
- false,
- true,
+ /*reenter*/false,
+ /*tx*/true,
tx.implicitSingle()) != null;
try {
@@ -762,7 +766,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry {
tx.threadId(),
tx.xidVersion(),
tx.timeout(),
- true,
+ /*tx*/true,
tx.implicitSingle(),
tx.ownedVersion(txKey())
);
[14/23] ignite git commit: ignite-1607 Implemented deadlock-free
optimistic serializable tx mode
Posted by yz...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index 0834e88..fcbf58d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@ -574,19 +574,42 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
// Nullify explicit version so that innerSet/innerRemove will work as usual.
explicitVer = null;
+ GridCacheVersion dhtVer = cached.isNear() ? writeVersion() : null;
+
if (op == CREATE || op == UPDATE) {
// Invalidate only for near nodes (backups cannot be invalidated).
if (isSystemInvalidate() || (isInvalidate() && cacheCtx.isNear()))
- cached.innerRemove(this, eventNodeId(), nodeId, false, false, true, true,
- topVer, null, replicate ? DR_BACKUP : DR_NONE,
+ cached.innerRemove(this,
+ eventNodeId(),
+ nodeId,
+ false,
+ false,
+ true,
+ true,
+ topVer,
+ null,
+ replicate ? DR_BACKUP : DR_NONE,
near() ? null : explicitVer, CU.subjectId(this, cctx),
- resolveTaskName());
+ resolveTaskName(),
+ dhtVer);
else {
- cached.innerSet(this, eventNodeId(), nodeId, val, false, false,
- txEntry.ttl(), true, true, topVer, null,
- replicate ? DR_BACKUP : DR_NONE, txEntry.conflictExpireTime(),
- near() ? null : explicitVer, CU.subjectId(this, cctx),
- resolveTaskName());
+ cached.innerSet(this,
+ eventNodeId(),
+ nodeId,
+ val,
+ false,
+ false,
+ txEntry.ttl(),
+ true,
+ true,
+ topVer,
+ null,
+ replicate ? DR_BACKUP : DR_NONE,
+ txEntry.conflictExpireTime(),
+ near() ? null : explicitVer,
+ CU.subjectId(this, cctx),
+ resolveTaskName(),
+ dhtVer);
// Keep near entry up to date.
if (nearCached != null) {
@@ -602,9 +625,20 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
}
}
else if (op == DELETE) {
- cached.innerRemove(this, eventNodeId(), nodeId, false, false, true, true,
- topVer, null, replicate ? DR_BACKUP : DR_NONE,
- near() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName());
+ cached.innerRemove(this,
+ eventNodeId(),
+ nodeId,
+ false,
+ false,
+ true,
+ true,
+ topVer,
+ null,
+ replicate ? DR_BACKUP : DR_NONE,
+ near() ? null : explicitVer,
+ CU.subjectId(this, cctx),
+ resolveTaskName(),
+ dhtVer);
// Keep near entry up to date.
if (nearCached != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java
new file mode 100644
index 0000000..721ba4e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.dht;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheFuture;
+import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
+import org.apache.ignite.internal.processors.cache.KeyCacheObject;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_NEAR_GET_MAX_REMAPS;
+import static org.apache.ignite.IgniteSystemProperties.getInteger;
+
+/**
+ *
+ */
+public abstract class CacheDistributedGetFutureAdapter<K, V> extends GridCompoundIdentityFuture<Map<K, V>>
+ implements GridCacheFuture<Map<K, V>> {
+ /** Default max remap count value. */
+ public static final int DFLT_MAX_REMAP_CNT = 3;
+
+ /** Maximum number of attempts to remap key to the same primary node. */
+ protected static final int MAX_REMAP_CNT = getInteger(IGNITE_NEAR_GET_MAX_REMAPS, DFLT_MAX_REMAP_CNT);
+
+ /** Context. */
+ protected final GridCacheContext<K, V> cctx;
+
+ /** Keys. */
+ protected Collection<KeyCacheObject> keys;
+
+ /** Read through flag. */
+ protected boolean readThrough;
+
+ /** Force primary flag. */
+ protected boolean forcePrimary;
+
+ /** Future ID. */
+ protected IgniteUuid futId;
+
+ /** Trackable flag. */
+ protected boolean trackable;
+
+ /** Remap count. */
+ protected AtomicInteger remapCnt = new AtomicInteger();
+
+ /** Subject ID. */
+ protected UUID subjId;
+
+ /** Task name. */
+ protected String taskName;
+
+ /** Whether to deserialize portable objects. */
+ protected boolean deserializePortable;
+
+ /** Skip values flag. */
+ protected boolean skipVals;
+
+ /** Expiry policy. */
+ protected IgniteCacheExpiryPolicy expiryPlc;
+
+ /** Flag indicating that get should be done on a locked topology version. */
+ protected final boolean canRemap;
+
+ /** */
+ protected final boolean needVer;
+
+ /** */
+ protected final boolean keepCacheObjects;
+
+ /**
+ * @param cctx Context.
+ * @param keys Keys.
+ * @param readThrough Read through flag.
+ * @param forcePrimary If {@code true} then will force network trip to primary node even
+ * if called on backup node.
+ * @param subjId Subject ID.
+ * @param taskName Task name.
+ * @param deserializePortable Deserialize portable flag.
+ * @param expiryPlc Expiry policy.
+ * @param skipVals Skip values flag.
+ * @param canRemap Flag indicating whether future can be remapped on a newer topology version.
+ * @param needVer If {@code true} returns values as tuples containing value and version.
+ * @param keepCacheObjects Keep cache objects flag.
+ */
+ protected CacheDistributedGetFutureAdapter(
+ GridCacheContext<K, V> cctx,
+ Collection<KeyCacheObject> keys,
+ boolean readThrough,
+ boolean forcePrimary,
+ @Nullable UUID subjId,
+ String taskName,
+ boolean deserializePortable,
+ @Nullable IgniteCacheExpiryPolicy expiryPlc,
+ boolean skipVals,
+ boolean canRemap,
+ boolean needVer,
+ boolean keepCacheObjects
+ ) {
+ super(cctx.kernalContext(), CU.<K, V>mapsReducer(keys.size()));
+
+ assert !F.isEmpty(keys);
+
+ this.cctx = cctx;
+ this.keys = keys;
+ this.readThrough = readThrough;
+ this.forcePrimary = forcePrimary;
+ this.subjId = subjId;
+ this.taskName = taskName;
+ this.deserializePortable = deserializePortable;
+ this.expiryPlc = expiryPlc;
+ this.skipVals = skipVals;
+ this.canRemap = canRemap;
+ this.needVer = needVer;
+ this.keepCacheObjects = keepCacheObjects;
+
+ futId = IgniteUuid.randomUuid();
+ }
+
+ /**
+ * @param map Result map.
+ * @param key Key.
+ * @param val Value.
+ * @param ver Version.
+ */
+ @SuppressWarnings("unchecked")
+ protected final void versionedResult(Map map, KeyCacheObject key, Object val, GridCacheVersion ver) {
+ assert needVer;
+ assert skipVals || val != null;
+ assert ver != null;
+
+ map.put(key, new T2<>(skipVals ? true : val, ver));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
index 9d02705..bdd1140 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
@@ -69,6 +69,7 @@ import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.CI2;
import org.apache.ignite.internal.util.typedef.CI3;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -562,7 +563,7 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
/**
* This method is used internally. Use
- * {@link #getDhtAsync(UUID, long, LinkedHashMap, boolean, boolean, AffinityTopologyVersion, UUID, int, IgniteCacheExpiryPolicy, boolean)}
+ * {@link #getDhtAsync(UUID, long, LinkedHashMap, boolean, AffinityTopologyVersion, UUID, int, IgniteCacheExpiryPolicy, boolean)}
* method instead to retrieve DHT value.
*
* @param keys {@inheritDoc}
@@ -574,7 +575,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
@Nullable Collection<? extends K> keys,
boolean forcePrimary,
boolean skipTx,
- @Nullable GridCacheEntryEx entry,
@Nullable UUID subjId,
String taskName,
boolean deserializePortable,
@@ -585,7 +585,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
return getAllAsync(keys,
opCtx == null || !opCtx.skipStore(),
- null,
/*don't check local tx. */false,
subjId,
taskName,
@@ -603,9 +602,10 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
* @param taskName Task name.
* @param expiry Expiry policy.
* @param skipVals Skip values flag.
+ * @param canRemap Can remap flag.
* @return Get future.
*/
- IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> getDhtAllAsync(
+ IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> getDhtAllAsync(
Collection<KeyCacheObject> keys,
boolean readThrough,
@Nullable UUID subjId,
@@ -623,7 +623,8 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
expiry,
skipVals,
/*keep cache objects*/true,
- canRemap);
+ canRemap,
+ /*need version*/true);
}
/**
@@ -631,18 +632,17 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
* @param msgId Message ID.
* @param keys Keys to get.
* @param readThrough Read through flag.
- * @param reload Reload flag.
* @param topVer Topology version.
* @param subjId Subject ID.
* @param taskNameHash Task name hash code.
* @param expiry Expiry policy.
+ * @param skipVals Skip values flag.
* @return DHT future.
*/
public GridDhtFuture<Collection<GridCacheEntryInfo>> getDhtAsync(UUID reader,
long msgId,
LinkedHashMap<KeyCacheObject, Boolean> keys,
boolean readThrough,
- boolean reload,
AffinityTopologyVersion topVer,
@Nullable UUID subjId,
int taskNameHash,
@@ -653,7 +653,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
reader,
keys,
readThrough,
- reload,
/*tx*/null,
topVer,
subjId,
@@ -672,6 +671,7 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
*/
protected void processNearGetRequest(final UUID nodeId, final GridNearGetRequest req) {
assert ctx.affinityNode();
+ assert !req.reload() : req;
long ttl = req.accessTtl();
@@ -682,7 +682,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
req.messageId(),
req.keys(),
req.readThrough(),
- req.reload(),
req.topologyVersion(),
req.subjectId(),
req.taskNameHash(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
index be2f3d3..1b2d834 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
@@ -163,6 +163,8 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
* @param topVer Topology version.
* @param threadId Owning thread ID.
* @param ver Lock version.
+ * @param serOrder Version for serializable transactions ordering.
+ * @param serReadVer Optional read entry version for optimistic serializable transaction.
* @param timeout Timeout to acquire lock.
* @param reenter Reentry flag.
* @param tx Tx flag.
@@ -177,10 +179,17 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
AffinityTopologyVersion topVer,
long threadId,
GridCacheVersion ver,
+ @Nullable GridCacheVersion serOrder,
+ @Nullable GridCacheVersion serReadVer,
long timeout,
boolean reenter,
boolean tx,
- boolean implicitSingle) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
+ boolean implicitSingle)
+ throws GridCacheEntryRemovedException, GridDistributedLockCancelledException
+ {
+ assert serReadVer == null || serOrder != null;
+ assert !reenter || serOrder == null;
+
GridCacheMvccCandidate cand;
GridCacheMvccCandidate prev;
GridCacheMvccCandidate owner;
@@ -213,6 +222,7 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
threadId,
ver,
timeout,
+ serOrder,
reenter,
tx,
implicitSingle,
@@ -235,12 +245,12 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
val = this.val;
- if (mvcc != null && mvcc.isEmpty())
+ if (mvcc.isEmpty())
mvccExtras(null);
}
// Don't link reentries.
- if (cand != null && !cand.reentry())
+ if (!cand.reentry())
// Link with other candidates in the same thread.
cctx.mvcc().addNext(cctx, cand);
@@ -250,7 +260,10 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
}
/** {@inheritDoc} */
- @Override public boolean tmLock(IgniteInternalTx tx, long timeout)
+ @Override public boolean tmLock(IgniteInternalTx tx,
+ long timeout,
+ @Nullable GridCacheVersion serOrder,
+ GridCacheVersion serReadVer)
throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
if (tx.local()) {
GridDhtTxLocalAdapter dhtTx = (GridDhtTxLocalAdapter)tx;
@@ -262,6 +275,8 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
tx.topologyVersion(),
tx.threadId(),
tx.xidVersion(),
+ serOrder,
+ serReadVer,
timeout,
/*reenter*/false,
/*tx*/true,
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
index a67b1de..7108da6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
@@ -17,16 +17,16 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.LinkedList;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheObject;
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.lang.GridClosureException;
import org.apache.ignite.internal.util.typedef.C2;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiClosure;
@@ -72,9 +73,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
/** */
private UUID reader;
- /** Reload flag. */
- private boolean reload;
-
/** Read through flag. */
private boolean readThrough;
@@ -120,7 +118,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
* @param reader Reader.
* @param keys Keys.
* @param readThrough Read through flag.
- * @param reload Reload flag.
* @param tx Transaction.
* @param topVer Topology version.
* @param subjId Subject ID.
@@ -134,7 +131,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
UUID reader,
LinkedHashMap<KeyCacheObject, Boolean> keys,
boolean readThrough,
- boolean reload,
@Nullable IgniteTxLocalEx tx,
@NotNull AffinityTopologyVersion topVer,
@Nullable UUID subjId,
@@ -152,7 +148,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
this.msgId = msgId;
this.keys = keys;
this.readThrough = readThrough;
- this.reload = reload;
this.tx = tx;
this.topVer = topVer;
this.subjId = subjId;
@@ -291,8 +286,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
return new GridFinishedFuture<Collection<GridCacheEntryInfo>>(
Collections.<GridCacheEntryInfo>emptyList());
- final Collection<GridCacheEntryInfo> infos = new LinkedList<>();
-
String taskName0 = cctx.kernalContext().job().currentTaskName();
if (taskName0 == null)
@@ -302,89 +295,77 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
GridCompoundFuture<Boolean, Boolean> txFut = null;
- for (Map.Entry<KeyCacheObject, Boolean> k : keys.entrySet()) {
- while (true) {
- GridDhtCacheEntry e = cache().entryExx(k.getKey(), topVer);
+ ClusterNode readerNode = cctx.discovery().node(reader);
- try {
- GridCacheEntryInfo info = e.info();
+ if (readerNode != null && !readerNode.isLocal() && cctx.discovery().cacheNearNode(readerNode, cctx.name())) {
+ for (Map.Entry<KeyCacheObject, Boolean> k : keys.entrySet()) {
+ while (true) {
+ GridDhtCacheEntry e = cache().entryExx(k.getKey(), topVer);
- // If entry is obsolete.
- if (info == null)
- continue;
+ try {
+ if (e.obsolete())
+ continue;
- boolean addReader = (!e.deleted() && k.getValue() && !skipVals);
+ boolean addReader = (!e.deleted() && k.getValue() && !skipVals);
- if (addReader)
- e.unswap(false);
+ if (addReader)
+ e.unswap(false);
- // Register reader. If there are active transactions for this entry,
- // then will wait for their completion before proceeding.
- // TODO: GG-4003:
- // TODO: What if any transaction we wait for actually removes this entry?
- // TODO: In this case seems like we will be stuck with untracked near entry.
- // TODO: To fix, check that reader is contained in the list of readers once
- // TODO: again after the returned future completes - if not, try again.
- // TODO: Also, why is info read before transactions are complete, and not after?
- IgniteInternalFuture<Boolean> f = addReader ? e.addReader(reader, msgId, topVer) : null;
+ // Register reader. If there are active transactions for this entry,
+ // then will wait for their completion before proceeding.
+ // TODO: GG-4003:
+ // TODO: What if any transaction we wait for actually removes this entry?
+ // TODO: In this case seems like we will be stuck with untracked near entry.
+ // TODO: To fix, check that reader is contained in the list of readers once
+ // TODO: again after the returned future completes - if not, try again.
+ IgniteInternalFuture<Boolean> f = addReader ? e.addReader(reader, msgId, topVer) : null;
- if (f != null) {
- if (txFut == null)
- txFut = new GridCompoundFuture<>(CU.boolReducer());
-
- txFut.add(f);
- }
+ if (f != null) {
+ if (txFut == null)
+ txFut = new GridCompoundFuture<>(CU.boolReducer());
- infos.add(info);
+ txFut.add(f);
+ }
- break;
- }
- catch (IgniteCheckedException err) {
- return new GridFinishedFuture<>(err);
- }
- catch (GridCacheEntryRemovedException ignore) {
- if (log.isDebugEnabled())
- log.debug("Got removed entry when getting a DHT value: " + e);
- }
- finally {
- cctx.evicts().touch(e, topVer);
+ break;
+ }
+ catch (IgniteCheckedException err) {
+ return new GridFinishedFuture<>(err);
+ }
+ catch (GridCacheEntryRemovedException ignore) {
+ if (log.isDebugEnabled())
+ log.debug("Got removed entry when getting a DHT value: " + e);
+ }
+ finally {
+ cctx.evicts().touch(e, topVer);
+ }
}
}
- }
- if (txFut != null)
- txFut.markInitialized();
+ if (txFut != null)
+ txFut.markInitialized();
+ }
- IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> fut;
+ IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> fut;
if (txFut == null || txFut.isDone()) {
- if (reload && cctx.readThrough() && cctx.store().configured()) {
- fut = cache().reloadAllAsync0(keys.keySet(),
- true,
- skipVals,
+ if (tx == null) {
+ fut = cache().getDhtAllAsync(
+ keys.keySet(),
+ readThrough,
subjId,
- taskName);
+ taskName,
+ expiryPlc,
+ skipVals,
+ /*can remap*/true);
}
else {
- if (tx == null) {
- fut = cache().getDhtAllAsync(
- keys.keySet(),
- readThrough,
- subjId,
- taskName,
- expiryPlc,
- skipVals,
- /*can remap*/true);
- }
- else {
- fut = tx.getAllAsync(cctx,
- keys.keySet(),
- null,
- /*deserialize portable*/false,
- skipVals,
- /*keep cache objects*/true,
- /*skip store*/!readThrough);
- }
+ fut = tx.getAllAsync(cctx,
+ keys.keySet(),
+ /*deserialize portable*/false,
+ skipVals,
+ /*keep cache objects*/true,
+ /*skip store*/!readThrough);
}
}
else {
@@ -393,38 +374,28 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
// transactions to complete.
fut = new GridEmbeddedFuture<>(
txFut,
- new C2<Boolean, Exception, IgniteInternalFuture<Map<KeyCacheObject, CacheObject>>>() {
- @Override public IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> apply(Boolean b, Exception e) {
+ new C2<Boolean, Exception, IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>>>() {
+ @Override public IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> apply(Boolean b, Exception e) {
if (e != null)
throw new GridClosureException(e);
- if (reload && cctx.readThrough() && cctx.store().configured()) {
- return cache().reloadAllAsync0(keys.keySet(),
- true,
- skipVals,
+ if (tx == null) {
+ return cache().getDhtAllAsync(
+ keys.keySet(),
+ readThrough,
subjId,
- taskName);
+ taskName,
+ expiryPlc,
+ skipVals,
+ /*can remap*/true);
}
else {
- if (tx == null) {
- return cache().getDhtAllAsync(
- keys.keySet(),
- readThrough,
- subjId,
- taskName,
- expiryPlc,
- skipVals,
- /*can remap*/true);
- }
- else {
- return tx.getAllAsync(cctx,
- keys.keySet(),
- null,
- /*deserialize portable*/false,
- skipVals,
- /*keep cache objects*/true,
- /*skip store*/!readThrough);
- }
+ return tx.getAllAsync(cctx,
+ keys.keySet(),
+ /*deserialize portable*/false,
+ skipVals,
+ /*keep cache objects*/true,
+ /*skip store*/!readThrough);
}
}
}
@@ -432,23 +403,29 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
}
return new GridEmbeddedFuture<>(
- new C2<Map<KeyCacheObject, CacheObject>, Exception, Collection<GridCacheEntryInfo>>() {
- @Override public Collection<GridCacheEntryInfo> apply(Map<KeyCacheObject, CacheObject> map, Exception e) {
+ new C2<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>, Exception, Collection<GridCacheEntryInfo>>() {
+ @Override public Collection<GridCacheEntryInfo> apply(Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>> map, Exception e) {
if (e != null) {
onDone(e);
return Collections.emptyList();
}
else {
- for (Iterator<GridCacheEntryInfo> it = infos.iterator(); it.hasNext();) {
- GridCacheEntryInfo info = it.next();
+ Collection<GridCacheEntryInfo> infos = new ArrayList<>(map.size());
- Object v = map.get(info.key());
+ for (Map.Entry<KeyCacheObject, T2<CacheObject, GridCacheVersion>> entry : map.entrySet()) {
+ T2<CacheObject, GridCacheVersion> val = entry.getValue();
- if (v == null)
- it.remove();
- else
- info.value(skipVals ? null : (CacheObject)v);
+ assert val != null;
+
+ GridCacheEntryInfo info = new GridCacheEntryInfo();
+
+ info.cacheId(cctx.cacheId());
+ info.key(entry.getKey());
+ info.value(skipVals ? null : val.get1());
+ info.version(val.get2());
+
+ infos.add(info);
}
return infos;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
index 4f3e97d..c175b0b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
@@ -380,9 +380,10 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
* @return Lock candidate.
* @throws GridCacheEntryRemovedException If entry was removed.
* @throws GridDistributedLockCancelledException If lock is canceled.
+ * @throws IgniteCheckedException If failed.
*/
@Nullable public GridCacheMvccCandidate addEntry(GridDhtCacheEntry entry)
- throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
+ throws GridCacheEntryRemovedException, GridDistributedLockCancelledException, IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Adding entry: " + entry);
@@ -400,6 +401,8 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
topVer,
threadId,
lockVer,
+ null,
+ null,
timeout,
/*reenter*/false,
inTx(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
index c09a611..4ce4759 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
@@ -672,9 +672,9 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
if (log.isDebugEnabled())
log.debug("Got removed entry when adding lock (will retry): " + entry);
}
- catch (GridDistributedLockCancelledException e) {
+ catch (IgniteCheckedException | GridDistributedLockCancelledException e) {
if (log.isDebugEnabled())
- log.debug("Got lock request for cancelled lock (will fail): " + entry);
+ log.debug("Failed to add entry [err=" + e + ", entry=" + entry + ']');
return new GridDhtFinishedFuture<>(e);
}
@@ -1106,62 +1106,55 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
if (tx == null || !tx.isRollbackOnly()) {
GridCacheVersion dhtVer = req.dhtVersion(i);
- try {
- GridCacheVersion ver = e.version();
-
- boolean ret = req.returnValue(i) || dhtVer == null || !dhtVer.equals(ver);
-
- CacheObject val = null;
-
- if (ret)
- val = e.innerGet(tx,
- /*swap*/true,
- /*read-through*/false,
- /*fail-fast.*/false,
- /*unmarshal*/false,
- /*update-metrics*/true,
- /*event notification*/req.returnValue(i),
- /*temporary*/false,
- CU.subjectId(tx, ctx.shared()),
- null,
- tx != null ? tx.resolveTaskName() : null,
- null);
-
- assert e.lockedBy(mappedVer) ||
- (ctx.mvcc().isRemoved(e.context(), mappedVer) && req.timeout() > 0) :
- "Entry does not own lock for tx [locNodeId=" + ctx.localNodeId() +
- ", entry=" + e +
- ", mappedVer=" + mappedVer + ", ver=" + ver +
- ", tx=" + tx + ", req=" + req +
- ", err=" + err + ']';
-
- boolean filterPassed = false;
-
- if (tx != null && tx.onePhaseCommit()) {
- IgniteTxEntry writeEntry = tx.entry(ctx.txKey(e.key()));
-
- assert writeEntry != null :
- "Missing tx entry for locked cache entry: " + e;
-
- filterPassed = writeEntry.filtersPassed();
- }
-
- if (ret && val == null)
- val = e.valueBytes(null);
-
- // We include values into response since they are required for local
- // calls and won't be serialized. We are also including DHT version.
- res.addValueBytes(
- ret ? val : null,
- filterPassed,
- ver,
- mappedVer);
- }
- catch (GridCacheFilterFailedException ex) {
- assert false : "Filter should never fail if fail-fast is false.";
+ GridCacheVersion ver = e.version();
+
+ boolean ret = req.returnValue(i) || dhtVer == null || !dhtVer.equals(ver);
+
+ CacheObject val = null;
+
+ if (ret)
+ val = e.innerGet(tx,
+ /*swap*/true,
+ /*read-through*/false,
+ /*fail-fast.*/false,
+ /*unmarshal*/false,
+ /*update-metrics*/true,
+ /*event notification*/req.returnValue(i),
+ /*temporary*/false,
+ CU.subjectId(tx, ctx.shared()),
+ null,
+ tx != null ? tx.resolveTaskName() : null,
+ null);
+
+ assert e.lockedBy(mappedVer) ||
+ (ctx.mvcc().isRemoved(e.context(), mappedVer) && req.timeout() > 0) :
+ "Entry does not own lock for tx [locNodeId=" + ctx.localNodeId() +
+ ", entry=" + e +
+ ", mappedVer=" + mappedVer + ", ver=" + ver +
+ ", tx=" + tx + ", req=" + req +
+ ", err=" + err + ']';
+
+ boolean filterPassed = false;
- ex.printStackTrace();
+ if (tx != null && tx.onePhaseCommit()) {
+ IgniteTxEntry writeEntry = tx.entry(ctx.txKey(e.key()));
+
+ assert writeEntry != null :
+ "Missing tx entry for locked cache entry: " + e;
+
+ filterPassed = writeEntry.filtersPassed();
}
+
+ if (ret && val == null)
+ val = e.valueBytes(null);
+
+ // We include values into response since they are required for local
+ // calls and won't be serialized. We are also including DHT version.
+ res.addValueBytes(
+ ret ? val : null,
+ filterPassed,
+ ver,
+ mappedVer);
}
else {
// We include values into response since they are required for local
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
index 4f8469f..44f34aa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
@@ -595,7 +595,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
if (finish(false) || state() == UNKNOWN)
fut.finish();
else
- fut.onError(new IgniteCheckedException("Failed to commit transaction: " + CU.txString(this)));
+ fut.onError(new IgniteCheckedException("Failed to rollback transaction: " + CU.txString(this)));
}
catch (IgniteTxOptimisticCheckedException e) {
if (log.isDebugEnabled())
@@ -627,7 +627,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
if (finish(false) || state() == UNKNOWN)
fut.finish();
else
- fut.onError(new IgniteCheckedException("Failed to commit transaction: " +
+ fut.onError(new IgniteCheckedException("Failed to rollback transaction: " +
CU.txString(GridDhtTxLocal.this)));
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index a15a334..d806801 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -42,7 +42,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
import org.apache.ignite.internal.processors.cache.GridCacheOperation;
@@ -57,6 +56,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.dr.GridDrType;
+import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
import org.apache.ignite.internal.util.F0;
import org.apache.ignite.internal.util.GridConcurrentHashSet;
import org.apache.ignite.internal.util.GridLeanSet;
@@ -429,9 +429,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
catch (GridCacheEntryRemovedException e) {
assert false : "Got entry removed exception while holding transactional lock on entry: " + e;
}
- catch (GridCacheFilterFailedException e) {
- assert false : "Got filter failed exception with fail fast false " + e;
- }
}
}
@@ -472,8 +469,18 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
if (log.isDebugEnabled())
log.debug("Marking all local candidates as ready: " + this);
- Iterable<IgniteTxEntry> checkEntries = writes;
+ readyLocks(writes);
+
+ if (tx.serializable() && tx.optimistic())
+ readyLocks(reads);
+ locksReady = true;
+ }
+
+ /**
+ * @param checkEntries Entries.
+ */
+ private void readyLocks(Iterable<IgniteTxEntry> checkEntries) {
for (IgniteTxEntry txEntry : checkEntries) {
GridCacheContext cacheCtx = txEntry.context();
@@ -513,8 +520,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
}
}
}
-
- locksReady = true;
}
/**
@@ -813,12 +818,19 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
this.writes = writes;
this.txNodes = txNodes;
- if (!F.isEmpty(writes)) {
+ boolean ser = tx.serializable() && tx.optimistic();
+
+ if (!F.isEmpty(writes) || (ser && !F.isEmpty(reads))) {
Map<Integer, Collection<KeyCacheObject>> forceKeys = null;
for (IgniteTxEntry entry : writes)
forceKeys = checkNeedRebalanceKeys(entry, forceKeys);
+ if (ser) {
+ for (IgniteTxEntry entry : reads)
+ forceKeys = checkNeedRebalanceKeys(entry, forceKeys);
+ }
+
forceKeysFut = forceRebalanceKeys(forceKeys);
}
@@ -847,7 +859,10 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
IgniteTxEntry e,
Map<Integer, Collection<KeyCacheObject>> map
) {
- if (retVal || !F.isEmpty(e.entryProcessors()) || !F.isEmpty(e.filters())) {
+ if (retVal ||
+ !F.isEmpty(e.entryProcessors()) ||
+ !F.isEmpty(e.filters()) ||
+ e.serializableReadVersion() != null) {
if (map == null)
map = new HashMap<>();
@@ -906,10 +921,86 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
}
/**
+ * @param entries Entries.
+ * @return Not null exception if version check failed.
+ * @throws IgniteCheckedException If failed.
+ */
+ @Nullable private IgniteCheckedException checkReadConflict(Iterable<IgniteTxEntry> entries)
+ throws IgniteCheckedException {
+ try {
+ for (IgniteTxEntry entry : entries) {
+ GridCacheVersion serReadVer = entry.serializableReadVersion();
+
+ if (serReadVer != null) {
+ entry.cached().unswap();
+
+ if (!entry.cached().checkSerializableReadVersion(serReadVer))
+ return versionCheckError(entry);
+ }
+ }
+ }
+ catch (GridCacheEntryRemovedException e) {
+ assert false : "Got removed exception on entry with dht local candidate: " + entries;
+ }
+
+ return null;
+ }
+
+ /**
+ * @param entry Entry.
+ * @return Optimistic version check error.
+ */
+ private IgniteTxOptimisticCheckedException versionCheckError(IgniteTxEntry entry) {
+ GridCacheContext cctx = entry.context();
+
+ return new IgniteTxOptimisticCheckedException("Failed to prepare transaction, " +
+ "read/write conflict [key=" + entry.key().value(cctx.cacheObjectContext(), false) +
+ ", cache=" + cctx.name() + ']');
+ }
+
+ /**
*
*/
private void prepare0() {
try {
+ if (tx.serializable() && tx.optimistic()) {
+ IgniteCheckedException err0;
+
+ try {
+ err0 = checkReadConflict(writes);
+
+ if (err0 == null)
+ err0 = checkReadConflict(reads);
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed to check entry version: " + e, e);
+
+ err0 = e;
+ }
+
+ if (err0 != null) {
+ err.compareAndSet(null, err0);
+
+ final GridNearTxPrepareResponse res = createPrepareResponse();
+
+ tx.rollbackAsync().listen(new CI1<IgniteInternalFuture<IgniteInternalTx>>() {
+ @Override public void apply(IgniteInternalFuture<IgniteInternalTx> fut) {
+ if (GridDhtTxPrepareFuture.super.onDone(res, res.error())) {
+ try {
+ if (replied.compareAndSet(false, true))
+ sendPrepareResponse(res);
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed to send prepare response for transaction: " + tx, e);
+ }
+ }
+ }
+ });
+
+ return;
+ }
+ }
+
// We are holding transaction-level locks for entries here, so we can get next write version.
onEntriesLocked();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
index a68e834..febe9ba 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
@@ -24,11 +24,9 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
@@ -39,8 +37,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFuture;
import org.apache.ignite.internal.processors.cache.GridCacheMessage;
import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
@@ -49,7 +45,6 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetR
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.GridLeanMap;
-import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -58,6 +53,7 @@ import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.CIX1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -65,83 +61,30 @@ import org.apache.ignite.lang.IgniteClosure;
import org.apache.ignite.lang.IgniteUuid;
import org.jetbrains.annotations.Nullable;
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_NEAR_GET_MAX_REMAPS;
-
/**
* Colocated get future.
*/
-public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<Map<K, V>>
- implements GridCacheFuture<Map<K, V>> {
+public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAdapter<K, V> {
/** */
private static final long serialVersionUID = 0L;
- /** Default max remap count value. */
- public static final int DFLT_MAX_REMAP_CNT = 3;
-
/** Logger reference. */
private static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
/** Logger. */
private static IgniteLogger log;
- /** Maximum number of attempts to remap key to the same primary node. */
- private static final int MAX_REMAP_CNT = IgniteSystemProperties.getInteger(IGNITE_NEAR_GET_MAX_REMAPS,
- DFLT_MAX_REMAP_CNT);
-
- /** Context. */
- private final GridCacheContext<K, V> cctx;
-
- /** Keys. */
- private Collection<KeyCacheObject> keys;
-
/** Topology version. */
private AffinityTopologyVersion topVer;
- /** Reload flag. */
- private boolean reload;
-
- /** Read-through flag. */
- private boolean readThrough;
-
- /** Force primary flag. */
- private boolean forcePrimary;
-
- /** Future ID. */
- private IgniteUuid futId;
-
/** Version. */
private GridCacheVersion ver;
- /** Trackable flag. */
- private volatile boolean trackable;
-
- /** Remap count. */
- private AtomicInteger remapCnt = new AtomicInteger();
-
- /** Subject ID. */
- private UUID subjId;
-
- /** Task name. */
- private String taskName;
-
- /** Whether to deserialize portable objects. */
- private boolean deserializePortable;
-
- /** Expiry policy. */
- private IgniteCacheExpiryPolicy expiryPlc;
-
- /** Skip values flag. */
- private boolean skipVals;
-
- /** Flag indicating whether future can be remapped on a newer topology version. */
- private final boolean canRemap;
-
/**
* @param cctx Context.
* @param keys Keys.
* @param topVer Topology version.
* @param readThrough Read through flag.
- * @param reload Reload flag.
* @param forcePrimary If {@code true} then will force network trip to primary node even
* if called on backup node.
* @param subjId Subject ID.
@@ -149,39 +92,39 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
* @param deserializePortable Deserialize portable flag.
* @param expiryPlc Expiry policy.
* @param skipVals Skip values flag.
+ * @param canRemap Flag indicating whether future can be remapped on a newer topology version.
+ * @param needVer If {@code true} returns values as tuples containing value and version.
+ * @param keepCacheObjects Keep cache objects flag.
*/
public GridPartitionedGetFuture(
GridCacheContext<K, V> cctx,
Collection<KeyCacheObject> keys,
AffinityTopologyVersion topVer,
boolean readThrough,
- boolean reload,
boolean forcePrimary,
@Nullable UUID subjId,
String taskName,
boolean deserializePortable,
@Nullable IgniteCacheExpiryPolicy expiryPlc,
boolean skipVals,
- boolean canRemap
+ boolean canRemap,
+ boolean needVer,
+ boolean keepCacheObjects
) {
- super(cctx.kernalContext(), CU.<K, V>mapsReducer(keys.size()));
-
- assert !F.isEmpty(keys);
+ super(cctx,
+ keys,
+ readThrough,
+ forcePrimary,
+ subjId,
+ taskName,
+ deserializePortable,
+ expiryPlc,
+ skipVals,
+ canRemap,
+ needVer,
+ keepCacheObjects);
- this.cctx = cctx;
- this.keys = keys;
this.topVer = topVer;
- this.readThrough = readThrough;
- this.reload = reload;
- this.forcePrimary = forcePrimary;
- this.subjId = subjId;
- this.deserializePortable = deserializePortable;
- this.taskName = taskName;
- this.expiryPlc = expiryPlc;
- this.skipVals = skipVals;
- this.canRemap = canRemap;
-
- futId = IgniteUuid.randomUuid();
ver = cctx.versions().next();
@@ -351,7 +294,6 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
-1,
mappedKeys,
readThrough,
- reload,
topVer,
subjId,
taskName == null ? 0 : taskName.hashCode(),
@@ -404,7 +346,6 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
ver,
mappedKeys,
readThrough,
- reload,
topVer,
subjId,
taskName == null ? 0 : taskName.hashCode(),
@@ -452,10 +393,10 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
boolean allowLocRead = !forcePrimary || cctx.affinity().primary(cctx.localNode(), key, topVer);
while (true) {
- GridCacheEntryEx entry = null;
+ GridCacheEntryEx entry;
try {
- if (!reload && allowLocRead) {
+ if (allowLocRead) {
try {
entry = colocated.context().isSwapOrOffheapEnabled() ? colocated.entryEx(key) :
colocated.peekEx(key);
@@ -464,18 +405,40 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
if (entry != null) {
boolean isNew = entry.isNewLocked();
- CacheObject v = entry.innerGet(null,
- /*swap*/true,
- /*read-through*/false,
- /*fail-fast*/true,
- /*unmarshal*/true,
- /**update-metrics*/false,
- /*event*/!skipVals,
- /*temporary*/false,
- subjId,
- null,
- taskName,
- expiryPlc);
+ CacheObject v = null;
+ GridCacheVersion ver = null;
+
+ if (needVer) {
+ T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+ null,
+ /*swap*/true,
+ /*unmarshal*/true,
+ /**update-metrics*/false,
+ /*event*/!skipVals,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+
+ if (res != null) {
+ v = res.get1();
+ ver = res.get2();
+ }
+ }
+ else {
+ v = entry.innerGet(null,
+ /*swap*/true,
+ /*read-through*/false,
+ /*fail-fast*/true,
+ /*unmarshal*/true,
+ /**update-metrics*/false,
+ /*event*/!skipVals,
+ /*temporary*/false,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+ }
colocated.context().evicts().touch(entry, topVer);
@@ -485,7 +448,16 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
colocated.removeIfObsolete(key);
}
else {
- cctx.addResult(locVals, key, v, skipVals, false, deserializePortable, true);
+ if (needVer)
+ versionedResult(locVals, key, v, ver);
+ else
+ cctx.addResult(locVals,
+ key,
+ v,
+ skipVals,
+ keepCacheObjects,
+ deserializePortable,
+ true);
return false;
}
@@ -536,14 +508,6 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
catch (GridCacheEntryRemovedException ignored) {
// No-op, will retry.
}
- catch (GridCacheFilterFailedException e) {
- if (log.isDebugEnabled())
- log.debug("Filter validation failed for entry: " + e);
-
- colocated.context().evicts().touch(entry, topVer);
-
- break;
- }
}
return remote;
@@ -591,7 +555,16 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
for (GridCacheEntryInfo info : infos) {
assert skipVals == (info.value() == null);
- cctx.addResult(map, info.key(), info.value(), skipVals, false, deserializePortable, false);
+ if (needVer)
+ versionedResult(map, info.key(), info.value(), info.version());
+ else
+ cctx.addResult(map,
+ info.key(),
+ info.value(),
+ skipVals,
+ keepCacheObjects,
+ deserializePortable,
+ false);
}
return map;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index cba6872..4cd9e84 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@ -306,7 +306,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
@Nullable final Collection<? extends K> keys,
final boolean forcePrimary,
boolean skipTx,
- @Nullable final GridCacheEntryEx entry,
@Nullable UUID subjId,
final String taskName,
final boolean deserializePortable,
@@ -334,7 +333,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
return asyncOp(new CO<IgniteInternalFuture<Map<K, V>>>() {
@Override public IgniteInternalFuture<Map<K, V>> apply() {
return getAllAsync0(ctx.cacheKeysView(keys),
- false,
forcePrimary,
subjId0,
taskName,
@@ -920,7 +918,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
* Entry point to all public API get methods.
*
* @param keys Keys to remove.
- * @param reload Reload flag.
* @param forcePrimary Force primary flag.
* @param subjId Subject ID.
* @param taskName Task name.
@@ -931,7 +928,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
* @return Get future.
*/
private IgniteInternalFuture<Map<K, V>> getAllAsync0(@Nullable Collection<KeyCacheObject> keys,
- boolean reload,
boolean forcePrimary,
UUID subjId,
String taskName,
@@ -947,7 +943,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
final IgniteCacheExpiryPolicy expiry = skipVals ? null : expiryPolicy(expiryPlc);
// Optimisation: try to resolve value locally and escape 'get future' creation.
- if (!reload && !forcePrimary) {
+ if (!forcePrimary) {
Map<K, V> locVals = U.newHashMap(keys.size());
boolean success = true;
@@ -997,10 +993,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
catch (GridCacheEntryRemovedException ignored) {
// No-op, retry.
}
- catch (GridCacheFilterFailedException ignored) {
- // No-op, skip the key.
- break;
- }
catch (GridDhtInvalidPartitionException ignored) {
success = false;
@@ -1036,14 +1028,15 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
keys,
topVer,
!skipStore,
- reload,
forcePrimary,
subjId,
taskName,
deserializePortable,
expiry,
skipVals,
- canRemap);
+ canRemap,
+ false,
+ false);
fut.init();
@@ -1663,6 +1656,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
if (idx != null) {
GridDhtCacheEntry entry = entries.get(idx);
+
try {
GridCacheVersion ver = entry.version();
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
index 6d69198..f03b461 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
@@ -36,7 +36,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheConcurrentMap;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException;
import org.apache.ignite.internal.processors.cache.GridCacheMapEntry;
import org.apache.ignite.internal.processors.cache.GridCacheMapEntryFactory;
@@ -68,6 +67,7 @@ import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.typedef.C2;
import org.apache.ignite.internal.util.typedef.CI2;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -188,7 +188,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
@Nullable final Collection<? extends K> keys,
boolean forcePrimary,
boolean skipTx,
- @Nullable final GridCacheEntryEx entry,
@Nullable UUID subjId,
String taskName,
final boolean deserializePortable,
@@ -212,7 +211,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
@Override public IgniteInternalFuture<Map<K, V>> op(IgniteTxLocalAdapter tx) {
return tx.getAllAsync(ctx,
ctx.cacheKeysView(keys),
- entry,
deserializePortable,
skipVals,
false,
@@ -230,7 +228,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
return loadAsync(
ctx.cacheKeysView(keys),
opCtx == null || !opCtx.skipStore(),
- false,
forcePrimary,
topVer,
subjId,
@@ -257,7 +254,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
/**
* @param keys Keys to load.
* @param readThrough Read through flag.
- * @param reload Reload flag.
* @param forcePrimary Force get from primary node flag.
* @param topVer Topology version.
* @param subjId Subject ID.
@@ -265,12 +261,12 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
* @param deserializePortable Deserialize portable flag.
* @param expiryPlc Expiry policy.
* @param skipVals Skip values flag.
+ * @param canRemap Can remap flag.
* @return Loaded values.
*/
public IgniteInternalFuture<Map<K, V>> loadAsync(
@Nullable Collection<KeyCacheObject> keys,
boolean readThrough,
- boolean reload,
boolean forcePrimary,
AffinityTopologyVersion topVer,
@Nullable UUID subjId,
@@ -278,7 +274,45 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
boolean deserializePortable,
@Nullable IgniteCacheExpiryPolicy expiryPlc,
boolean skipVals,
- boolean canRemap
+ boolean canRemap) {
+ return loadAsync(keys,
+ readThrough,
+ forcePrimary,
+ topVer, subjId,
+ taskName,
+ deserializePortable,
+ expiryPlc,
+ skipVals,
+ canRemap,
+ false,
+ false);
+ }
+
+ /**
+ * @param keys Keys to load.
+ * @param readThrough Read through flag.
+ * @param forcePrimary Force get from primary node flag.
+ * @param topVer Topology version.
+ * @param subjId Subject ID.
+ * @param taskName Task name.
+ * @param deserializePortable Deserialize portable flag.
+ * @param expiryPlc Expiry policy.
+ * @param skipVals Skip values flag.
+ * @return Loaded values.
+ */
+ public IgniteInternalFuture<Map<K, V>> loadAsync(
+ @Nullable Collection<KeyCacheObject> keys,
+ boolean readThrough,
+ boolean forcePrimary,
+ AffinityTopologyVersion topVer,
+ @Nullable UUID subjId,
+ String taskName,
+ boolean deserializePortable,
+ @Nullable IgniteCacheExpiryPolicy expiryPlc,
+ boolean skipVals,
+ boolean canRemap,
+ boolean needVer,
+ boolean keepCacheObj
) {
if (keys == null || keys.isEmpty())
return new GridFinishedFuture<>(Collections.<K, V>emptyMap());
@@ -287,8 +321,8 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
expiryPlc = expiryPolicy(null);
// Optimisation: try to resolve value locally and escape 'get future' creation.
- if (!reload && !forcePrimary) {
- Map<K, V> locVals = U.newHashMap(keys.size());
+ if (!forcePrimary) {
+ Map<K, V> locVals = null;
boolean success = true;
@@ -304,18 +338,40 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
if (entry != null) {
boolean isNew = entry.isNewLocked();
- CacheObject v = entry.innerGet(null,
- /*swap*/true,
- /*read-through*/false,
- /*fail-fast*/true,
- /*unmarshal*/true,
- /**update-metrics*/false,
- /*event*/!skipVals,
- /*temporary*/false,
- subjId,
- null,
- taskName,
- expiryPlc);
+ CacheObject v = null;
+ GridCacheVersion ver = null;
+
+ if (needVer) {
+ T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+ null,
+ /*swap*/true,
+ /*unmarshal*/true,
+ /**update-metrics*/false,
+ /*event*/!skipVals,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+
+ if (res != null) {
+ v = res.get1();
+ ver = res.get2();
+ }
+ }
+ else {
+ v = entry.innerGet(null,
+ /*swap*/true,
+ /*read-through*/false,
+ /*fail-fast*/true,
+ /*unmarshal*/true,
+ /**update-metrics*/false,
+ /*event*/!skipVals,
+ /*temporary*/false,
+ subjId,
+ null,
+ taskName,
+ expiryPlc);
+ }
// Entry was not in memory or in swap, so we remove it from cache.
if (v == null) {
@@ -326,8 +382,22 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
success = false;
}
- else
- ctx.addResult(locVals, key, v, skipVals, false, deserializePortable, true);
+ else {
+ if (locVals == null)
+ locVals = U.newHashMap(keys.size());
+
+ if (needVer)
+ locVals.put((K)key, (V)new T2<>((Object)(skipVals ? true : v), ver));
+ else {
+ ctx.addResult(locVals,
+ key,
+ v,
+ skipVals,
+ keepCacheObj,
+ deserializePortable,
+ true);
+ }
+ }
}
else
success = false;
@@ -337,10 +407,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
catch (GridCacheEntryRemovedException ignored) {
// No-op, retry.
}
- catch (GridCacheFilterFailedException ignored) {
- // No-op, skip the key.
- break;
- }
catch (GridDhtInvalidPartitionException ignored) {
success = false;
@@ -377,14 +443,15 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
keys,
topVer,
readThrough,
- reload,
forcePrimary,
subjId,
taskName,
deserializePortable,
expiryPlc,
skipVals,
- canRemap);
+ canRemap,
+ needVer,
+ keepCacheObj);
fut.init();
@@ -803,10 +870,9 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
if (log.isDebugEnabled())
log.debug("Got removed entry when adding lock (will retry): " + entry);
}
- catch (GridDistributedLockCancelledException e) {
+ catch (IgniteCheckedException | GridDistributedLockCancelledException e) {
if (log.isDebugEnabled())
- log.debug("Got lock request for cancelled lock (will ignore): " +
- entry);
+ log.debug("Failed to add entry [err=" + e + ", entry=" + entry + ']');
fut.onError(e);
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
index 53c2b63..365b46b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
@@ -323,7 +323,8 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
inTx(),
inTx() && tx.implicitSingle(),
false,
- false);
+ false,
+ null);
cand.topologyVersion(topVer.get());
}
@@ -342,7 +343,8 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
inTx(),
inTx() && tx.implicitSingle(),
false,
- false);
+ false,
+ null);
cand.topologyVersion(topVer.get());
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
index 82054d9..1bf03a9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
@@ -385,7 +385,6 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> {
@Nullable Collection<? extends K> keys,
boolean forcePrimary,
boolean skipTx,
- @Nullable GridCacheEntryEx entry,
@Nullable UUID subjId,
String taskName,
boolean deserializePortable,
@@ -406,7 +405,6 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> {
return loadAsync(null,
ctx.cacheKeysView(keys),
- false,
forcePrimary,
subjId,
taskName,