You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/11/20 06:49:11 UTC
[01/23] ignite git commit: ignite-1.5 Changed update version url.
Repository: ignite
Updated Branches:
refs/heads/ignite-sql-opt 930166c07 -> d46109fc4
ignite-1.5 Changed update version url.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/33ec73f9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/33ec73f9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/33ec73f9
Branch: refs/heads/ignite-sql-opt
Commit: 33ec73f901ca5dba441c6ca4e118d55165f3d25e
Parents: c490de3
Author: Andrey <an...@gridgain.com>
Authored: Thu Nov 19 15:43:51 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Thu Nov 19 15:43:51 2015 +0700
----------------------------------------------------------------------
.../main/java/org/apache/ignite/internal/GridUpdateNotifier.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/33ec73f9/modules/core/src/main/java/org/apache/ignite/internal/GridUpdateNotifier.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridUpdateNotifier.java b/modules/core/src/main/java/org/apache/ignite/internal/GridUpdateNotifier.java
index b6162ed..5d2cf35 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridUpdateNotifier.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridUpdateNotifier.java
@@ -141,7 +141,7 @@ class GridUpdateNotifier {
this.ver = ver;
- url = "http://tiny.cc/updater/update_status_ignite.php";
+ url = "http://ignite.run/update_status_ignite.php";
this.gridName = gridName == null ? "null" : gridName;
this.gw = gw;
[07/23] ignite git commit: Optimization for single key cache 'get'
operation.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java
new file mode 100644
index 0000000..ba0081c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetResponse.java
@@ -0,0 +1,321 @@
+/*
+ * 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.nio.ByteBuffer;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.GridDirectTransient;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheObject;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
+import org.apache.ignite.internal.processors.cache.GridCacheMessage;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class GridNearSingleGetResponse extends GridCacheMessage implements GridCacheDeployable {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ public static final int INVALID_PART_FLAG_MASK = 0x1;
+
+ /** */
+ public static final int CONTAINS_VAL_FLAG_MASK = 0x2;
+
+ /** Future ID. */
+ private IgniteUuid futId;
+
+ /** */
+ private Message res;
+
+ /** */
+ private AffinityTopologyVersion topVer;
+
+ /** Error. */
+ @GridDirectTransient
+ private IgniteCheckedException err;
+
+ /** Serialized error. */
+ private byte[] errBytes;
+
+ /** */
+ private byte flags;
+
+ /**
+ * Empty constructor required for {@link Message}.
+ */
+ public GridNearSingleGetResponse() {
+ // No-op.
+ }
+
+ /**
+ * @param cacheId Cache ID.
+ * @param futId Future ID.
+ * @param topVer Topology version.
+ * @param res Result.
+ * @param invalidPartitions {@code True} if invalid partitions error occurred.
+ * @param addDepInfo Deployment info.
+ */
+ public GridNearSingleGetResponse(
+ int cacheId,
+ IgniteUuid futId,
+ AffinityTopologyVersion topVer,
+ @Nullable Message res,
+ boolean invalidPartitions,
+ boolean addDepInfo
+ ) {
+ assert futId != null;
+
+ this.cacheId = cacheId;
+ this.futId = futId;
+ this.topVer = topVer;
+ this.res = res;
+ this.addDepInfo = addDepInfo;
+
+ if (invalidPartitions)
+ flags = (byte)(flags | INVALID_PART_FLAG_MASK);
+ }
+
+ /**
+ * @param err Error.
+ */
+ public void error(IgniteCheckedException err) {
+ this.err = err;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteCheckedException error() {
+ return err;
+ }
+
+ /**
+ * @return Topology version.
+ */
+ @Override public AffinityTopologyVersion topologyVersion() {
+ return topVer;
+ }
+
+ /**
+ * @return {@code True} if invalid partitions error occurred.
+ */
+ public boolean invalidPartitions() {
+ return (flags & INVALID_PART_FLAG_MASK) != 0;
+ }
+
+ /**
+ * @return Results for request with set flag {@link GridNearSingleGetRequest#skipValues()}.
+ */
+ public boolean containsValue() {
+ return (flags & CONTAINS_VAL_FLAG_MASK) != 0;
+ }
+
+ /**
+ *
+ */
+ public void setContainsValue() {
+ flags = (byte)(flags | CONTAINS_VAL_FLAG_MASK);
+ }
+
+ /**
+ * @return Result.
+ */
+ public Message result() {
+ return res;
+ }
+
+ /**
+ * @return Future ID.
+ */
+ public IgniteUuid futureId() {
+ return futId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
+ super.prepareMarshal(ctx);
+
+ if (res != null) {
+ GridCacheContext cctx = ctx.cacheContext(cacheId);
+
+ if (res instanceof CacheObject)
+ prepareMarshalCacheObject((CacheObject) res, cctx);
+ else if (res instanceof CacheVersionedValue)
+ ((CacheVersionedValue)res).prepareMarshal(cctx.cacheObjectContext());
+ else if (res instanceof GridCacheEntryInfo)
+ ((GridCacheEntryInfo)res).marshal(cctx);
+ }
+
+ if (err != null)
+ errBytes = ctx.marshaller().marshal(err);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException {
+ super.finishUnmarshal(ctx, ldr);
+
+ if (res != null) {
+ GridCacheContext cctx = ctx.cacheContext(cacheId());
+
+ if (res instanceof CacheObject)
+ ((CacheObject)res).finishUnmarshal(cctx.cacheObjectContext(), ldr);
+ else if (res instanceof CacheVersionedValue)
+ ((CacheVersionedValue)res).finishUnmarshal(cctx, ldr);
+ else if (res instanceof GridCacheEntryInfo)
+ ((GridCacheEntryInfo)res).unmarshal(cctx, ldr);
+ }
+
+ if (errBytes != null && err == null)
+ err = ctx.marshaller().unmarshal(errBytes, ldr);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
+ writer.setBuffer(buf);
+
+ if (!super.writeTo(buf, writer))
+ return false;
+
+ if (!writer.isHeaderWritten()) {
+ if (!writer.writeHeader(directType(), fieldsCount()))
+ return false;
+
+ writer.onHeaderWritten();
+ }
+
+ switch (writer.state()) {
+ case 3:
+ if (!writer.writeByteArray("errBytes", errBytes))
+ return false;
+
+ writer.incrementState();
+
+ case 4:
+ if (!writer.writeByte("flags", flags))
+ return false;
+
+ writer.incrementState();
+
+ case 5:
+ if (!writer.writeIgniteUuid("futId", futId))
+ return false;
+
+ writer.incrementState();
+
+ case 6:
+ if (!writer.writeMessage("res", res))
+ return false;
+
+ writer.incrementState();
+
+ case 7:
+ if (!writer.writeMessage("topVer", topVer))
+ return false;
+
+ writer.incrementState();
+
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
+ reader.setBuffer(buf);
+
+ if (!reader.beforeMessageRead())
+ return false;
+
+ if (!super.readFrom(buf, reader))
+ return false;
+
+ switch (reader.state()) {
+ case 3:
+ errBytes = reader.readByteArray("errBytes");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 4:
+ flags = reader.readByte("flags");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 5:
+ futId = reader.readIgniteUuid("futId");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 6:
+ res = reader.readMessage("res");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 7:
+ topVer = reader.readMessage("topVer");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ }
+
+ return reader.afterMessageRead(GridNearSingleGetResponse.class);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean addDeploymentInfo() {
+ return addDepInfo;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte directType() {
+ return 117;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte fieldsCount() {
+ return 8;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridNearSingleGetResponse.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 1a26028..fd3d056 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
@@ -423,7 +423,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
assert nodeId != null;
assert res != null;
- GridNearLockFuture fut = (GridNearLockFuture)ctx.mvcc().<Boolean>future(res.version(),
+ GridNearLockFuture fut = (GridNearLockFuture)ctx.mvcc().<Boolean>mvccFuture(res.version(),
res.futureId());
if (fut != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 9c022b2..102cc4b 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
@@ -79,7 +79,7 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
private GridCacheSharedContext<K, V> cctx;
/** Future ID. */
- private IgniteUuid futId;
+ private final IgniteUuid futId;
/** Transaction. */
@GridToStringInclude
@@ -125,26 +125,6 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
}
/** {@inheritDoc} */
- @Override public GridCacheVersion version() {
- return tx.xidVersion();
- }
-
- /**
- * @return Involved nodes.
- */
- @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) {
for (IgniteInternalFuture<?> fut : futures())
if (isMini(fut)) {
@@ -298,7 +278,7 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
}
// Don't forget to clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeFuture(futId);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 b92be31..1c01e4e 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
@@ -332,7 +332,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
boolean readThrough,
boolean async,
final Collection<KeyCacheObject> keys,
- boolean skipVals,
+ final boolean skipVals,
final boolean needVer,
final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c
) {
@@ -361,35 +361,70 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
});
}
else if (cacheCtx.isColocated()) {
- return cacheCtx.colocated().loadAsync(
- keys,
- readThrough,
- /*force primary*/needVer,
- topologyVersion(),
- CU.subjectId(this, cctx),
- resolveTaskName(),
- /*deserializePortable*/false,
- accessPolicy(cacheCtx, keys),
- skipVals,
- /*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;
+ if (keys.size() == 1) {
+ final KeyCacheObject key = F.first(keys);
+
+ return cacheCtx.colocated().loadAsync(
+ key,
+ readThrough,
+ /*force primary*/needVer,
+ topologyVersion(),
+ CU.subjectId(this, cctx),
+ resolveTaskName(),
+ /*deserializePortable*/false,
+ accessPolicy(cacheCtx, keys),
+ skipVals,
+ /*can remap*/true,
+ needVer,
+ /*keepCacheObject*/true
+ ).chain(new C1<IgniteInternalFuture<Object>, Void>() {
+ @Override public Void apply(IgniteInternalFuture<Object> f) {
+ try {
+ Object val = f.get();
+
+ processLoaded(key, val, needVer, skipVals, c);
+
+ return null;
+ }
+ catch (Exception e) {
+ setRollbackOnly();
+
+ throw new GridClosureException(e);
+ }
}
- catch (Exception e) {
- setRollbackOnly();
-
- throw new GridClosureException(e);
+ });
+ }
+ else {
+ return cacheCtx.colocated().loadAsync(
+ keys,
+ readThrough,
+ /*force primary*/needVer,
+ topologyVersion(),
+ CU.subjectId(this, cctx),
+ resolveTaskName(),
+ /*deserializePortable*/false,
+ accessPolicy(cacheCtx, keys),
+ skipVals,
+ /*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();
@@ -409,29 +444,45 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
final Collection<KeyCacheObject> keys,
boolean needVer,
GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
- for (KeyCacheObject key : keys) {
- Object val = map.get(key);
+ for (KeyCacheObject key : keys)
+ processLoaded(key, map.get(key), needVer, false, c);
+ }
- if (val != null) {
- Object v;
- GridCacheVersion ver;
+ /**
+ * @param key Key.
+ * @param val Value.
+ * @param needVer If {@code true} version is required for loaded values.
+ * @param skipVals Skip values flag.
+ * @param c Closure.
+ */
+ private void processLoaded(
+ KeyCacheObject key,
+ @Nullable Object val,
+ boolean needVer,
+ boolean skipVals,
+ GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
+ if (val != null) {
+ Object v;
+ GridCacheVersion ver;
- if (needVer) {
- T2<Object, GridCacheVersion> t = (T2)val;
+ if (needVer) {
+ T2<Object, GridCacheVersion> t = (T2)val;
- v = t.get1();
- ver = t.get2();
- }
- else {
- v = val;
- ver = null;
- }
-
- c.apply(key, v, ver);
+ v = t.get1();
+ ver = t.get2();
}
- else
+ else {
+ v = val;
+ ver = null;
+ }
+
+ if (skipVals && v == Boolean.FALSE)
c.apply(key, null, IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER);
+ else
+ c.apply(key, v, ver);
}
+ else
+ c.apply(key, null, IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER);
}
/** {@inheritDoc} */
@@ -771,7 +822,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
if (fut == null && !commitFut.compareAndSet(null, fut = new GridNearTxFinishFuture<>(cctx, this, true)))
return commitFut.get();
- cctx.mvcc().addFuture(fut);
+ cctx.mvcc().addFuture(fut, fut.futureId());
final IgniteInternalFuture<?> prepareFut = prepFut.get();
@@ -816,7 +867,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
if (!rollbackFut.compareAndSet(null, fut = new GridNearTxFinishFuture<>(cctx, this, false)))
return rollbackFut.get();
- cctx.mvcc().addFuture(fut);
+ cctx.mvcc().addFuture(fut, fut.futureId());
IgniteInternalFuture<?> prepFut = this.prepFut.get();
@@ -957,7 +1008,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
final GridDhtTxFinishFuture fut = new GridDhtTxFinishFuture<>(cctx, this, /*commit*/true);
- cctx.mvcc().addFuture(fut);
+ cctx.mvcc().addFuture(fut, fut.futureId());
if (prep == null || prep.isDone()) {
assert prep != null || optimistic();
@@ -1016,7 +1067,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
final GridDhtTxFinishFuture fut = new GridDhtTxFinishFuture<>(cctx, this, /*commit*/false);
- cctx.mvcc().addFuture(fut);
+ cctx.mvcc().addFuture(fut, fut.futureId());
IgniteInternalFuture<?> prep = prepFut.get();
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 cfaadc9..52cad91 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
@@ -25,7 +25,7 @@ import javax.cache.expiry.ExpiryPolicy;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFuture;
+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;
@@ -48,8 +48,8 @@ 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 GridCompoundFuture<GridNearTxPrepareResponse, IgniteInternalTx>
- implements GridCacheFuture<IgniteInternalTx> {
+public abstract class GridNearTxPrepareFutureAdapter extends
+ GridCompoundFuture<GridNearTxPrepareResponse, IgniteInternalTx> implements GridCacheMvccFuture<IgniteInternalTx> {
/** Logger reference. */
protected static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCache.java
index 87da9a1..544d5b4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCache.java
@@ -231,8 +231,8 @@ public class GridLocalCache<K, V> extends GridCacheAdapter<K, V> {
/**
* @param fut Clears future from cache.
*/
- void onFutureDone(GridCacheFuture<?> fut) {
- if (ctx.mvcc().removeFuture(fut)) {
+ void onFutureDone(GridLocalLockFuture fut) {
+ if (ctx.mvcc().removeMvccFuture(fut)) {
if (log().isDebugEnabled())
log().debug("Explicitly removed future from map of futures: " + fut);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 cb14b4c..d392d53 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
@@ -154,11 +154,6 @@ public final class GridLocalLockFuture<K, V> extends GridFutureAdapter<Boolean>
}
/** {@inheritDoc} */
- @Override public Collection<? extends ClusterNode> nodes() {
- return Collections.emptyList();
- }
-
- /** {@inheritDoc} */
@Override public boolean onNodeLeft(UUID nodeId) {
return false;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 0e5657b..a9846ef 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
@@ -477,7 +477,7 @@ public class IgniteTxHandler {
*/
private void processNearTxPrepareResponse(UUID nodeId, GridNearTxPrepareResponse res) {
GridNearTxPrepareFutureAdapter fut = (GridNearTxPrepareFutureAdapter)ctx.mvcc()
- .<IgniteInternalTx>future(res.version(), res.futureId());
+ .<IgniteInternalTx>mvccFuture(res.version(), res.futureId());
if (fut == null) {
U.warn(log, "Failed to find future for prepare response [sender=" + nodeId + ", res=" + res + ']');
@@ -495,8 +495,7 @@ public class IgniteTxHandler {
private void processNearTxFinishResponse(UUID nodeId, GridNearTxFinishResponse res) {
ctx.tm().onFinishedRemote(nodeId, res.threadId());
- GridNearTxFinishFuture fut = (GridNearTxFinishFuture)ctx.mvcc().<IgniteInternalTx>future(
- res.xid(), res.futureId());
+ GridNearTxFinishFuture fut = (GridNearTxFinishFuture)ctx.mvcc().<IgniteInternalTx>future(res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
@@ -513,7 +512,7 @@ public class IgniteTxHandler {
* @param res Response.
*/
private void processDhtTxPrepareResponse(UUID nodeId, GridDhtTxPrepareResponse res) {
- GridDhtTxPrepareFuture fut = (GridDhtTxPrepareFuture)ctx.mvcc().future(res.version(), res.futureId());
+ GridDhtTxPrepareFuture fut = (GridDhtTxPrepareFuture)ctx.mvcc().mvccFuture(res.version(), res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
@@ -534,8 +533,7 @@ public class IgniteTxHandler {
assert res != null;
if (res.checkCommitted()) {
- GridNearTxFinishFuture fut = (GridNearTxFinishFuture)ctx.mvcc().<IgniteInternalTx>future(
- res.xid(), res.futureId());
+ GridNearTxFinishFuture fut = (GridNearTxFinishFuture)ctx.mvcc().<IgniteInternalTx>future(res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
@@ -547,8 +545,7 @@ public class IgniteTxHandler {
fut.onResult(nodeId, res);
}
else {
- GridDhtTxFinishFuture fut = (GridDhtTxFinishFuture)ctx.mvcc().<IgniteInternalTx>future(
- res.xid(), res.futureId());
+ GridDhtTxFinishFuture fut = (GridDhtTxFinishFuture)ctx.mvcc().<IgniteInternalTx>future(res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
@@ -566,7 +563,8 @@ public class IgniteTxHandler {
* @param req Request.
* @return Future.
*/
- @Nullable public IgniteInternalFuture<IgniteInternalTx> processNearTxFinishRequest(UUID nodeId, GridNearTxFinishRequest req) {
+ @Nullable public IgniteInternalFuture<IgniteInternalTx> processNearTxFinishRequest(UUID nodeId,
+ GridNearTxFinishRequest req) {
return finish(nodeId, null, req);
}
@@ -1359,8 +1357,7 @@ public class IgniteTxHandler {
if (log.isDebugEnabled())
log.debug("Processing check prepared transaction response [nodeId=" + nodeId + ", res=" + res + ']');
- GridCacheTxRecoveryFuture fut = (GridCacheTxRecoveryFuture)ctx.mvcc().
- <Boolean>future(res.version(), res.futureId());
+ GridCacheTxRecoveryFuture fut = (GridCacheTxRecoveryFuture)ctx.mvcc().future(res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 9e44b10..ecb0595 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
@@ -1372,7 +1372,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (txEntry != null) {
CacheObject val = txEntry.value();
- // Read value from locked entry in group-lock transaction as well.
if (txEntry.hasValue()) {
if (!F.isEmpty(txEntry.entryProcessors()))
val = txEntry.applyEntryProcessors(val);
@@ -2224,6 +2223,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/**
* @param cacheCtx Cache context.
* @param keys Keys to load.
+ * @param filter Filter.
* @param ret Return value.
* @param needReadVer Read version flag.
* @param singleRmv {@code True} for single remove operation.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 67bca51..247ccaf 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
@@ -1764,7 +1764,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
tx.originatingNodeId(),
tx.transactionNodes());
- cctx.mvcc().addFuture(fut);
+ cctx.mvcc().addFuture(fut, fut.futureId());
if (log.isDebugEnabled())
log.debug("Checking optimistic transaction state on remote nodes [tx=" + tx + ", fut=" + fut + ']');
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
index 6131f54..6cf10f4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
@@ -53,6 +53,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNe
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsFullMessage;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse;
import org.apache.ignite.internal.util.typedef.CI1;
@@ -765,6 +766,12 @@ public class IgniteClientReconnectCacheTest extends IgniteClientReconnectAbstrac
}
};
+ IgniteInClosure<IgniteCache<Object, Object>> getAllOp = new CI1<IgniteCache<Object, Object>>() {
+ @Override public void apply(IgniteCache<Object, Object> cache) {
+ cache.getAll(F.asSet(1, 2));
+ }
+ };
+
int cnt = 0;
for (CacheAtomicityMode atomicityMode : CacheAtomicityMode.values()) {
@@ -799,7 +806,9 @@ public class IgniteClientReconnectCacheTest extends IgniteClientReconnectAbstrac
log.info("Test cache get [atomicity=" + atomicityMode + ", syncMode=" + syncMode + ']');
- checkOperationInProgressFails(client, ccfg, GridNearGetResponse.class, getOp);
+ checkOperationInProgressFails(client, ccfg, GridNearSingleGetResponse.class, getOp);
+
+ checkOperationInProgressFails(client, ccfg, GridNearGetResponse.class, getAllOp);
client.destroyCache(ccfg.getName());
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 1d79e20..e8e86e9 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
@@ -382,6 +382,81 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract
/**
* @throws Exception If failed.
*/
+ public void testContainsKeyTx() throws Exception {
+ if (!txEnabled())
+ return;
+
+ IgniteCache<String, Integer> cache = jcache();
+
+ IgniteTransactions txs = ignite(0).transactions();
+
+ for (int i = 0; i < 10; i++) {
+ String key = String.valueOf(i);
+
+ try (Transaction tx = txs.txStart()) {
+ assertNull(key, cache.get(key));
+
+ assertFalse(cache.containsKey(key));
+
+ tx.commit();
+ }
+
+ try (Transaction tx = txs.txStart()) {
+ assertNull(key, cache.get(key));
+
+ cache.put(key, i);
+
+ assertTrue(cache.containsKey(key));
+
+ tx.commit();
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testContainsKeysTx() throws Exception {
+ if (!txEnabled())
+ return;
+
+ IgniteCache<String, Integer> cache = jcache();
+
+ IgniteTransactions txs = ignite(0).transactions();
+
+ Set<String> keys = new HashSet<>();
+
+ for (int i = 0; i < 10; i++) {
+ String key = String.valueOf(i);
+
+ keys.add(key);
+ }
+
+ try (Transaction tx = txs.txStart()) {
+ for (String key : keys)
+ assertNull(key, cache.get(key));
+
+ assertFalse(cache.containsKeys(keys));
+
+ tx.commit();
+ }
+
+ try (Transaction tx = txs.txStart()) {
+ for (String key : keys)
+ assertNull(key, cache.get(key));
+
+ for (String key : keys)
+ cache.put(key, 0);
+
+ assertTrue(cache.containsKeys(keys));
+
+ tx.commit();
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testRemoveInExplicitLocks() throws Exception {
if (lockingEnabled()) {
IgniteCache<String, Integer> cache = jcache();
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 1ef77f2..45c8c2c 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
@@ -613,21 +613,6 @@ public class GridCacheConcurrentTxMultiNodeTest extends GridCommonAbstractTest {
X.println("Near entry [grid="+ g.name() + ", key=" + k + ", entry=" + nearEntry);
X.println("DHT entry [grid=" + g.name() + ", key=" + k + ", entry=" + dhtEntry);
-
- GridCacheMvccCandidate nearCand =
- nearEntry == null ? null : F.first(nearEntry.localCandidates());
-
- if (nearCand != null)
- X.println("Near futures: " +
- nearEntry.context().mvcc().futures(nearCand.version()));
-
- GridCacheMvccCandidate dhtCand =
- dhtEntry == null ? null : F.first(dhtEntry.localCandidates());
-
- if (dhtCand != null)
- X.println("Dht futures: " +
- dhtEntry.context().mvcc().futures(dhtCand.version()));
-
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedGetSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedGetSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedGetSelfTest.java
index cbfc97b..2cb4a00 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedGetSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedGetSelfTest.java
@@ -28,6 +28,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.managers.communication.GridMessageListener;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
import org.apache.ignite.spi.discovery.DiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
@@ -228,7 +229,7 @@ public class GridCachePartitionedGetSelfTest extends GridCommonAbstractTest {
@Override public void onMessage(UUID nodeId, Object msg) {
info("Received message from node [nodeId=" + nodeId + ", msg=" + msg + ']');
- if (msg instanceof GridNearGetRequest) {
+ if (msg instanceof GridNearSingleGetRequest) {
info("Setting flag: " + System.identityHashCode(received));
received.set(true);
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractStopBusySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractStopBusySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractStopBusySelfTest.java
index 8ddee0c..e5cff5a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractStopBusySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractStopBusySelfTest.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.cache;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -37,6 +38,8 @@ import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.managers.communication.GridIoMessage;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.lang.IgniteInClosure;
import org.apache.ignite.plugin.extensions.communication.Message;
@@ -218,7 +221,7 @@ public abstract class IgniteCacheAbstractStopBusySelfTest extends GridCommonAbst
* @throws Exception If failed.
*/
public void testGet() throws Exception {
- bannedMsg.set(GridNearGetRequest.class);
+ bannedMsg.set(GridNearSingleGetRequest.class);
executeTest(new Callable<Integer>() {
/** {@inheritDoc} */
@@ -235,6 +238,28 @@ public abstract class IgniteCacheAbstractStopBusySelfTest extends GridCommonAbst
}
/**
+ * @throws Exception If failed.
+ */
+ public void testGetAll() throws Exception {
+ bannedMsg.set(GridNearGetRequest.class);
+
+ executeTest(new Callable<Integer>() {
+ /** {@inheritDoc} */
+ @Override public Integer call() throws Exception {
+ info("Start operation.");
+
+ Set<Integer> keys = F.asSet(1, 2, 3);
+
+ clientCache().getAll(keys);
+
+ info("Stop operation.");
+
+ return null;
+ }
+ });
+ }
+
+ /**
*
* @param call Closure executing cache operation.
* @throws Exception If failed.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
index f4423f7..9c1abc7 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
@@ -21,6 +21,7 @@ import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.cache.CacheException;
import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
@@ -30,6 +31,7 @@ import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.X;
/**
@@ -37,7 +39,10 @@ import org.apache.ignite.internal.util.typedef.X;
*/
public class IgniteCacheP2pUnmarshallingErrorTest extends IgniteCacheAbstractTest {
/** Allows to change behavior of readExternal method. */
- protected static AtomicInteger readCnt = new AtomicInteger();
+ protected static final AtomicInteger readCnt = new AtomicInteger();
+
+ /** Allows to change behavior of readExternal method. */
+ protected static final AtomicInteger valReadCnt = new AtomicInteger();
/** Iterable key. */
protected static int key = 0;
@@ -86,71 +91,40 @@ public class IgniteCacheP2pUnmarshallingErrorTest extends IgniteCacheAbstractTes
return cfg;
}
- /** Test key 1. */
- protected static class TestKey implements Externalizable {
- /** Field. */
- @QuerySqlField(index = true)
- private String field;
-
- /**
- * @param field Test key 1.
- */
- public TestKey(String field) {
- this.field = field;
- }
-
- /** Test key 1. */
- public TestKey() {
- // No-op.
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
-
- TestKey key = (TestKey)o;
-
- return !(field != null ? !field.equals(key.field) : key.field != null);
- }
+ /**
+ * Sends put atomically and handles fail.
+ *
+ * @param k Key.
+ */
+ protected void failAtomicPut(int k) {
+ try {
+ jcache(0).put(new TestKey(String.valueOf(k)), "");
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return field != null ? field.hashCode() : 0;
+ assert false : "p2p marshalling failed, but error response was not sent";
}
-
- /** {@inheritDoc} */
- @Override public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(field);
+ catch (CacheException e) {
+ assert X.hasCause(e, IOException.class);
}
- /** {@inheritDoc} */
- @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- field = (String)in.readObject();
-
- if (readCnt.decrementAndGet() <= 0)
- throw new IOException("Class can not be unmarshalled.");
- }
+ assert readCnt.get() == 0; //ensure we have read count as expected.
}
/**
- * Sends put atomically and handles fail.
+ * Sends get atomically and handles fail.
*
* @param k Key.
*/
- protected void failAtomicPut(int k) {
+ protected void failGetAll(int k) {
try {
- jcache(0).put(new TestKey(String.valueOf(k)), "");
+ Set<Object> keys = F.<Object>asSet(new TestKey(String.valueOf(k)));
+
+ jcache(0).getAll(keys);
assert false : "p2p marshalling failed, but error response was not sent";
}
catch (CacheException e) {
assert X.hasCause(e, IOException.class);
}
-
- assert readCnt.get() == 0; //ensure we have read count as expected.
}
/**
@@ -158,7 +132,7 @@ public class IgniteCacheP2pUnmarshallingErrorTest extends IgniteCacheAbstractTes
*
* @param k Key.
*/
- protected void failAtomicGet(int k) {
+ protected void failGet(int k) {
try {
jcache(0).get(new TestKey(String.valueOf(k)));
@@ -175,38 +149,132 @@ public class IgniteCacheP2pUnmarshallingErrorTest extends IgniteCacheAbstractTes
* @throws Exception If failed.
*/
public void testResponseMessageOnUnmarshallingFailed() throws Exception {
- //GridNearAtomicUpdateRequest unmarshalling failed test
+ // GridNearAtomicUpdateRequest unmarshalling failed test.
readCnt.set(1);
failAtomicPut(++key);
- //Check that cache is empty.
+ // Check that cache is empty.
readCnt.set(Integer.MAX_VALUE);
assert jcache(0).get(new TestKey(String.valueOf(key))) == null;
- //GridDhtAtomicUpdateRequest unmarshalling failed test
+ // GridDhtAtomicUpdateRequest unmarshalling failed test.
readCnt.set(2);
failAtomicPut(++key);
- //Check that cache is not empty.
+ // Check that cache is not empty.
readCnt.set(Integer.MAX_VALUE);
assert jcache(0).get(new TestKey(String.valueOf(key))) != null;
- //GridNearGetRequest unmarshalling failed test
+ // GridNearGetRequest unmarshalling failed test.
readCnt.set(1);
- failAtomicGet(++key);
+ failGetAll(++key);
- //GridNearGetResponse unmarshalling failed test
+ // GridNearGetResponse unmarshalling failed test.
readCnt.set(Integer.MAX_VALUE);
jcache(0).put(new TestKey(String.valueOf(++key)), "");
readCnt.set(2);
- failAtomicGet(key);
+ failGetAll(key);
+
+ readCnt.set(Integer.MAX_VALUE);
+ valReadCnt.set(Integer.MAX_VALUE);
+
+ jcache(0).put(new TestKey(String.valueOf(++key)), new TestValue());
+
+ assertNotNull(new TestKey(String.valueOf(key)));
+
+ // GridNearSingleGetRequest unmarshalling failed.
+ readCnt.set(1);
+
+ failGet(key);
+
+ // GridNearSingleGetRequest unmarshalling failed.
+ valReadCnt.set(1);
+ readCnt.set(2);
+
+ failGet(key);
+ }
+
+ /**
+ * Test key.
+ */
+ protected static class TestKey implements Externalizable {
+ /** Field. */
+ @QuerySqlField(index = true)
+ private String field;
+
+ /**
+ * Required by {@link Externalizable}.
+ */
+ public TestKey() {
+ // No-op.
+ }
+
+ /**
+ * @param field Test key 1.
+ */
+ public TestKey(String field) {
+ this.field = field;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ TestKey key = (TestKey)o;
+
+ return !(field != null ? !field.equals(key.field) : key.field != null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return field != null ? field.hashCode() : 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(field);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ field = (String)in.readObject();
+
+ if (readCnt.decrementAndGet() <= 0)
+ throw new IOException("Class can not be unmarshalled.");
+ }
+ }
+
+ /**
+ * Test value.
+ */
+ protected static class TestValue implements Externalizable {
+ /**
+ * Required by {@link Externalizable}.
+ */
+ public TestValue() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ if (valReadCnt.decrementAndGet() <= 0)
+ throw new IOException("Class can not be unmarshalled.");
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheGetFutureHangsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheGetFutureHangsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheGetFutureHangsSelfTest.java
index 53ac648..c005945 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheGetFutureHangsSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheGetFutureHangsSelfTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.distributed;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicReferenceArray;
@@ -29,6 +30,7 @@ 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.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
@@ -135,12 +137,16 @@ public class CacheGetFutureHangsSelfTest extends GridCommonAbstractTest {
@Override public void run() {
T2<Ignite, Integer> ignite;
+ Set<Integer> keys = F.asSet(1, 2, 3, 4, 5);
+
while ((ignite = randomNode()) != null) {
IgniteCache<Object, Object> cache = ignite.get1().cache(null);
for (int i = 0; i < 100; i++)
cache.containsKey(ThreadLocalRandom.current().nextInt(100_000));
+ cache.containsKeys(keys);
+
assertTrue(nodes.compareAndSet(ignite.get2(), null, ignite.get1()));
try {
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheAbstractNodeRestartSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheAbstractNodeRestartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheAbstractNodeRestartSelfTest.java
index 6f0565b..dbd8758 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheAbstractNodeRestartSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheAbstractNodeRestartSelfTest.java
@@ -661,6 +661,8 @@ public abstract class GridCacheAbstractNodeRestartSelfTest extends GridCommonAbs
// It is ok if primary node leaves grid.
}
+ cache.get(key);
+
int c = putCntr.incrementAndGet();
if (c % logFreq == 0)
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSingleGetMessageTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSingleGetMessageTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSingleGetMessageTest.java
new file mode 100644
index 0000000..42b5ee3
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSingleGetMessageTest.java
@@ -0,0 +1,357 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.communication.GridIoMessage;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
+import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.spi.IgniteSpiException;
+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;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
+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.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+
+/**
+ *
+ */
+public class IgniteCacheSingleGetMessageTest extends GridCommonAbstractTest {
+ /** */
+ private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ private static final int SRVS = 4;
+
+ /** */
+ private boolean client;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ cfg.setClientMode(client);
+
+ TestCommunicationSpi commSpi = new TestCommunicationSpi();
+
+ cfg.setCommunicationSpi(commSpi);
+
+ ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder);
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGridsMultiThreaded(SRVS);
+
+ client = true;
+
+ startGridsMultiThreaded(SRVS, 1);
+
+ client = false;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testSingleGetMessage() throws Exception {
+ assertFalse(ignite(0).configuration().isClientMode());
+ assertTrue(ignite(SRVS).configuration().isClientMode());
+
+ List<CacheConfiguration<Integer, Integer>> ccfgs = cacheConfigurations();
+
+ for (int i = 0; i < ccfgs.size(); i++) {
+ CacheConfiguration<Integer, Integer> ccfg = ccfgs.get(i);
+
+ ccfg.setName("cache-" + i);
+
+ log.info("Test cache: " + i);
+
+ ignite(0).createCache(ccfg);
+
+ try {
+ IgniteCache<Integer, Integer> srvCache = ignite(0).cache(ccfg.getName());
+ IgniteCache<Integer, Integer> clientCache = ignite(SRVS).cache(ccfg.getName());
+
+ Integer key = nearKey(clientCache);
+
+ checkSingleGetMessage(clientCache, key, false);
+
+ if (ccfg.getBackups() > 0) {
+ key = backupKeys(srvCache, 1, 100_000).get(0);
+
+ checkSingleGetMessage(srvCache, key, true);
+ }
+
+ if (ccfg.getCacheMode() != REPLICATED) {
+ key = nearKeys(srvCache, 1, 200_000).get(0);
+
+ checkSingleGetMessage(srvCache, key, false);
+ }
+ }
+ finally {
+ ignite(0).destroyCache(ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @param cache Cache.
+ * @param key Key.
+ * @param backup {@code True} if given key is backup key.
+ * @throws Exception If failed.
+ */
+ @SuppressWarnings("unchecked")
+ private void checkSingleGetMessage(IgniteCache<Integer, Integer> cache,
+ Integer key,
+ boolean backup) throws Exception {
+ CacheConfiguration<Integer, Integer> ccfg = cache.getConfiguration(CacheConfiguration.class);
+
+ Ignite node = cache.unwrap(Ignite.class);
+
+ TestCommunicationSpi spi = (TestCommunicationSpi)node.configuration().getCommunicationSpi();
+
+ spi.record(GridNearSingleGetRequest.class);
+
+ Ignite primary = primaryNode(key, cache.getName());
+
+ assertNotSame(node, primary);
+
+ TestCommunicationSpi primarySpi = (TestCommunicationSpi)primary.configuration().getCommunicationSpi();
+
+ primarySpi.record(GridNearSingleGetResponse.class);
+
+ assertNull(cache.get(key));
+
+ checkMessages(spi, primarySpi);
+
+ assertFalse(cache.containsKey(key));
+
+ checkMessages(spi, primarySpi);
+
+ cache.put(key, 1);
+
+ assertNotNull(cache.get(key));
+
+ if (backup)
+ checkNoMessages(spi, primarySpi);
+ else
+ checkMessages(spi, primarySpi);
+
+ assertTrue(cache.containsKey(key));
+
+ if (backup)
+ checkNoMessages(spi, primarySpi);
+ else
+ checkMessages(spi, primarySpi);
+
+ if (ccfg.getAtomicityMode() == TRANSACTIONAL) {
+ cache.remove(key);
+
+ try (Transaction tx = node.transactions().txStart(OPTIMISTIC, REPEATABLE_READ)) {
+ assertNull(cache.get(key));
+
+ tx.commit();
+ }
+
+ checkMessages(spi, primarySpi);
+
+ try (Transaction tx = node.transactions().txStart(OPTIMISTIC, REPEATABLE_READ)) {
+ assertFalse(cache.containsKey(key));
+
+ tx.commit();
+ }
+
+ checkMessages(spi, primarySpi);
+
+ cache.put(key, 1);
+
+ try (Transaction tx = node.transactions().txStart(OPTIMISTIC, REPEATABLE_READ)) {
+ assertNotNull(cache.get(key));
+
+ tx.commit();
+ }
+
+ if (backup)
+ checkNoMessages(spi, primarySpi);
+ else
+ checkMessages(spi, primarySpi);
+
+ try (Transaction tx = node.transactions().txStart(OPTIMISTIC, REPEATABLE_READ)) {
+ assertTrue(cache.containsKey(key));
+
+ tx.commit();
+ }
+
+ if (backup)
+ checkNoMessages(spi, primarySpi);
+ else
+ checkMessages(spi, primarySpi);
+ }
+ }
+
+ /**
+ * @param spi Near node SPI.
+ * @param primarySpi Primary node SPI.
+ */
+ private void checkMessages(TestCommunicationSpi spi, TestCommunicationSpi primarySpi) {
+ List<Object> msgs = spi.recordedMessages();
+
+ assertEquals(1, msgs.size());
+ assertTrue(msgs.get(0) instanceof GridNearSingleGetRequest);
+
+ msgs = primarySpi.recordedMessages();
+
+ assertEquals(1, msgs.size());
+ assertTrue(msgs.get(0) instanceof GridNearSingleGetResponse);
+ }
+
+ /**
+ * @param spi Near node SPI.
+ * @param primarySpi Primary node SPI.
+ */
+ private void checkNoMessages(TestCommunicationSpi spi, TestCommunicationSpi primarySpi) {
+ List<Object> msgs = spi.recordedMessages();
+ assertEquals(0, msgs.size());
+
+ msgs = primarySpi.recordedMessages();
+ assertEquals(0, msgs.size());
+ }
+
+ /**
+ * @return Cache configurations to test.
+ */
+ private List<CacheConfiguration<Integer, Integer>> cacheConfigurations() {
+ List<CacheConfiguration<Integer, Integer>> ccfgs = new ArrayList<>();
+
+ ccfgs.add(cacheConfiguration(PARTITIONED, TRANSACTIONAL, FULL_SYNC, 0));
+ ccfgs.add(cacheConfiguration(PARTITIONED, TRANSACTIONAL, FULL_SYNC, 1));
+ ccfgs.add(cacheConfiguration(REPLICATED, TRANSACTIONAL, FULL_SYNC, 0));
+
+ ccfgs.add(cacheConfiguration(PARTITIONED, ATOMIC, FULL_SYNC, 0));
+ ccfgs.add(cacheConfiguration(PARTITIONED, ATOMIC, FULL_SYNC, 1));
+ ccfgs.add(cacheConfiguration(REPLICATED, ATOMIC, FULL_SYNC, 0));
+
+ return ccfgs;
+ }
+
+ /**
+ * @param cacheMode Cache mode.
+ * @param atomicityMode Cache atomicity mode.
+ * @param syncMode Write synchronization mode.
+ * @param backups Number of backups.
+ * @return Cache configuration.
+ */
+ private CacheConfiguration<Integer, Integer> cacheConfiguration(
+ CacheMode cacheMode,
+ CacheAtomicityMode atomicityMode,
+ CacheWriteSynchronizationMode syncMode,
+ int backups) {
+ CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+
+ ccfg.setCacheMode(cacheMode);
+ ccfg.setAtomicityMode(atomicityMode);
+ ccfg.setAtomicityMode(TRANSACTIONAL);
+ ccfg.setWriteSynchronizationMode(syncMode);
+
+ if (cacheMode == PARTITIONED)
+ ccfg.setBackups(backups);
+
+ return ccfg;
+ }
+
+ /**
+ *
+ */
+ private static class TestCommunicationSpi extends TcpCommunicationSpi {
+ /** */
+ private Class<?> recordCls;
+
+ /** */
+ private List<Object> recordedMsgs = new ArrayList<>();
+
+ /** {@inheritDoc} */
+ @Override public void sendMessage(ClusterNode node, Message msg, IgniteInClosure<IgniteException> ackC)
+ throws IgniteSpiException {
+ if (msg instanceof GridIoMessage) {
+ Object msg0 = ((GridIoMessage)msg).message();
+
+ synchronized (this) {
+ if (recordCls != null && msg0.getClass().equals(recordCls))
+ recordedMsgs.add(msg0);
+ }
+ }
+
+ super.sendMessage(node, msg, ackC);
+ }
+
+ /**
+ * @param recordCls Message class to record.
+ */
+ void record(@Nullable Class<?> recordCls) {
+ synchronized (this) {
+ this.recordCls = recordCls;
+ }
+ }
+
+ /**
+ * @return Recorded messages.
+ */
+ List<Object> recordedMessages() {
+ synchronized (this) {
+ List<Object> msgs = recordedMsgs;
+
+ recordedMsgs = new ArrayList<>();
+
+ return msgs;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridCacheReplicatedMetricsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridCacheReplicatedMetricsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridCacheReplicatedMetricsSelfTest.java
index 319aa56..2fa43be 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridCacheReplicatedMetricsSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridCacheReplicatedMetricsSelfTest.java
@@ -18,7 +18,6 @@
package org.apache.ignite.internal.processors.cache.distributed.replicated;
import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.processors.cache.GridCacheTransactionalAbstractMetricsSelfTest;
import static org.apache.ignite.cache.CacheMode.REPLICATED;
@@ -30,14 +29,6 @@ public class GridCacheReplicatedMetricsSelfTest extends GridCacheTransactionalAb
/** */
private static final int GRID_CNT = 2;
- @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
- IgniteConfiguration c = super.getConfiguration(gridName);
-
- c.getTransactionConfiguration().setTxSerializableEnabled(true);
-
- return c;
- }
-
/** {@inheritDoc} */
@Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception {
CacheConfiguration cfg = super.cacheConfiguration(gridName);
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
index b89bffd..fcc8d37 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
@@ -81,6 +81,7 @@ import org.apache.ignite.internal.processors.cache.distributed.CacheGetFutureHan
import org.apache.ignite.internal.processors.cache.distributed.CacheNoValueClassOnServerNodeTest;
import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheCreatePutMultiNodeSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheCreatePutTest;
+import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheSingleGetMessageTest;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridCacheDhtTxPreloadSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.dht.IgniteCacheLockFailoverSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.dht.IgniteCacheMultiTxLockSelfTest;
@@ -283,6 +284,8 @@ public class IgniteCacheTestSuite4 extends TestSuite {
suite.addTestSuite(CacheGetFutureHangsSelfTest.class);
+ suite.addTestSuite(IgniteCacheSingleGetMessageTest.class);
+
return suite;
}
}
\ No newline at end of file
[13/23] ignite git commit: ACCEPT_ALL predicate should have SUID.
This closes #248.
Posted by sb...@apache.org.
ACCEPT_ALL predicate should have SUID. This closes #248.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f708c1a4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f708c1a4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f708c1a4
Branch: refs/heads/ignite-sql-opt
Commit: f708c1a4d33b202bf0e74edef2f5113612797f8e
Parents: e369e1f
Author: agura <ag...@gridgain.com>
Authored: Thu Nov 19 19:29:27 2015 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Nov 19 19:29:27 2015 +0300
----------------------------------------------------------------------
.../apache/ignite/internal/processors/cache/IgniteCacheProxy.java | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/f708c1a4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
index 4b03bb9..d896249 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
@@ -97,6 +97,9 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V
/** */
private static final IgniteBiPredicate ACCEPT_ALL = new IgniteBiPredicate() {
+ /** */
+ private static final long serialVersionUID = -1640538788290240617L;
+
@Override public boolean apply(Object k, Object v) {
return true;
}
[03/23] ignite git commit: IGNITE-1790 Camel streamer: Add README.txt,
license txt and fix Javadoc.
Posted by sb...@apache.org.
IGNITE-1790 Camel streamer: Add README.txt, license txt and fix Javadoc.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/480d457a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/480d457a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/480d457a
Branch: refs/heads/ignite-sql-opt
Commit: 480d457a724800c1afa4aadf3fc9ceda7f9a217f
Parents: fee7f86
Author: Raul Kripalani <ra...@apache.org>
Authored: Thu Nov 19 11:47:25 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Thu Nov 19 11:47:34 2015 +0000
----------------------------------------------------------------------
modules/camel/README.txt | 34 ++++
modules/camel/licenses/apache-2.0.txt | 202 +++++++++++++++++++
.../ignite/stream/camel/CamelStreamer.java | 2 +-
3 files changed, 237 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/480d457a/modules/camel/README.txt
----------------------------------------------------------------------
diff --git a/modules/camel/README.txt b/modules/camel/README.txt
new file mode 100644
index 0000000..ca119ae
--- /dev/null
+++ b/modules/camel/README.txt
@@ -0,0 +1,34 @@
+Apache Ignite Camel Module
+--------------------------
+
+Apache Ignite Camel provides a streamer to consume cache tuples from a Camel endpoint such as
+HTTP, TCP, File, FTP, AMQP, SNMP, databases, etc. For more information on available components,
+refer to http://camel.apache.org/components.html.
+
+To enable the Camel module when starting a standalone node, move 'optional/ignite-camel' folder
+to 'libs' folder before running 'ignite.{sh|bat}' script. The content of the module folder will
+be added to classpath in this case.
+
+Importing the Camel module in a Maven project
+---------------------------------------------
+
+If you are using Maven to manage dependencies of your project, you can add the Camel module
+dependency like this (replace '${ignite.version}' with actual Ignite version you are
+interested in):
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ ...
+ <dependencies>
+ ...
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-camel</artifactId>
+ <version>${ignite.version}</version>
+ </dependency>
+ ...
+ </dependencies>
+ ...
+</project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/480d457a/modules/camel/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/camel/licenses/apache-2.0.txt b/modules/camel/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/camel/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
http://git-wip-us.apache.org/repos/asf/ignite/blob/480d457a/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java
----------------------------------------------------------------------
diff --git a/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java b/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java
index 40ed6b3..369d2a6 100644
--- a/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java
+++ b/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java
@@ -40,7 +40,7 @@ import org.apache.ignite.stream.StreamSingleTupleExtractor;
* This streamer consumes messages from an Apache Camel consumer endpoint and feeds them into an Ignite data streamer.
*
* The only mandatory properties are {@link #endpointUri} and the appropriate stream tuple extractor (either {@link
- * StreamSingleTupleExtractor} or {@link StreamMultipleTupleExtractor)}.
+ * StreamSingleTupleExtractor} or {@link StreamMultipleTupleExtractor}.
*
* The user can also provide a custom {@link CamelContext} in case they want to attach custom components, a {@link
* org.apache.camel.component.properties.PropertiesComponent}, set tracers, management strategies, etc.
[16/23] ignite git commit: Updated benchmark properties file:
benchmark-query-put-separated.properties
Posted by sb...@apache.org.
Updated benchmark properties file: benchmark-query-put-separated.properties
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8728a5b8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8728a5b8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8728a5b8
Branch: refs/heads/ignite-sql-opt
Commit: 8728a5b8a1b70cd0aa2c623e38c7e93e1bd2d5f3
Parents: c85d1f5
Author: ashutak <as...@gridgain.com>
Authored: Thu Nov 19 19:36:56 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Thu Nov 19 19:36:56 2015 +0300
----------------------------------------------------------------------
.../config/benchmark-query-put-separated.properties | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/8728a5b8/modules/yardstick/config/benchmark-query-put-separated.properties
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/benchmark-query-put-separated.properties b/modules/yardstick/config/benchmark-query-put-separated.properties
index b1b2942..6d2ce33 100644
--- a/modules/yardstick/config/benchmark-query-put-separated.properties
+++ b/modules/yardstick/config/benchmark-query-put-separated.properties
@@ -70,10 +70,10 @@ nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS}
b=1
# Warmup.
-w=10
+w=60
# Duration.
-d=30
+d=300
# Threads count.
t=64
@@ -81,8 +81,7 @@ t=64
# Sync mode.
sm=PRIMARY_SYNC
-# Run configuration which contains all benchmarks.
-# Note that each benchmark is set to run for 300 seconds (5 mins) with warm-up set to 60 seconds (1 minute).
+# Run configuration which contains separated query put benchmark.
CONFIGS="\
--cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w ${w} -d ${d} -t ${t} -sm PRIMARY_SYNC -dn IgniteSqlQueryPutSeparatedBenchmark -sn IgniteNode -ds query-put-1b,\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w ${w} -d ${d} -t ${t} -sm PRIMARY_SYNC -dn IgniteSqlQueryPutSeparatedBenchmark -sn IgniteNode -ds ${ver}query-put-separated-1b,\
"
[05/23] ignite git commit: IGNITE-530 Initial implementation
Posted by sb...@apache.org.
IGNITE-530 Initial implementation
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a39681ef
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a39681ef
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a39681ef
Branch: refs/heads/ignite-sql-opt
Commit: a39681ef54206ac23f3dff9dab930dc2596d9870
Parents: 480d457
Author: sylentprayer <un4given>
Authored: Thu Nov 19 15:32:24 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Thu Nov 19 15:32:24 2015 +0300
----------------------------------------------------------------------
modules/twitter/README.txt | 32 ++
modules/twitter/licenses/apache-2.0.txt | 202 +++++++++++++
modules/twitter/pom.xml | 116 ++++++++
.../ignite/stream/twitter/OAuthSettings.java | 86 ++++++
.../ignite/stream/twitter/TwitterStreamer.java | 295 +++++++++++++++++++
.../twitter/IgniteTwitterStreamerTest.java | 234 +++++++++++++++
.../twitter/IgniteTwitterStreamerTestSuite.java | 32 ++
.../stream/twitter/TwitterStreamerImpl.java | 79 +++++
pom.xml | 1 +
9 files changed, 1077 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/README.txt
----------------------------------------------------------------------
diff --git a/modules/twitter/README.txt b/modules/twitter/README.txt
new file mode 100644
index 0000000..1c412f9
--- /dev/null
+++ b/modules/twitter/README.txt
@@ -0,0 +1,32 @@
+Apache Ignite Twitter Streamer Module
+------------------------
+
+Apache Ignite Twitter Streamer module provides streaming from Twitter to Ignite cache.
+
+To enable Twitter Streamer module when starting a standalone node, move 'optional/ignite-twitter' folder to
+'libs' folder before running 'ignite.{sh|bat}' script. The content of the module folder will
+be added to classpath in this case.
+
+Importing Ignite Twitter Streamer Module In Maven Project
+-------------------------------------
+
+If you are using Maven to manage dependencies of your project, you can add JCL module
+dependency like this (replace '${ignite.version}' with actual Ignite version you are
+interested in):
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ ...
+ <dependencies>
+ ...
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-twitter</artifactId>
+ <version>${ignite.version}</version>
+ </dependency>
+ ...
+ </dependencies>
+ ...
+</project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/twitter/licenses/apache-2.0.txt b/modules/twitter/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/twitter/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/pom.xml
----------------------------------------------------------------------
diff --git a/modules/twitter/pom.xml b/modules/twitter/pom.xml
new file mode 100644
index 0000000..21e6f51
--- /dev/null
+++ b/modules/twitter/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-parent</artifactId>
+ <version>1</version>
+ <relativePath>../../parent</relativePath>
+ </parent>
+
+ <artifactId>ignite-twitter</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <url>http://ignite.apache.org</url>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-log4j</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-spring</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.twitter</groupId>
+ <artifactId>hbc-twitter4j</artifactId>
+ <version>2.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.tomakehurst</groupId>
+ <artifactId>wiremock</artifactId>
+ <version>1.57</version>
+ <classifier>standalone</classifier>
+ <exclusions>
+ <exclusion>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.skyscreamer</groupId>
+ <artifactId>jsonassert</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.jayway.jsonpath</groupId>
+ <artifactId>json-path</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>net.sf.jopt-simple</groupId>
+ <artifactId>jopt-simple</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/OAuthSettings.java
----------------------------------------------------------------------
diff --git a/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/OAuthSettings.java b/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/OAuthSettings.java
new file mode 100644
index 0000000..c2e46a5
--- /dev/null
+++ b/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/OAuthSettings.java
@@ -0,0 +1,86 @@
+/*
+ * 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.stream.twitter;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * OAuth keys holder.
+ */
+public class OAuthSettings {
+ /** */
+ private final String consumerKey;
+
+ /** */
+ private final String consumerSecret;
+
+ /** */
+ private final String accessToken;
+
+ /** */
+ private final String accessTokenSecret;
+
+ /**
+ * @param consumerKey Consumer key.
+ * @param consumerSecret Consumer secret.
+ * @param accessToken Access token.
+ * @param accessTokenSecret Access secret token.
+ */
+ public OAuthSettings(
+ @NotNull String consumerKey,
+ @NotNull String consumerSecret,
+ @NotNull String accessToken,
+ @NotNull String accessTokenSecret) {
+ this.consumerKey = consumerKey;
+ this.consumerSecret = consumerSecret;
+ this.accessToken = accessToken;
+ this.accessTokenSecret = accessTokenSecret;
+ }
+
+ /**
+ * @return Consumer key.
+ */
+ @NotNull
+ public String getConsumerKey() {
+ return consumerKey;
+ }
+
+ /**
+ * @return Consumer secret.
+ */
+ @NotNull
+ public String getConsumerSecret() {
+ return consumerSecret;
+ }
+
+ /**
+ * @return Access token.
+ */
+ @NotNull
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ /**
+ * @return Access token secret.
+ */
+ @NotNull
+ public String getAccessTokenSecret() {
+ return accessTokenSecret;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/TwitterStreamer.java
----------------------------------------------------------------------
diff --git a/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/TwitterStreamer.java b/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/TwitterStreamer.java
new file mode 100644
index 0000000..309cc52
--- /dev/null
+++ b/modules/twitter/src/main/java/org/apache/ignite/stream/twitter/TwitterStreamer.java
@@ -0,0 +1,295 @@
+/*
+ * 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.stream.twitter;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import com.twitter.hbc.ClientBuilder;
+import com.twitter.hbc.core.Client;
+import com.twitter.hbc.core.HttpConstants;
+import com.twitter.hbc.core.HttpHosts;
+import com.twitter.hbc.core.endpoint.DefaultStreamingEndpoint;
+import com.twitter.hbc.core.endpoint.SitestreamEndpoint;
+import com.twitter.hbc.core.endpoint.StatusesFilterEndpoint;
+import com.twitter.hbc.core.endpoint.StatusesFirehoseEndpoint;
+import com.twitter.hbc.core.endpoint.StatusesSampleEndpoint;
+import com.twitter.hbc.core.endpoint.StreamingEndpoint;
+import com.twitter.hbc.core.endpoint.UserstreamEndpoint;
+import com.twitter.hbc.core.processor.StringDelimitedProcessor;
+import com.twitter.hbc.httpclient.auth.Authentication;
+import com.twitter.hbc.httpclient.auth.OAuth1;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.stream.StreamAdapter;
+
+/**
+ * Streamer that consumes from a Twitter Streaming API and feeds transformed key-value pairs,
+ * by default <tweetId, text>, into an {@link IgniteDataStreamer} instance.
+ * <p>
+ * This streamer uses https://dev.twitter.com/streaming API and supports Public API, User Streams,
+ * Site Streams and Firehose.
+ * <p>
+ * This Streamer features:
+ * <ul>
+ * <li>Supports OAuth1 authentication scheme.
+ * <br/> BasicAuth not supported by Streaming API https://dev.twitter.com/streaming/overview/connecting</li>
+ * <li>Provide all params in apiParams map. https://dev.twitter.com/streaming/overview/request-parameters</li>
+ * </ul>
+ */
+public class TwitterStreamer<K, V> extends StreamAdapter<String, K, V> {
+ /** Logger. */
+ protected IgniteLogger log;
+
+ /** Threads count used to transform tweets. */
+ private int threadsCount = 1;
+
+ /** Twitter Streaming API params. See https://dev.twitter.com/streaming/overview/request-parameters */
+ private Map<String, String> apiParams;
+
+ /** Twitter streaming API endpoint example, '/statuses/filter.json' or '/statuses/firehose.json' */
+ private String endpointUrl;
+
+ /** OAuth params holder */
+ private OAuthSettings oAuthSettings;
+
+ /** shared variable to communicate/signal that streamer is already running or can be started */
+ private final AtomicInteger running = new AtomicInteger();
+
+ /**
+ * Size of buffer for streaming, as for some tracking terms traffic can be low and for others high, this is
+ * configurable
+ */
+ private Integer bufferCapacity = 100000;
+
+ /** Twitter streaming client (Twitter HBC) to interact with stream */
+ private Client client;
+
+ /** Process stream asynchronously */
+ private ExecutorService tweetStreamProcessor;
+
+ /** Param key name constant for Site streaming */
+ private final String SITE_USER_ID_KEY = "follow";
+
+ /**
+ * @param oAuthSettings OAuth Settings
+ */
+ public TwitterStreamer(OAuthSettings oAuthSettings) {
+ this.oAuthSettings = oAuthSettings;
+ }
+
+ /**
+ * Starts streamer.
+ */
+ public void start() {
+ if (!running.compareAndSet(0, 1))
+ throw new IgniteException("Attempted to start an already started Twitter Streamer");
+
+ validateConfig();
+
+ log = getIgnite().log();
+
+ final BlockingQueue<String> tweetQueue = new LinkedBlockingQueue<>(bufferCapacity);
+
+ client = getClient(tweetQueue);
+
+ client.connect();
+
+ tweetStreamProcessor = Executors.newFixedThreadPool(threadsCount);
+
+ for (int i = 0; i < threadsCount; i++) {
+ Callable<Boolean> task = new Callable<Boolean>() {
+
+ @Override
+ public Boolean call() {
+ while (true) {
+ try {
+ String tweet = tweetQueue.take();
+
+ addMessage(tweet);
+ }
+ catch (InterruptedException e) {
+ U.warn(log, "Tweets transformation was interrupted", e);
+
+ return true;
+ }
+ }
+ }
+ };
+
+ tweetStreamProcessor.submit(task);
+ }
+ }
+
+ /**
+ * Stops streamer.
+ */
+ public void stop() {
+ if (running.get() == 0)
+ throw new IgniteException("Attempted to stop an already stopped Twitter Streamer");
+
+ tweetStreamProcessor.shutdownNow();
+
+ client.stop();
+
+ running.compareAndSet(1, 0);
+ }
+
+ /**
+ * Validates config at start.
+ */
+ protected void validateConfig() {
+ A.notNull(getStreamer(), "Streamer");
+ A.notNull(getIgnite(), "Ignite");
+ A.notNull(endpointUrl, "Twitter Streaming API endpoint");
+
+ A.ensure(getSingleTupleExtractor() != null || getMultipleTupleExtractor() != null, "Twitter extractor");
+
+ String followParam = apiParams.get(SITE_USER_ID_KEY);
+
+ A.ensure(followParam != null && followParam.matches("^(\\d+,? ?)+$"),
+ "Site streaming endpoint must provide 'follow' param with value as comma separated numbers");
+ }
+
+ /**
+ * @param tweetQueue Tweet queue.
+ * @return Client.
+ */
+ protected Client getClient(BlockingQueue<String> tweetQueue) {
+ StreamingEndpoint endpoint;
+
+ HttpHosts hosts;
+
+ switch (endpointUrl.toLowerCase()) {
+ case StatusesFilterEndpoint.PATH:
+ endpoint = new StatusesFilterEndpoint();
+
+ hosts = HttpHosts.STREAM_HOST;
+
+ break;
+ case StatusesFirehoseEndpoint.PATH:
+ endpoint = new StatusesFirehoseEndpoint();
+
+ hosts = HttpHosts.STREAM_HOST;
+
+ break;
+ case StatusesSampleEndpoint.PATH:
+ endpoint = new StatusesSampleEndpoint();
+
+ hosts = HttpHosts.STREAM_HOST;
+
+ break;
+ case UserstreamEndpoint.PATH:
+ endpoint = new UserstreamEndpoint();
+
+ hosts = HttpHosts.USERSTREAM_HOST;
+
+ break;
+ case SitestreamEndpoint.PATH:
+ String follow = apiParams.remove(SITE_USER_ID_KEY);
+
+ List<Long> followers = Lists.newArrayList();
+
+ for (String follower : Splitter.on(',').trimResults().omitEmptyStrings().split(follow))
+ followers.add(Long.valueOf(follower));
+
+ endpoint = new SitestreamEndpoint(followers);
+
+ hosts = HttpHosts.SITESTREAM_HOST;
+
+ break;
+ default:
+ endpoint = new DefaultStreamingEndpoint(endpointUrl, HttpConstants.HTTP_GET, false);
+
+ hosts = HttpHosts.STREAM_HOST;
+
+ }
+
+ for (Map.Entry<String, String> entry : apiParams.entrySet()) {
+ endpoint.addPostParameter(entry.getKey(), entry.getValue());
+ }
+
+ return buildClient(tweetQueue, hosts, endpoint);
+ }
+
+ /**
+ * @param tweetQueue tweet Queue.
+ * @param hosts Hostes.
+ * @param endpoint Endpoint.
+ * @return Client.
+ */
+ protected Client buildClient(BlockingQueue<String> tweetQueue, HttpHosts hosts, StreamingEndpoint endpoint) {
+ Authentication authentication = new OAuth1(oAuthSettings.getConsumerKey(), oAuthSettings.getConsumerSecret(),
+ oAuthSettings.getAccessToken(), oAuthSettings.getAccessTokenSecret());
+
+ ClientBuilder builder = new ClientBuilder()
+ .name("Ignite-Twitter-Client")
+ .hosts(hosts)
+ .authentication(authentication)
+ .endpoint(endpoint)
+ .processor(new StringDelimitedProcessor(tweetQueue));
+
+ return builder.build();
+ }
+
+ /**
+ * Sets API Params.
+ *
+ * @param apiParams API Params.
+ */
+ public void setApiParams(Map<String, String> apiParams) {
+ this.apiParams = apiParams;
+ }
+
+ /**
+ * Sets Endpoint URL.
+ *
+ * @param endpointUrl Endpoint URL.
+ */
+ public void setEndpointUrl(String endpointUrl) {
+ this.endpointUrl = endpointUrl;
+ }
+
+ /**
+ * Sets Buffer capacity.
+ *
+ * @param bufferCapacity Buffer capacity.
+ */
+ public void setBufferCapacity(Integer bufferCapacity) {
+ this.bufferCapacity = bufferCapacity;
+ }
+
+ /**
+ * Sets Threads count.
+ *
+ * @param threadsCount Threads count.
+ */
+ public void setThreadsCount(int threadsCount) {
+ this.threadsCount = threadsCount;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTest.java b/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTest.java
new file mode 100644
index 0000000..4ba07ff
--- /dev/null
+++ b/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.stream.twitter;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.twitter.hbc.core.HttpHosts;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.events.CacheEvent;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Rule;
+import twitter4j.Status;
+import twitter4j.TwitterException;
+import twitter4j.TwitterObjectFactory;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
+
+/**
+ * Test for {@link TwitterStreamer}. Tests Public Status streaming API https://dev.twitter.com/streaming/public.
+ */
+public class IgniteTwitterStreamerTest extends GridCommonAbstractTest {
+
+ /** Cache entries count. */
+ private static final int CACHE_ENTRY_COUNT = 100;
+
+ /** Mocked api in embedded server. */
+ private static final String MOCK_TWEET_PATH = "/tweet/mock";
+
+ /** Sample tweet. */
+ private static final String tweet = "{\"id\":647375831971590144,\"text\":\"sample tweet to test streamer\"}\n";
+
+ /** Constructor. */
+ public IgniteTwitterStreamerTest() {
+ super(true);
+ }
+
+ /** Embedded mock HTTP server's for Twitter API rule. */
+ @Rule
+ public final WireMockRule wireMockRule = new WireMockRule();
+
+ /** Embedded mock HTTP server for Twitter API. */
+ public final WireMockServer mockServer = new WireMockServer(); //Starts server on 8080 port.
+
+ /** {@inheritDoc} */
+ @Override protected long getTestTimeout() {
+ return 10_000;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void beforeTest() throws Exception {
+ grid().getOrCreateCache(defaultCacheConfiguration());
+
+ mockServer.start();
+
+ stubFor(get(urlMatching("/1.1" + MOCK_TWEET_PATH + ".*")).willReturn(aResponse().
+ withHeader("Content-Type", "text/plain").withBody(tweet.length() + "\n" + tweet)));
+ }
+
+ /** {@inheritDoc} */
+ public void afterTest() throws Exception {
+ stopAllGrids();
+
+ mockServer.stop();
+ }
+
+ /**
+ * @throws Exception Test exception.
+ */
+ public void testStatusesFilterEndpointOAuth1() throws Exception {
+ try (IgniteDataStreamer<Long, String> dataStreamer = grid().dataStreamer(null)) {
+ TwitterStreamerImpl streamer = newStreamerInstance(dataStreamer);
+
+ Map<String, String> params = new HashMap<>();
+
+ params.put("track", "apache, twitter");
+ params.put("follow", "3004445758");// @ApacheIgnite id.
+
+ streamer.setApiParams(params);
+ streamer.setEndpointUrl(MOCK_TWEET_PATH);
+ streamer.setHosts(new HttpHosts("http://localhost:8080"));
+ streamer.setThreadsCount(8);
+
+ executeStreamer(streamer);
+ }
+ }
+
+ /**
+ * @param streamer Twitter streamer.
+ * @throws InterruptedException Test exception.
+ * @throws TwitterException Test exception.
+ */
+ private void executeStreamer(TwitterStreamer streamer) throws InterruptedException, TwitterException {
+ // Checking streaming.
+
+ CacheListener listener = subscribeToPutEvents();
+
+ streamer.start();
+
+ try {
+ streamer.start();
+
+ fail("Successful start of already started Twitter Streamer");
+ }
+ catch (IgniteException ex) {
+ // No-op.
+ }
+
+ CountDownLatch latch = listener.getLatch();
+
+ // Enough tweets was handled in 10 seconds. Limited by test's timeout.
+ latch.await();
+
+ unsubscribeToPutEvents(listener);
+
+ streamer.stop();
+
+ try {
+ streamer.stop();
+
+ fail("Successful stop of already stopped Twitter Streamer");
+ }
+ catch (IgniteException ex) {
+ // No-op.
+ }
+
+ // Checking cache content after streaming finished.
+
+ Status status = TwitterObjectFactory.createStatus(tweet);
+
+ IgniteCache<Long, String> cache = grid().cache(null);
+
+ String cachedValue = cache.get(status.getId());
+
+ // Tweet successfully put to cache.
+ assertTrue(cachedValue != null && cachedValue.equals(status.getText()));
+
+ // Same tweets does not produce duplicate entries.
+ assertTrue(cache.size() == 1);
+ }
+
+ /**
+ * @return Cache listener.
+ */
+ private CacheListener subscribeToPutEvents() {
+ Ignite ignite = grid();
+
+ // Listen to cache PUT events and expect as many as messages as test data items.
+ CacheListener listener = new CacheListener();
+
+ ignite.events(ignite.cluster().forCacheNodes(null)).localListen(listener, EVT_CACHE_OBJECT_PUT);
+
+ return listener;
+ }
+
+ /**
+ * @param listener Cache listener.
+ */
+ private void unsubscribeToPutEvents(CacheListener listener) {
+ Ignite ignite = grid();
+
+ ignite.events(ignite.cluster().forCacheNodes(null)).stopLocalListen(listener, EVT_CACHE_OBJECT_PUT);
+ }
+
+ /**
+ * @param dataStreamer Ignite Data Streamer.
+ * @return Twitter Streamer.
+ */
+ private TwitterStreamerImpl newStreamerInstance(IgniteDataStreamer<Long, String> dataStreamer) {
+ OAuthSettings oAuthSettings = new OAuthSettings("<dummy>", "<dummy>", "<dummy>", "<dummy>");
+
+ TwitterStreamerImpl streamer = new TwitterStreamerImpl(oAuthSettings);
+
+ streamer.setIgnite(grid());
+ streamer.setStreamer(dataStreamer);
+
+ dataStreamer.allowOverwrite(true);
+ dataStreamer.autoFlushFrequency(10);
+
+ return streamer;
+ }
+
+ /**
+ * Listener.
+ */
+ private class CacheListener implements IgnitePredicate<CacheEvent> {
+
+ /** */
+ private final CountDownLatch latch = new CountDownLatch(CACHE_ENTRY_COUNT);
+
+ /**
+ * @return Latch.
+ */
+ public CountDownLatch getLatch() {
+ return latch;
+ }
+
+ /**
+ * @param evt Cache Event.
+ * @return {@code true}.
+ */
+ @Override
+ public boolean apply(CacheEvent evt) {
+ latch.countDown();
+
+ return true;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTestSuite.java b/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTestSuite.java
new file mode 100644
index 0000000..b458bed
--- /dev/null
+++ b/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/IgniteTwitterStreamerTestSuite.java
@@ -0,0 +1,32 @@
+/*
+ * 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.stream.twitter;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Twitter streamer tests.
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ IgniteTwitterStreamerTest.class
+})
+public class IgniteTwitterStreamerTestSuite {
+
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/TwitterStreamerImpl.java
----------------------------------------------------------------------
diff --git a/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/TwitterStreamerImpl.java b/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/TwitterStreamerImpl.java
new file mode 100644
index 0000000..3c047e0
--- /dev/null
+++ b/modules/twitter/src/test/java/org/apache/ignite/stream/twitter/TwitterStreamerImpl.java
@@ -0,0 +1,79 @@
+/*
+ * 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.stream.twitter;
+
+import com.twitter.hbc.core.Client;
+import com.twitter.hbc.core.HttpHosts;
+import com.twitter.hbc.core.endpoint.StreamingEndpoint;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiTuple;
+import org.apache.ignite.stream.StreamSingleTupleExtractor;
+import twitter4j.Status;
+import twitter4j.TwitterException;
+import twitter4j.TwitterObjectFactory;
+
+/**
+ * Long, String (With Mocked server support) implementation of TwitterStreamer.
+ */
+public class TwitterStreamerImpl extends TwitterStreamer<Long, String> {
+ /** Mocked server support. */
+ HttpHosts hosts;
+
+ /**
+ * @param oAuthSettings OAuth Settings
+ */
+ public TwitterStreamerImpl(OAuthSettings oAuthSettings) {
+ super(oAuthSettings);
+
+ setSingleTupleExtractor(new TwitterStreamSingleTupleExtractorImpl());
+ }
+
+ /**
+ * @param hosts hosts.
+ */
+ public void setHosts(HttpHosts hosts) {
+ this.hosts = hosts;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Client buildClient(BlockingQueue<String> tweetQueue, HttpHosts hosts,
+ StreamingEndpoint endpoint) {
+ return super.buildClient(tweetQueue, this.hosts, endpoint);
+ }
+
+ /**
+ * Long, String Tweet Single Tuple Extractor.
+ */
+ class TwitterStreamSingleTupleExtractorImpl implements StreamSingleTupleExtractor<String, Long, String> {
+ @Override public Map.Entry<Long, String> extract(String tweet) {
+ try {
+ Status status = TwitterObjectFactory.createStatus(tweet);
+
+ return new IgniteBiTuple<>(status.getId(), status.getText());
+ }
+ catch (TwitterException e) {
+ U.error(log, e);
+
+ return null;
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a39681ef/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b9c51b2..1008981 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,7 @@
<module>modules/flume</module>
<module>modules/yarn</module>
<module>modules/jms11</module>
+ <module>modules/twitter</module>
<module>modules/mqtt</module>
<module>modules/zookeeper</module>
<module>modules/camel</module>
[17/23] ignite git commit: IGNITE-426 Implemented failover for
Continuous query.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryAbstractSelfTest.java
index 46a5f8c..5f5dfd4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryAbstractSelfTest.java
@@ -75,6 +75,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.LOCAL;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
import static org.apache.ignite.cache.CacheMode.REPLICATED;
import static org.apache.ignite.cache.CacheRebalanceMode.ASYNC;
@@ -192,12 +193,6 @@ public abstract class GridCacheContinuousQueryAbstractSelfTest extends GridCommo
}
}
- for (int i = 0; i < gridCount(); i++)
- assertEquals("Cache is not empty [entrySet=" + grid(i).cache(null).localEntries() +
- ", i=" + i + ']',
- 0, grid(i).cache(null).localSize());
-
-
for (int i = 0; i < gridCount(); i++) {
GridContinuousProcessor proc = grid(i).context().continuous();
@@ -368,6 +363,114 @@ public abstract class GridCacheContinuousQueryAbstractSelfTest extends GridCommo
/**
* @throws Exception If failed.
*/
+ public void testTwoQueryListener() throws Exception {
+ if (cacheMode() == LOCAL)
+ return;
+
+ IgniteCache<Integer, Integer> cache = grid(0).cache(null);
+ IgniteCache<Integer, Integer> cache1 = grid(1).cache(null);
+
+ final AtomicInteger cntr = new AtomicInteger(0);
+ final AtomicInteger cntr1 = new AtomicInteger(0);
+
+ ContinuousQuery<Integer, Integer> qry1 = new ContinuousQuery<>();
+ ContinuousQuery<Integer, Integer> qry2 = new ContinuousQuery<>();
+
+ qry1.setLocalListener(new CacheEntryUpdatedListener<Integer, Integer>() {
+ @Override public void onUpdated(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
+ for (CacheEntryEvent<? extends Integer, ? extends Integer> ignore : evts)
+ cntr.incrementAndGet();
+ }
+ });
+
+ qry2.setLocalListener(new CacheEntryUpdatedListener<Integer, Integer>() {
+ @Override public void onUpdated(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
+ for (CacheEntryEvent<? extends Integer, ? extends Integer> ignore : evts)
+ cntr1.incrementAndGet();
+ }
+ });
+
+ try (QueryCursor<Cache.Entry<Integer, Integer>> query2 = cache1.query(qry2);
+ QueryCursor<Cache.Entry<Integer, Integer>> query1 = cache.query(qry1)) {
+ for (int i = 0; i < gridCount(); i++) {
+ IgniteCache<Object, Object> cache0 = grid(i).cache(null);
+
+ cache0.put(1, 1);
+ cache0.put(2, 2);
+ cache0.put(3, 3);
+
+ cache0.remove(1);
+ cache0.remove(2);
+ cache0.remove(3);
+
+ final int iter = i + 1;
+
+ assert GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return iter * 6 /* count operation */ * 2 /* count continues queries*/
+ == (cntr.get() + cntr1.get());
+ }
+ }, 5000L);
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRestartQuery() throws Exception {
+ if (cacheMode() == LOCAL)
+ return;
+
+ IgniteCache<Integer, Integer> cache = grid(0).cache(null);
+
+ final int parts = grid(0).affinity(null).partitions();
+
+ final int keyCnt = parts * 2;
+
+ for (int i = 0; i < parts / 2; i++)
+ cache.put(i, i);
+
+ for (int i = 0; i < 10; i++) {
+ if (i % 2 == 0) {
+ final AtomicInteger cntr = new AtomicInteger(0);
+
+ ContinuousQuery<Integer, Integer> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(new CacheEntryUpdatedListener<Integer, Integer>() {
+ @Override public void onUpdated(
+ Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
+ for (CacheEntryEvent<? extends Integer, ? extends Integer> ignore : evts)
+ cntr.incrementAndGet();
+ }
+ });
+
+ QueryCursor<Cache.Entry<Integer, Integer>> query = cache.query(qry);
+
+ for (int key = 0; key < keyCnt; key++)
+ cache.put(key, key);
+
+ try {
+ assert GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return cntr.get() == keyCnt;
+ }
+ }, 2000L);
+ }
+ finally {
+ query.close();
+ }
+ }
+ else {
+ for (int key = 0; key < keyCnt; key++)
+ cache.put(key, key);
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testEntriesByFilter() throws Exception {
IgniteCache<Integer, Integer> cache = grid(0).cache(null);
@@ -852,44 +955,6 @@ public abstract class GridCacheContinuousQueryAbstractSelfTest extends GridCommo
/**
* @throws Exception If failed.
*/
- public void testNodeJoin() throws Exception {
- IgniteCache<Integer, Integer> cache = grid(0).cache(null);
-
- ContinuousQuery<Integer, Integer> qry = new ContinuousQuery<>();
-
- final Collection<CacheEntryEvent<? extends Integer, ? extends Integer>> all = new ConcurrentLinkedDeque8<>();
- final CountDownLatch latch = new CountDownLatch(30);
-
- qry.setLocalListener(new CacheEntryUpdatedListener<Integer, Integer>() {
- @Override public void onUpdated(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
- for (CacheEntryEvent<? extends Integer, ? extends Integer> evt : evts)
- all.add(evt);
-
- latch.countDown();
- }
- });
-
- try (QueryCursor<Cache.Entry<Integer, Integer>> ignored = cache.query(qry)) {
- cache.put(0, 0);
-
- startGrid("anotherGrid");
-
- for (int i = 1; i < 30; i++) {
- cache.put(i, i);
- }
-
- assert latch.await(LATCH_TIMEOUT, MILLISECONDS) : all;
-
- assertEquals(30, all.size());
- }
- finally {
- stopGrid("anotherGrid");
- }
- }
-
- /**
- * @throws Exception If failed.
- */
@SuppressWarnings("TryFinallyCanBeTryWithResources")
public void testNodeJoinWithoutCache() throws Exception {
IgniteCache<Integer, Integer> cache = grid(0).cache(null);
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryTxSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryTxSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryTxSelfTest.java
new file mode 100644
index 0000000..91b6b9c
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/GridCacheContinuousQueryTxSelfTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.query.continuous;
+
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+
+/**
+ * Continuous queries tests for atomic cache.
+ */
+public class GridCacheContinuousQueryTxSelfTest extends GridCacheContinuousQueryPartitionedSelfTest {
+ /** {@inheritDoc} */
+ @Override protected CacheAtomicityMode atomicityMode() {
+ return TRANSACTIONAL;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected CacheMode cacheMode() {
+ return CacheMode.REPLICATED;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected NearCacheConfiguration nearConfiguration() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void testInternalKey() throws Exception {
+ // No-op.
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientReconnectTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientReconnectTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientReconnectTest.java
new file mode 100644
index 0000000..2e1d78d
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientReconnectTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.query.continuous;
+
+import java.util.concurrent.CountDownLatch;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryUpdatedListener;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.query.ContinuousQuery;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteClientReconnectAbstractTest;
+import org.apache.ignite.resources.LoggerResource;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class IgniteCacheContinuousQueryClientReconnectTest extends IgniteClientReconnectAbstractTest {
+ /** {@inheritDoc} */
+ @Override protected int serverCount() {
+ return 4;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected int clientCount() {
+ return 1;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ CacheConfiguration ccfg = new CacheConfiguration();
+
+ ccfg.setCacheMode(PARTITIONED);
+ ccfg.setAtomicityMode(atomicMode());
+ ccfg.setWriteSynchronizationMode(FULL_SYNC);
+
+ cfg.setCacheConfiguration(ccfg);
+
+ return cfg;
+ }
+
+ /**
+ * @return Atomic mode.
+ */
+ protected CacheAtomicityMode atomicMode() {
+ return ATOMIC;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testReconnectClient() throws Exception {
+ Ignite client = grid(serverCount());
+
+ Ignite srv = clientRouter(client);
+
+ assertTrue(client.cluster().localNode().isClient());
+
+ final CacheEventListener lsnr = new CacheEventListener();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ IgniteCache<Object, Object> clnCache = client.cache(null);
+
+ QueryCursor<?> cur = clnCache.query(qry);
+
+ int keyCnt = 100;
+
+ for (int i = 0; i < 10; i++) {
+ lsnr.latch = new CountDownLatch(keyCnt);
+
+ for (int key = 0; key < keyCnt; key++)
+ clnCache.put(key, key);
+
+ assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
+
+ reconnectClientNode(client, srv, null);
+
+ lsnr.latch = new CountDownLatch(keyCnt);
+
+ for (int key = 0; key < keyCnt; key++)
+ clnCache.put(key, key);
+
+ assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
+ }
+
+ cur.close();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testReconnectClientAndLeftRouter() throws Exception {
+ Ignite client = grid(serverCount());
+
+ final Ignite srv = clientRouter(client);
+
+ final String clnRouterName = srv.name();
+
+ assertTrue(client.cluster().localNode().isClient());
+
+ final CacheEventListener lsnr = new CacheEventListener();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ IgniteCache<Object, Object> clnCache = client.cache(null);
+
+ QueryCursor<?> cur = clnCache.query(qry);
+
+ int keyCnt = 100;
+
+ lsnr.latch = new CountDownLatch(keyCnt);
+
+ for (int key = 0; key < keyCnt; key++)
+ clnCache.put(key, key);
+
+ assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
+
+ reconnectClientNode(client, srv, new Runnable() {
+ @Override public void run() {
+ stopGrid(clnRouterName);
+ }
+ });
+
+ assertFalse("Client connected to the same server node.", clnRouterName.equals(clientRouter(client).name()));
+
+ lsnr.latch = new CountDownLatch(keyCnt);
+
+ for (int key = 0; key < keyCnt; key++)
+ clnCache.put(key, key);
+
+ assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
+
+ cur.close();
+ }
+
+ /**
+ *
+ */
+ private static class CacheEventListener implements CacheEntryUpdatedListener<Object, Object> {
+ /** */
+ private volatile CountDownLatch latch = new CountDownLatch(1);
+
+ /** */
+ @LoggerResource
+ private IgniteLogger log;
+
+ /** {@inheritDoc} */
+ @Override public void onUpdated(Iterable<CacheEntryEvent<?, ?>> evts) {
+ for (CacheEntryEvent<?, ?> evt : evts) {
+ log.info("Received cache event: " + evt);
+
+ latch.countDown();
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTest.java
index 1afeb05..534f298 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTest.java
@@ -27,11 +27,13 @@ import org.apache.ignite.cache.query.ContinuousQuery;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.lang.IgniteOutClosure;
import org.apache.ignite.resources.LoggerResource;
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 java.util.concurrent.TimeUnit.SECONDS;
@@ -83,11 +85,13 @@ public class IgniteCacheContinuousQueryClientTest extends GridCommonAbstractTest
client = true;
- Ignite clientNode = startGrid(3);
+ final int CLIENT_ID = 3;
+
+ Ignite clientNode = startGrid(CLIENT_ID);
client = false;
- CacheEventListener lsnr = new CacheEventListener();
+ final CacheEventListener lsnr = new CacheEventListener();
ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
@@ -95,27 +99,154 @@ public class IgniteCacheContinuousQueryClientTest extends GridCommonAbstractTest
QueryCursor<?> cur = clientNode.cache(null).query(qry);
- Ignite joined1 = startGrid(4);
+ for (int i = 0; i < 10; i++) {
+ log.info("Start iteration: " + i);
+
+ lsnr.latch = new CountDownLatch(1);
+
+ Ignite joined1 = startGrid(4);
+
+ IgniteCache<Object, Object> joinedCache1 = joined1.cache(null);
+
+ joinedCache1.put(primaryKey(joinedCache1), 1);
+
+ assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
+
+ lsnr.latch = new CountDownLatch(1);
+
+ Ignite joined2 = startGrid(5);
+
+ IgniteCache<Object, Object> joinedCache2 = joined2.cache(null);
- IgniteCache<Object, Object> joinedCache1 = joined1.cache(null);
+ joinedCache2.put(primaryKey(joinedCache2), 2);
- joinedCache1.put(primaryKey(joinedCache1), 1);
+ assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
- assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
+ stopGrid(4);
+
+ stopGrid(5);
+ }
cur.close();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testNodeJoinsRestartQuery() throws Exception {
+ startGrids(2);
+
+ client = true;
+
+ final int CLIENT_ID = 3;
+
+ Ignite clientNode = startGrid(CLIENT_ID);
+
+ client = false;
+
+ for (int i = 0; i < 10; i++) {
+ log.info("Start iteration: " + i);
+
+ final CacheEventListener lsnr = new CacheEventListener();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ QueryCursor<?> cur = clientNode.cache(null).query(qry);
+
+ lsnr.latch = new CountDownLatch(1);
+
+ Ignite joined1 = startGrid(4);
+
+ IgniteCache<Object, Object> joinedCache1 = joined1.cache(null);
+
+ joinedCache1.put(primaryKey(joinedCache1), 1);
+
+ assertTrue("Failed to wait for event.", lsnr.latch.await(5, SECONDS));
+
+ cur.close();
- lsnr.latch = new CountDownLatch(1);
+ lsnr.latch = new CountDownLatch(1);
- Ignite joined2 = startGrid(5);
+ Ignite joined2 = startGrid(5);
- IgniteCache<Object, Object> joinedCache2 = joined2.cache(null);
+ IgniteCache<Object, Object> joinedCache2 = joined2.cache(null);
- joinedCache2.put(primaryKey(joinedCache2), 2);
+ joinedCache2.put(primaryKey(joinedCache2), 2);
- U.sleep(1000);
+ assertFalse("Unexpected event received.", GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return 1 != lsnr.latch.getCount();
+ }
+ }, 1000));
- assertEquals("Unexpected event received.", 1, lsnr.latch.getCount());
+ stopGrid(4);
+
+ stopGrid(5);
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testServerNodeLeft() throws Exception {
+ startGrids(3);
+
+ client = true;
+
+ final int CLIENT_ID = 3;
+
+ Ignite clnNode = startGrid(CLIENT_ID);
+
+ client = false;
+
+ IgniteOutClosure<IgniteCache<Integer, Integer>> rndCache =
+ new IgniteOutClosure<IgniteCache<Integer, Integer>>() {
+ int cnt = 0;
+
+ @Override public IgniteCache<Integer, Integer> apply() {
+ ++cnt;
+
+ return grid(CLIENT_ID).cache(null);
+ }
+ };
+
+ final CacheEventListener lsnr = new CacheEventListener();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ QueryCursor<?> cur = clnNode.cache(null).query(qry);
+
+ boolean first = true;
+
+ int keyCnt = 1;
+
+ for (int i = 0; i < 10; i++) {
+ log.info("Start iteration: " + i);
+
+ if (first)
+ first = false;
+ else {
+ for (int srv = 0; srv < CLIENT_ID - 1; srv++)
+ startGrid(srv);
+ }
+
+ lsnr.latch = new CountDownLatch(keyCnt);
+
+ for (int key = 0; key < keyCnt; key++)
+ rndCache.apply().put(key, key);
+
+ assertTrue("Failed to wait for event. Left events: " + lsnr.latch.getCount(),
+ lsnr.latch.await(10, SECONDS));
+
+ for (int srv = 0; srv < CLIENT_ID - 1; srv++)
+ stopGrid(srv);
+ }
+
+ cur.close();
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTxReconnectTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTxReconnectTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTxReconnectTest.java
new file mode 100644
index 0000000..a10ebc9
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/IgniteCacheContinuousQueryClientTxReconnectTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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.query.continuous;
+
+import org.apache.ignite.cache.CacheAtomicityMode;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+
+/**
+ *
+ */
+public class IgniteCacheContinuousQueryClientTxReconnectTest extends IgniteCacheContinuousQueryClientReconnectTest {
+ /** {@inheritDoc} */
+ @Override protected CacheAtomicityMode atomicMode() {
+ return TRANSACTIONAL;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PSameClassLoaderSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PSameClassLoaderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PSameClassLoaderSelfTest.java
index 108b11d..ba5e15b 100644
--- a/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PSameClassLoaderSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PSameClassLoaderSelfTest.java
@@ -23,7 +23,11 @@ import java.net.URLClassLoader;
import org.apache.ignite.Ignite;
import org.apache.ignite.configuration.DeploymentMode;
import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.PA;
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.config.GridTestProperties;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.testframework.junits.common.GridCommonTest;
@@ -41,6 +45,9 @@ public class GridP2PSameClassLoaderSelfTest extends GridCommonAbstractTest {
private static final String TEST_TASK2_NAME = "org.apache.ignite.tests.p2p.P2PTestTaskExternalPath2";
/** */
+ private static final TcpDiscoveryIpFinder FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
private static final ClassLoader CLASS_LOADER;
/** Current deployment mode. Used in {@link #getConfiguration(String)}. */
@@ -66,6 +73,7 @@ public class GridP2PSameClassLoaderSelfTest extends GridCommonAbstractTest {
cfg.setDeploymentMode(depMode);
((TcpDiscoverySpi)cfg.getDiscoverySpi()).setHeartbeatFrequency(500);
+ ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(FINDER);
cfg.setCacheConfiguration();
@@ -81,10 +89,16 @@ public class GridP2PSameClassLoaderSelfTest extends GridCommonAbstractTest {
@SuppressWarnings({"unchecked"})
private void processTest(boolean isIsolatedDifferentTask, boolean isIsolatedDifferentNode) throws Exception {
try {
- Ignite ignite1 = startGrid(1);
+ final Ignite ignite1 = startGrid(1);
Ignite ignite2 = startGrid(2);
Ignite ignite3 = startGrid(3);
+ assert GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return ignite1.cluster().nodes().size() == 3;
+ }
+ }, 20000L);
+
Class task1 = CLASS_LOADER.loadClass(TEST_TASK1_NAME);
Class task2 = CLASS_LOADER.loadClass(TEST_TASK2_NAME);
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
index 3e41979..6f9c559 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
@@ -1248,7 +1248,7 @@ public abstract class GridAbstractTest extends TestCase {
if (isDebug()) {
discoSpi.setMaxMissedHeartbeats(Integer.MAX_VALUE);
- cfg.setNetworkTimeout(Long.MAX_VALUE);
+ cfg.setNetworkTimeout(Long.MAX_VALUE / 3);
}
else {
// Set network timeout to 10 sec to avoid unexpected p2p class loading errors.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 c19e718..e0ffc60 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
@@ -431,6 +431,9 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
for (IgniteCacheProxy<?, ?> c : g0.context().cache().jcaches()) {
CacheConfiguration cfg = c.context().config();
+ if (cfg == null)
+ continue;
+
if (cfg.getCacheMode() == PARTITIONED &&
cfg.getRebalanceMode() != NONE &&
g.cluster().nodes().size() > 1) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 6cb1a52..6cc2599 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -65,6 +65,10 @@ import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalAtomicQ
import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalFieldsQuerySelfTest;
import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalQuerySelfTest;
import org.apache.ignite.internal.processors.cache.query.GridCacheSwapScanQuerySelfTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicReplicatedSelfTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxReplicatedSelfTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxSelfTest;
import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicNearEnabledSelfTest;
import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicP2PDisabledSelfTest;
import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicSelfTest;
@@ -77,7 +81,10 @@ import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheCon
import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedOneNodeSelfTest;
import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedP2PDisabledSelfTest;
import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedSelfTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryTxSelfTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientReconnectTest;
import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientTest;
+import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientTxReconnectTest;
import org.apache.ignite.internal.processors.cache.reducefields.GridCacheReduceFieldsQueryAtomicSelfTest;
import org.apache.ignite.internal.processors.cache.reducefields.GridCacheReduceFieldsQueryLocalSelfTest;
import org.apache.ignite.internal.processors.cache.reducefields.GridCacheReduceFieldsQueryPartitionedSelfTest;
@@ -157,11 +164,18 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
suite.addTestSuite(GridCacheContinuousQueryPartitionedSelfTest.class);
suite.addTestSuite(GridCacheContinuousQueryPartitionedOnlySelfTest.class);
suite.addTestSuite(GridCacheContinuousQueryPartitionedP2PDisabledSelfTest.class);
+ suite.addTestSuite(GridCacheContinuousQueryTxSelfTest.class);
suite.addTestSuite(GridCacheContinuousQueryAtomicSelfTest.class);
suite.addTestSuite(GridCacheContinuousQueryAtomicNearEnabledSelfTest.class);
suite.addTestSuite(GridCacheContinuousQueryAtomicP2PDisabledSelfTest.class);
- suite.addTestSuite(IgniteCacheContinuousQueryClientTest.class);
suite.addTestSuite(GridCacheContinuousQueryReplicatedOneNodeSelfTest.class);
+ suite.addTestSuite(IgniteCacheContinuousQueryClientTest.class);
+ suite.addTestSuite(IgniteCacheContinuousQueryClientReconnectTest.class);
+ suite.addTestSuite(IgniteCacheContinuousQueryClientTxReconnectTest.class);
+ suite.addTestSuite(CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest.class);
+ suite.addTestSuite(CacheContinuousQueryFailoverAtomicReplicatedSelfTest.class);
+ suite.addTestSuite(CacheContinuousQueryFailoverTxSelfTest.class);
+ suite.addTestSuite(CacheContinuousQueryFailoverTxReplicatedSelfTest.class);
// Reduce fields queries.
suite.addTestSuite(GridCacheReduceFieldsQueryLocalSelfTest.class);
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/CacheEntryEventProbe.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/CacheEntryEventProbe.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/CacheEntryEventProbe.java
new file mode 100644
index 0000000..e42479a
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/CacheEntryEventProbe.java
@@ -0,0 +1,156 @@
+/*
+ * 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.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.CacheEntryUpdatedListener;
+import org.apache.ignite.cache.query.ContinuousQuery;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.yardstickframework.BenchmarkConfiguration;
+import org.yardstickframework.BenchmarkDriver;
+import org.yardstickframework.BenchmarkProbe;
+import org.yardstickframework.BenchmarkProbePoint;
+
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.yardstickframework.BenchmarkUtils.errorHelp;
+import static org.yardstickframework.BenchmarkUtils.println;
+
+/**
+ * Probe which calculate continuous query events.
+ */
+public class CacheEntryEventProbe implements BenchmarkProbe {
+ /** */
+ private BenchmarkConfiguration cfg;
+
+ /** Counter. */
+ private AtomicLong cnt = new AtomicLong(0);
+
+ /** Collected points. */
+ private Collection<BenchmarkProbePoint> collected = new ArrayList<>();
+
+ /** Query cursor. */
+ private QueryCursor qryCur;
+
+ /** Service building probe points. */
+ private ExecutorService buildingService;
+
+ /** {@inheritDoc} */
+ @Override public void start(BenchmarkDriver drv, BenchmarkConfiguration cfg) throws Exception {
+ this.cfg = cfg;
+
+ if (drv instanceof IgniteCacheAbstractBenchmark) {
+ IgniteCacheAbstractBenchmark drv0 = (IgniteCacheAbstractBenchmark)drv;
+
+ if (drv0.cache() != null) {
+ ContinuousQuery<Integer, Integer> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(new CacheEntryUpdatedListener<Integer, Integer>() {
+ @Override public void onUpdated(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>>
+ events) throws CacheEntryListenerException {
+ int size = 0;
+
+ for (CacheEntryEvent<? extends Integer, ? extends Integer> e : events)
+ ++size;
+
+ cnt.addAndGet(size);
+ }
+ });
+
+ qryCur = drv0.cache().query(qry);
+
+ buildingService = Executors.newSingleThreadExecutor();
+
+ buildingService.submit(new Runnable() {
+ @Override public void run() {
+ try {
+ while (!Thread.currentThread().isInterrupted()) {
+ Thread.sleep(1000);
+
+ long evts = cnt.getAndSet(0);
+
+ BenchmarkProbePoint pnt = new BenchmarkProbePoint(
+ TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()),
+ new double[] {evts});
+
+ collectPoint(pnt);
+ }
+ }
+ catch (InterruptedException e) {
+ // No-op.
+ }
+ }
+ });
+
+ println(cfg, getClass().getSimpleName() + " probe is started.");
+ }
+ }
+
+ if (qryCur == null)
+ errorHelp(cfg, "Can not start " + getClass().getSimpleName()
+ + " probe. Probably, the driver doesn't provide \"cache()\" method.");
+ }
+
+ /** {@inheritDoc} */
+ @Override public void stop() throws Exception {
+ if (qryCur != null) {
+ qryCur.close();
+
+ qryCur = null;
+
+ buildingService.shutdownNow();
+
+ buildingService.awaitTermination(1, MINUTES);
+
+ println(cfg, getClass().getSimpleName() + " is stopped.");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<String> metaInfo() {
+ return Arrays.asList("Time, sec", "Received events/sec (more is better)");
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized Collection<BenchmarkProbePoint> points() {
+ Collection<BenchmarkProbePoint> ret = collected;
+
+ collected = new ArrayList<>(ret.size() + 5);
+
+ return ret;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void buildPoint(long time) {
+ // No-op.
+ }
+
+ /**
+ * @param pnt Probe point.
+ */
+ private synchronized void collectPoint(BenchmarkProbePoint pnt) {
+ collected.add(pnt);
+ }
+}
[15/23] ignite git commit: Merge remote-tracking branch
'apache/ignite-1.5' into ignite-1.5
Posted by sb...@apache.org.
Merge remote-tracking branch 'apache/ignite-1.5' into ignite-1.5
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c85d1f5f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c85d1f5f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c85d1f5f
Branch: refs/heads/ignite-sql-opt
Commit: c85d1f5fed821d0fa5e354d19d7da3fd7f9ac87c
Parents: 96483be f708c1a
Author: ashutak <as...@gridgain.com>
Authored: Thu Nov 19 19:32:31 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Thu Nov 19 19:32:31 2015 +0300
----------------------------------------------------------------------
modules/camel/README.txt | 34 +
modules/camel/licenses/apache-2.0.txt | 202 ++++++
modules/camel/pom.xml | 102 +++
.../ignite/stream/camel/CamelStreamer.java | 237 +++++++
.../stream/camel/IgniteCamelStreamerTest.java | 420 +++++++++++
.../camel/IgniteCamelStreamerTestSuite.java | 48 ++
.../src/test/resources/camel.test.properties | 18 +
.../ignite/codegen/MessageCodeGenerator.java | 11 +-
.../java/org/apache/ignite/IgniteCache.java | 3 +-
.../java/org/apache/ignite/IgniteCompute.java | 3 +-
.../org/apache/ignite/compute/ComputeJob.java | 2 +-
.../ignite/internal/GridUpdateNotifier.java | 2 +-
.../communication/GridIoMessageFactory.java | 18 +
.../discovery/GridDiscoveryManager.java | 2 +-
.../processors/cache/GridCacheAdapter.java | 103 ++-
.../processors/cache/GridCacheAtomicFuture.java | 6 +
.../cache/GridCacheDeploymentManager.java | 2 +-
.../processors/cache/GridCacheFuture.java | 13 -
.../processors/cache/GridCacheGateway.java | 1 -
.../processors/cache/GridCacheIoManager.java | 50 +-
.../processors/cache/GridCacheMessage.java | 20 +-
.../processors/cache/GridCacheMvcc.java | 7 -
.../processors/cache/GridCacheMvccFuture.java | 7 +
.../processors/cache/GridCacheMvccManager.java | 150 ++--
.../GridCachePartitionExchangeManager.java | 55 +-
.../cache/GridCacheSharedContext.java | 7 +-
.../processors/cache/IgniteCacheProxy.java | 3 +
.../distributed/GridCacheTxRecoveryFuture.java | 54 +-
.../distributed/GridDistributedBaseMessage.java | 56 --
.../distributed/GridDistributedLockRequest.java | 6 -
.../GridDistributedLockResponse.java | 32 +-
.../GridDistributedTxPrepareRequest.java | 67 +-
.../dht/CacheDistributedGetFutureAdapter.java | 27 +-
.../cache/distributed/dht/CacheGetFuture.java | 32 +
.../distributed/dht/GridDhtCacheAdapter.java | 141 ++++
.../distributed/dht/GridDhtLockFuture.java | 79 ++-
.../distributed/dht/GridDhtLockRequest.java | 2 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 14 +-
.../distributed/dht/GridDhtTxFinishFuture.java | 24 +-
.../cache/distributed/dht/GridDhtTxLocal.java | 4 +-
.../distributed/dht/GridDhtTxLocalAdapter.java | 9 +
.../distributed/dht/GridDhtTxPrepareFuture.java | 77 +-
.../dht/GridDhtTxPrepareRequest.java | 54 +-
.../dht/GridPartitionedGetFuture.java | 69 +-
.../dht/GridPartitionedSingleGetFuture.java | 697 +++++++++++++++++++
.../dht/atomic/GridDhtAtomicCache.java | 127 +++-
.../dht/atomic/GridDhtAtomicUpdateFuture.java | 84 +--
.../dht/atomic/GridDhtAtomicUpdateRequest.java | 11 +
.../dht/atomic/GridNearAtomicUpdateFuture.java | 5 -
.../dht/colocated/GridDhtColocatedCache.java | 162 ++++-
.../colocated/GridDhtColocatedLockFuture.java | 81 ++-
.../distributed/near/CacheVersionedValue.java | 2 +-
.../distributed/near/GridNearCacheAdapter.java | 4 +-
.../distributed/near/GridNearGetFuture.java | 57 +-
.../distributed/near/GridNearGetRequest.java | 1 -
.../distributed/near/GridNearGetResponse.java | 2 -
.../distributed/near/GridNearLockFuture.java | 72 +-
.../distributed/near/GridNearLockRequest.java | 4 +-
...arOptimisticSerializableTxPrepareFuture.java | 108 +--
.../near/GridNearOptimisticTxPrepareFuture.java | 69 +-
.../GridNearPessimisticTxPrepareFuture.java | 58 +-
.../near/GridNearSingleGetRequest.java | 396 +++++++++++
.../near/GridNearSingleGetResponse.java | 321 +++++++++
.../near/GridNearTransactionalCache.java | 9 +-
.../near/GridNearTxFinishFuture.java | 42 +-
.../cache/distributed/near/GridNearTxLocal.java | 164 +++--
.../near/GridNearTxPrepareFutureAdapter.java | 20 +-
.../near/GridNearTxPrepareRequest.java | 52 +-
.../processors/cache/local/GridLocalCache.java | 4 +-
.../cache/local/GridLocalLockFuture.java | 5 -
.../cache/transactions/IgniteInternalTx.java | 1 +
.../cache/transactions/IgniteTxAdapter.java | 1 +
.../cache/transactions/IgniteTxEntry.java | 9 +-
.../cache/transactions/IgniteTxHandler.java | 19 +-
.../IgniteTxImplicitSingleStateImpl.java | 7 +
.../transactions/IgniteTxLocalAdapter.java | 14 +-
.../cache/transactions/IgniteTxManager.java | 3 +-
.../IgniteTxRemoteStateAdapter.java | 5 +
.../cache/transactions/IgniteTxState.java | 6 +
.../cache/transactions/IgniteTxStateImpl.java | 69 +-
.../clock/GridClockSyncProcessor.java | 28 +-
.../internal/util/UUIDCollectionMessage.java | 114 +++
.../util/future/GridCompoundFuture.java | 15 +-
.../ignite/internal/util/lang/GridFunc.java | 8 +-
.../ignite/internal/util/nio/GridNioServer.java | 13 +-
.../ignite/marshaller/MarshallerExclusions.java | 4 +-
.../org/apache/ignite/stream/StreamAdapter.java | 19 +-
.../IgniteClientReconnectCacheTest.java | 11 +-
.../cache/GridCacheAbstractFullApiSelfTest.java | 75 ++
.../GridCacheConcurrentTxMultiNodeTest.java | 15 -
.../cache/GridCachePartitionedGetSelfTest.java | 3 +-
.../IgniteCacheAbstractStopBusySelfTest.java | 27 +-
.../IgniteCacheP2pUnmarshallingErrorTest.java | 184 +++--
.../CacheGetFutureHangsSelfTest.java | 6 +
.../GridCacheAbstractNodeRestartSelfTest.java | 2 +
.../IgniteCacheSingleGetMessageTest.java | 357 ++++++++++
.../GridCacheReplicatedMetricsSelfTest.java | 9 -
.../IgniteCacheTxStoreSessionTest.java | 2 +-
.../testsuites/IgniteCacheTestSuite3.java | 2 +
.../testsuites/IgniteCacheTestSuite4.java | 3 +
modules/flume/README.md | 40 --
modules/flume/README.txt | 72 ++
modules/flume/licenses/apache-2.0.txt | 202 ++++++
modules/twitter/README.txt | 32 +
modules/twitter/licenses/apache-2.0.txt | 202 ++++++
modules/twitter/pom.xml | 122 ++++
.../ignite/stream/twitter/OAuthSettings.java | 86 +++
.../ignite/stream/twitter/TwitterStreamer.java | 295 ++++++++
.../twitter/IgniteTwitterStreamerTest.java | 234 +++++++
.../twitter/IgniteTwitterStreamerTestSuite.java | 32 +
.../stream/twitter/TwitterStreamerImpl.java | 79 +++
pom.xml | 2 +
112 files changed, 6152 insertions(+), 1107 deletions(-)
----------------------------------------------------------------------
[06/23] ignite git commit: IGNITE-530 pom.xml fix
Posted by sb...@apache.org.
IGNITE-530 pom.xml fix
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ba1d563a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ba1d563a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ba1d563a
Branch: refs/heads/ignite-sql-opt
Commit: ba1d563ae04b6e3a30fcfb2b89456f6fcd36d246
Parents: a39681e
Author: Anton Vinogradov <av...@apache.org>
Authored: Thu Nov 19 15:53:03 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Thu Nov 19 15:53:03 2015 +0300
----------------------------------------------------------------------
modules/twitter/pom.xml | 6 ++++++
1 file changed, 6 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/ba1d563a/modules/twitter/pom.xml
----------------------------------------------------------------------
diff --git a/modules/twitter/pom.xml b/modules/twitter/pom.xml
index 21e6f51..6c02935 100644
--- a/modules/twitter/pom.xml
+++ b/modules/twitter/pom.xml
@@ -41,17 +41,20 @@
<artifactId>ignite-core</artifactId>
<version>${project.version}</version>
</dependency>
+
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-log4j</artifactId>
<version>${project.version}</version>
</dependency>
+
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
@@ -59,11 +62,13 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>com.twitter</groupId>
<artifactId>hbc-twitter4j</artifactId>
<version>2.2.0</version>
</dependency>
+
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
@@ -111,6 +116,7 @@
<artifactId>jopt-simple</artifactId>
</exclusion>
</exclusions>
+ <scope>test</scope>
</dependency>
</dependencies>
</project>
[12/23] ignite git commit: Merge remote-tracking branch
'origin/ignite-1.5' into ignite-1.5
Posted by sb...@apache.org.
Merge remote-tracking branch 'origin/ignite-1.5' into ignite-1.5
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e369e1fe
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e369e1fe
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e369e1fe
Branch: refs/heads/ignite-sql-opt
Commit: e369e1fe797ac3309cf3eee74a7bacd3c1ad0565
Parents: dae3de0 f0db0d9
Author: Anton Vinogradov <av...@apache.org>
Authored: Thu Nov 19 17:42:40 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Thu Nov 19 17:42:40 2015 +0300
----------------------------------------------------------------------
.../java/org/apache/ignite/IgniteCache.java | 3 +-
.../java/org/apache/ignite/IgniteCompute.java | 3 +-
.../org/apache/ignite/compute/ComputeJob.java | 2 +-
.../communication/GridIoMessageFactory.java | 12 +
.../processors/cache/GridCacheAdapter.java | 103 ++-
.../processors/cache/GridCacheAtomicFuture.java | 6 +
.../processors/cache/GridCacheFuture.java | 13 -
.../processors/cache/GridCacheIoManager.java | 50 +-
.../processors/cache/GridCacheMessage.java | 20 +-
.../processors/cache/GridCacheMvccFuture.java | 7 +
.../processors/cache/GridCacheMvccManager.java | 108 +--
.../distributed/GridCacheTxRecoveryFuture.java | 13 +-
.../dht/CacheDistributedGetFutureAdapter.java | 27 +-
.../cache/distributed/dht/CacheGetFuture.java | 32 +
.../distributed/dht/GridDhtCacheAdapter.java | 141 ++++
.../distributed/dht/GridDhtLockFuture.java | 16 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 9 +-
.../distributed/dht/GridDhtTxFinishFuture.java | 24 +-
.../cache/distributed/dht/GridDhtTxLocal.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 17 +-
.../dht/GridPartitionedGetFuture.java | 69 +-
.../dht/GridPartitionedSingleGetFuture.java | 697 +++++++++++++++++++
.../dht/atomic/GridDhtAtomicCache.java | 127 +++-
.../dht/atomic/GridDhtAtomicUpdateFuture.java | 84 +--
.../dht/atomic/GridDhtAtomicUpdateRequest.java | 11 +
.../dht/atomic/GridNearAtomicUpdateFuture.java | 5 -
.../dht/colocated/GridDhtColocatedCache.java | 160 ++++-
.../colocated/GridDhtColocatedLockFuture.java | 26 +-
.../distributed/near/CacheVersionedValue.java | 2 +-
.../distributed/near/GridNearCacheAdapter.java | 4 +-
.../distributed/near/GridNearGetFuture.java | 57 +-
.../distributed/near/GridNearGetRequest.java | 1 -
.../distributed/near/GridNearGetResponse.java | 2 -
.../distributed/near/GridNearLockFuture.java | 16 +-
...arOptimisticSerializableTxPrepareFuture.java | 17 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 19 +-
.../GridNearPessimisticTxPrepareFuture.java | 19 +-
.../near/GridNearSingleGetRequest.java | 396 +++++++++++
.../near/GridNearSingleGetResponse.java | 321 +++++++++
.../near/GridNearTransactionalCache.java | 2 +-
.../near/GridNearTxFinishFuture.java | 24 +-
.../cache/distributed/near/GridNearTxLocal.java | 149 ++--
.../near/GridNearTxPrepareFutureAdapter.java | 6 +-
.../processors/cache/local/GridLocalCache.java | 4 +-
.../cache/local/GridLocalLockFuture.java | 5 -
.../cache/transactions/IgniteTxHandler.java | 19 +-
.../transactions/IgniteTxLocalAdapter.java | 2 +-
.../cache/transactions/IgniteTxManager.java | 2 +-
.../ignite/marshaller/MarshallerExclusions.java | 4 +-
.../IgniteClientReconnectCacheTest.java | 11 +-
.../cache/GridCacheAbstractFullApiSelfTest.java | 75 ++
.../GridCacheConcurrentTxMultiNodeTest.java | 15 -
.../cache/GridCachePartitionedGetSelfTest.java | 3 +-
.../IgniteCacheAbstractStopBusySelfTest.java | 27 +-
.../IgniteCacheP2pUnmarshallingErrorTest.java | 184 +++--
.../CacheGetFutureHangsSelfTest.java | 6 +
.../GridCacheAbstractNodeRestartSelfTest.java | 2 +
.../IgniteCacheSingleGetMessageTest.java | 357 ++++++++++
.../GridCacheReplicatedMetricsSelfTest.java | 9 -
.../testsuites/IgniteCacheTestSuite4.java | 3 +
60 files changed, 2915 insertions(+), 637 deletions(-)
----------------------------------------------------------------------
[08/23] ignite git commit: Optimization for single key cache 'get'
operation.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
new file mode 100644
index 0000000..8f2357b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
@@ -0,0 +1,697 @@
+/*
+ * 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.LinkedHashMap;
+import java.util.List;
+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.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheObject;
+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.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.near.CacheVersionedValue;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+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.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.IgniteProductVersion;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class GridPartitionedSingleGetFuture extends GridFutureAdapter<Object> implements GridCacheFuture<Object>,
+ CacheGetFuture {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ public static final IgniteProductVersion SINGLE_GET_MSG_SINCE = IgniteProductVersion.fromString("1.5.0");
+
+ /** Logger reference. */
+ private static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
+
+ /** Logger. */
+ private static IgniteLogger log;
+
+ /** Topology version. */
+ private AffinityTopologyVersion topVer;
+
+ /** Context. */
+ private final GridCacheContext cctx;
+
+ /** Key. */
+ private final KeyCacheObject key;
+
+ /** Read through flag. */
+ private final boolean readThrough;
+
+ /** Force primary flag. */
+ private final boolean forcePrimary;
+
+ /** Future ID. */
+ private final IgniteUuid futId;
+
+ /** Trackable flag. */
+ private boolean trackable;
+
+ /** Subject ID. */
+ private final UUID subjId;
+
+ /** Task name. */
+ private final 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 final boolean needVer;
+
+ /** */
+ private final boolean keepCacheObjects;
+
+ /** */
+ private ClusterNode node;
+
+ /**
+ * @param cctx Context.
+ * @param key Key.
+ * @param topVer Topology version.
+ * @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.
+ */
+ public GridPartitionedSingleGetFuture(
+ GridCacheContext cctx,
+ KeyCacheObject key,
+ AffinityTopologyVersion topVer,
+ boolean readThrough,
+ boolean forcePrimary,
+ @Nullable UUID subjId,
+ String taskName,
+ boolean deserializePortable,
+ @Nullable IgniteCacheExpiryPolicy expiryPlc,
+ boolean skipVals,
+ boolean canRemap,
+ boolean needVer,
+ boolean keepCacheObjects
+ ) {
+ assert key != null;
+
+ this.cctx = cctx;
+ this.key = key;
+ 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;
+ this.topVer = topVer;
+
+ futId = IgniteUuid.randomUuid();
+
+ if (log == null)
+ log = U.logger(cctx.kernalContext(), logRef, GridPartitionedSingleGetFuture.class);
+ }
+
+ /**
+ *
+ */
+ public void init() {
+ AffinityTopologyVersion topVer = this.topVer.topologyVersion() > 0 ? this.topVer :
+ canRemap ? cctx.affinity().affinityTopologyVersion() : cctx.shared().exchange().readyAffinityVersion();
+
+ map(topVer);
+ }
+
+ /**
+ * @param topVer Topology version.
+ */
+ @SuppressWarnings("unchecked")
+ private void map(AffinityTopologyVersion topVer) {
+ this.topVer = topVer;
+
+ ClusterNode node = mapKeyToNode(topVer);
+
+ if (node == null) {
+ assert isDone() : this;
+
+ return;
+ }
+
+ if (node.isLocal()) {
+ LinkedHashMap<KeyCacheObject, Boolean> map = U.newLinkedHashMap(1);
+
+ map.put(key, false);
+
+ final GridDhtFuture<Collection<GridCacheEntryInfo>> fut = cctx.dht().getDhtAsync(node.id(),
+ -1,
+ map,
+ readThrough,
+ topVer,
+ subjId,
+ taskName == null ? 0 : taskName.hashCode(),
+ expiryPlc,
+ skipVals);
+
+ final Collection<Integer> invalidParts = fut.invalidPartitions();
+
+ if (!F.isEmpty(invalidParts)) {
+ AffinityTopologyVersion updTopVer = cctx.discovery().topologyVersionEx();
+
+ assert updTopVer.compareTo(topVer) > 0 : "Got invalid partitions for local node but topology " +
+ "version did not change [topVer=" + topVer + ", updTopVer=" + updTopVer +
+ ", invalidParts=" + invalidParts + ']';
+
+ // Remap recursively.
+ map(updTopVer);
+ }
+ else {
+ fut.listen(new CI1<IgniteInternalFuture<Collection<GridCacheEntryInfo>>>() {
+ @Override public void apply(IgniteInternalFuture<Collection<GridCacheEntryInfo>> fut) {
+ try {
+ Collection<GridCacheEntryInfo> infos = fut.get();
+
+ assert F.isEmpty(infos) || infos.size() == 1 : infos;
+
+ setResult(F.first(infos));
+ }
+ catch (Exception e) {
+ U.error(log, "Failed to get values from dht cache [fut=" + fut + "]", e);
+
+ onDone(e);
+ }
+ }
+ });
+ }
+ }
+ else {
+ synchronized (this) {
+ this.node = node;
+ }
+
+ if (!trackable) {
+ trackable = true;
+
+ cctx.mvcc().addFuture(this, futId);
+ }
+
+ GridCacheMessage req;
+
+ if (node.version().compareTo(SINGLE_GET_MSG_SINCE) >= 0) {
+ req = new GridNearSingleGetRequest(cctx.cacheId(),
+ futId,
+ key,
+ readThrough,
+ topVer,
+ subjId,
+ taskName == null ? 0 : taskName.hashCode(),
+ expiryPlc != null ? expiryPlc.forAccess() : -1L,
+ skipVals,
+ /**add reader*/false,
+ needVer,
+ cctx.deploymentEnabled());
+ }
+ else {
+ LinkedHashMap<KeyCacheObject, Boolean> map = U.newLinkedHashMap(1);
+
+ map.put(key, false);
+
+ req = new GridNearGetRequest(
+ cctx.cacheId(),
+ futId,
+ futId,
+ cctx.versions().next(),
+ map,
+ readThrough,
+ topVer,
+ subjId,
+ taskName == null ? 0 : taskName.hashCode(),
+ expiryPlc != null ? expiryPlc.forAccess() : -1L,
+ skipVals,
+ cctx.deploymentEnabled());
+ }
+
+ try {
+ cctx.io().send(node, req, cctx.ioPolicy());
+ }
+ catch (IgniteCheckedException e) {
+ if (e instanceof ClusterTopologyCheckedException)
+ onNodeLeft(node.id());
+ else
+ onDone(e);
+ }
+ }
+ }
+
+ /**
+ * @param topVer Topology version.
+ * @return Primary node or {@code null} if future was completed.
+ */
+ @Nullable private ClusterNode mapKeyToNode(AffinityTopologyVersion topVer) {
+ ClusterNode primary = affinityNode(key, topVer);
+
+ if (primary == null) {
+ onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache " +
+ "(all partition nodes left the grid) [topVer=" + topVer + ", cache=" + cctx.name() + ']'));
+
+ return null;
+ }
+
+ boolean allowLocRead = (cctx.affinityNode() && !forcePrimary) || primary.isLocal();
+
+ if (allowLocRead) {
+ GridDhtCacheAdapter colocated = cctx.dht();
+
+ while (true) {
+ GridCacheEntryEx entry;
+
+ try {
+ entry = colocated.context().isSwapOrOffheapEnabled() ? colocated.entryEx(key) :
+ colocated.peekEx(key);
+
+ // If our DHT cache do has value, then we peek it.
+ if (entry != null) {
+ boolean isNew = entry.isNewLocked();
+
+ 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);
+
+ // Entry was not in memory or in swap, so we remove it from cache.
+ if (v == null) {
+ if (isNew && entry.markObsoleteIfEmpty(ver))
+ colocated.removeIfObsolete(key);
+ }
+ else {
+ if (!skipVals && cctx.config().isStatisticsEnabled())
+ cctx.cache().metrics0().onRead(true);
+
+ if (!skipVals)
+ setResult(v, ver);
+ else
+ setSkipValueResult(true, ver);
+
+ return null;
+ }
+ }
+
+ break;
+ }
+ catch (GridDhtInvalidPartitionException ignored) {
+ break;
+ }
+ catch (IgniteCheckedException e) {
+ onDone(e);
+
+ return null;
+ }
+ catch (GridCacheEntryRemovedException ignored) {
+ // No-op, will retry.
+ }
+ }
+ }
+
+ return primary;
+ }
+
+ /**
+ * @param nodeId Node ID.
+ * @param res Result.
+ */
+ public void onResult(UUID nodeId, GridNearSingleGetResponse res) {
+ if (!processResponse(nodeId) || !checkError(res.error(), res.invalidPartitions(), res.topologyVersion()))
+ return;
+
+ Message res0 = res.result();
+
+ if (needVer) {
+ CacheVersionedValue verVal = (CacheVersionedValue)res0;
+
+ if (verVal != null) {
+ if (skipVals)
+ setSkipValueResult(true, verVal.version());
+ else
+ setResult(verVal.value() , verVal.version());
+ }
+ else {
+ if (skipVals)
+ setSkipValueResult(false, null);
+ else
+ setResult(null , null);
+ }
+ }
+ else {
+ if (skipVals)
+ setSkipValueResult(res.containsValue(), null);
+ else
+ setResult((CacheObject)res0, null);
+ }
+ }
+
+ /**
+ * @param nodeId Node ID.
+ * @param res Result.
+ */
+ public void onResult(UUID nodeId, GridNearGetResponse res) {
+ if (!processResponse(nodeId) ||
+ !checkError(res.error(), !F.isEmpty(res.invalidPartitions()), res.topologyVersion()))
+ return;
+
+ Collection<GridCacheEntryInfo> infos = res.entries();
+
+ assert F.isEmpty(infos) || infos.size() == 1 : infos;
+
+ setResult(F.first(infos));
+ }
+
+ /**
+ * @param nodeId Node ID.
+ * @return {@code True} if should process received response.
+ */
+ private boolean processResponse(UUID nodeId) {
+ synchronized (this) {
+ if (node != null && node.id().equals(nodeId)) {
+ node = null;
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param err Error.
+ * @param invalidParts Invalid partitions error flag.
+ * @param rmtTopVer Received topology version.
+ */
+ private boolean checkError(@Nullable IgniteCheckedException err,
+ boolean invalidParts,
+ AffinityTopologyVersion rmtTopVer) {
+ if (err != null) {
+ onDone(err);
+
+ return false;
+ }
+
+ if (invalidParts) {
+ assert !rmtTopVer.equals(AffinityTopologyVersion.ZERO);
+
+ if (rmtTopVer.compareTo(topVer) <= 0) {
+ // Fail the whole get future.
+ onDone(new IgniteCheckedException("Failed to process invalid partitions response (remote node reported " +
+ "invalid partitions but remote topology version does not differ from local) " +
+ "[topVer=" + topVer + ", rmtTopVer=" + rmtTopVer + ", part=" + cctx.affinity().partition(key) +
+ ", nodeId=" + node.id() + ']'));
+
+ return false;
+ }
+
+ if (canRemap) {
+ IgniteInternalFuture<Long> topFut = cctx.discovery().topologyFuture(rmtTopVer.topologyVersion());
+
+ topFut.listen(new CIX1<IgniteInternalFuture<Long>>() {
+ @Override public void applyx(IgniteInternalFuture<Long> fut) {
+ try {
+ AffinityTopologyVersion topVer = new AffinityTopologyVersion(fut.get());
+
+ remap(topVer);
+ }
+ catch (IgniteCheckedException e) {
+ onDone(e);
+ }
+ }
+ });
+
+ }
+ else
+ map(topVer);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @param info Entry info.
+ */
+ private void setResult(@Nullable GridCacheEntryInfo info) {
+ assert info == null || skipVals == (info.value() == null);
+
+ if (skipVals) {
+ if (info != null)
+ setSkipValueResult(true, info.version());
+ else
+ setSkipValueResult(false, null);
+ }
+ else {
+ if (info != null)
+ setResult(info.value(), info.version());
+ else
+ setResult(null, null);
+ }
+ }
+
+ /**
+ * @param res Result.
+ * @param ver Version.
+ */
+ private void setSkipValueResult(boolean res, @Nullable GridCacheVersion ver) {
+ assert skipVals;
+
+ if (needVer) {
+ assert ver != null || !res;
+
+ onDone(new T2<>(res, ver));
+ }
+ else
+ onDone(res);
+ }
+
+ /**
+ * @param val Value.
+ * @param ver Version.
+ */
+ private void setResult(@Nullable CacheObject val, @Nullable GridCacheVersion ver) {
+ try {
+ assert !skipVals;
+
+ if (val != null) {
+ if (needVer) {
+ assert ver != null;
+
+ onDone(new T2<>(val, ver));
+ }
+ else {
+ if (!keepCacheObjects) {
+ Object res = CU.value(val, cctx, true);
+
+ if (deserializePortable && !skipVals)
+ res = cctx.unwrapPortableIfNeeded(res, false);
+
+ onDone(res);
+ }
+ else
+ onDone(val);
+ }
+ }
+ else
+ onDone(null);
+ }
+ catch (Exception e) {
+ onDone(e);
+ }
+ }
+
+ /**
+ * Affinity node to send get request to.
+ *
+ * @param key Key to get.
+ * @param topVer Topology version.
+ * @return Affinity node to get key from.
+ */
+ private ClusterNode affinityNode(KeyCacheObject key, AffinityTopologyVersion topVer) {
+ if (!canRemap) {
+ List<ClusterNode> affNodes = cctx.affinity().nodes(key, topVer);
+
+ for (ClusterNode node : affNodes) {
+ if (cctx.discovery().alive(node))
+ return node;
+ }
+
+ return null;
+ }
+ else
+ return cctx.affinity().primary(key, topVer);
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteUuid futureId() {
+ return futId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean onNodeLeft(UUID nodeId) {
+ if (!processResponse(nodeId))
+ return false;
+
+ if (canRemap) {
+ final AffinityTopologyVersion updTopVer = new AffinityTopologyVersion(
+ Math.max(topVer.topologyVersion() + 1, cctx.discovery().topologyVersion()));
+
+ cctx.affinity().affinityReadyFuture(updTopVer).listen(
+ new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
+ @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
+ try {
+ fut.get();
+
+ remap(updTopVer);
+ }
+ catch (IgniteCheckedException e) {
+ onDone(e);
+ }
+ }
+ });
+ }
+ else
+ remap(topVer);
+
+ return true;
+ }
+
+ /**
+ * @param topVer Topology version.
+ */
+ private void remap(final AffinityTopologyVersion topVer) {
+ cctx.closures().runLocalSafe(new Runnable() {
+ @Override public void run() {
+ map(topVer);
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean onDone(Object res, Throwable err) {
+ if (super.onDone(res, err)) {
+ // Don't forget to clean up.
+ if (trackable)
+ cctx.mvcc().removeFuture(futId);
+
+ cctx.dht().sendTtlUpdateRequest(expiryPlc);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean trackable() {
+ return trackable;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void markNotTrackable() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridPartitionedSingleGetFuture.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 7f9edb2..75f8c2f 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
@@ -65,11 +65,14 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheE
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.distributed.dht.GridPartitionedGetFuture;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
import org.apache.ignite.internal.processors.cache.dr.GridCacheDrExpirationInfo;
import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx;
@@ -242,6 +245,12 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
}
});
+ ctx.io().addHandler(ctx.cacheId(), GridNearSingleGetRequest.class, new CI2<UUID, GridNearSingleGetRequest>() {
+ @Override public void apply(UUID nodeId, GridNearSingleGetRequest req) {
+ processNearSingleGetRequest(nodeId, req);
+ }
+ });
+
ctx.io().addHandler(ctx.cacheId(), GridNearAtomicUpdateRequest.class, new CI2<UUID, GridNearAtomicUpdateRequest>() {
@Override public void apply(UUID nodeId, GridNearAtomicUpdateRequest req) {
processNearAtomicUpdateRequest(nodeId, req);
@@ -279,6 +288,12 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
processNearGetResponse(nodeId, res);
}
});
+
+ ctx.io().addHandler(ctx.cacheId(), GridNearSingleGetResponse.class, new CI2<UUID, GridNearSingleGetResponse>() {
+ @Override public void apply(UUID nodeId, GridNearSingleGetResponse res) {
+ processNearSingleGetResponse(nodeId, res);
+ }
+ });
}
}
@@ -301,6 +316,45 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
}
/** {@inheritDoc} */
+ @Override protected IgniteInternalFuture<V> getAsync(final K key,
+ final boolean forcePrimary,
+ final boolean skipTx,
+ @Nullable UUID subjId,
+ final String taskName,
+ final boolean deserializePortable,
+ final boolean skipVals,
+ final boolean canRemap) {
+ ctx.checkSecurity(SecurityPermission.CACHE_READ);
+
+ if (keyCheck)
+ validateCacheKey(key);
+
+ CacheOperationContext opCtx = ctx.operationContextPerCall();
+
+ subjId = ctx.subjectIdPerCall(null, opCtx);
+
+ final UUID subjId0 = subjId;
+
+ final ExpiryPolicy expiryPlc = skipVals ? null : opCtx != null ? opCtx.expiry() : null;
+
+ final boolean skipStore = opCtx != null && opCtx.skipStore();
+
+ return asyncOp(new CO<IgniteInternalFuture<V>>() {
+ @Override public IgniteInternalFuture<V> apply() {
+ return getAsync0(ctx.toCacheKeyObject(key),
+ forcePrimary,
+ subjId0,
+ taskName,
+ deserializePortable,
+ expiryPlc,
+ skipVals,
+ skipStore,
+ canRemap);
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteInternalFuture<Map<K, V>> getAllAsync(
@Nullable final Collection<? extends K> keys,
final boolean forcePrimary,
@@ -914,9 +968,57 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
}
/**
+ * Entry point to all public API single get methods.
+ *
+ * @param key Key.
+ * @param forcePrimary Force primary flag.
+ * @param subjId Subject ID.
+ * @param taskName Task name.
+ * @param deserializePortable Deserialize portable flag.
+ * @param expiryPlc Expiry policy.
+ * @param skipVals Skip values flag.
+ * @param skipStore Skip store flag.
+ * @param canRemap Can remap flag.
+ * @return Get future.
+ */
+ private IgniteInternalFuture<V> getAsync0(KeyCacheObject key,
+ boolean forcePrimary,
+ UUID subjId,
+ String taskName,
+ boolean deserializePortable,
+ @Nullable ExpiryPolicy expiryPlc,
+ boolean skipVals,
+ boolean skipStore,
+ boolean canRemap
+ ) {
+ AffinityTopologyVersion topVer = canRemap ? ctx.affinity().affinityTopologyVersion() :
+ ctx.shared().exchange().readyAffinityVersion();
+
+ IgniteCacheExpiryPolicy expiry = skipVals ? null : expiryPolicy(expiryPlc);
+
+ GridPartitionedSingleGetFuture fut = new GridPartitionedSingleGetFuture(ctx,
+ key,
+ topVer,
+ !skipStore,
+ forcePrimary,
+ subjId,
+ taskName,
+ deserializePortable,
+ expiry,
+ skipVals,
+ canRemap,
+ false,
+ false);
+
+ fut.init();
+
+ return (IgniteInternalFuture<V>)fut;
+ }
+
+ /**
* Entry point to all public API get methods.
*
- * @param keys Keys to remove.
+ * @param keys Keys.
* @param forcePrimary Force primary flag.
* @param subjId Subject ID.
* @param taskName Task name.
@@ -942,7 +1044,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 (!forcePrimary) {
+ if (!forcePrimary && ctx.affinityNode()) {
Map<K, V> locVals = U.newHashMap(keys.size());
boolean success = true;
@@ -2409,27 +2511,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
/**
* @param nodeId Sender node ID.
- * @param res Near get response.
- */
- private void processNearGetResponse(UUID nodeId, GridNearGetResponse res) {
- if (log.isDebugEnabled())
- log.debug("Processing near get response [nodeId=" + nodeId + ", res=" + res + ']');
-
- GridPartitionedGetFuture<K, V> fut = (GridPartitionedGetFuture<K, V>)ctx.mvcc().<Map<K, V>>future(
- res.version(), res.futureId());
-
- if (fut == null) {
- if (log.isDebugEnabled())
- log.debug("Failed to find future for get response [sender=" + nodeId + ", res=" + res + ']');
-
- return;
- }
-
- fut.onResult(nodeId, res);
- }
-
- /**
- * @param nodeId Sender node ID.
* @param req Near atomic update request.
*/
private void processNearAtomicUpdateRequest(UUID nodeId, GridNearAtomicUpdateRequest req) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
index 4ace5c4..c34dcfd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
@@ -22,7 +22,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import javax.cache.processor.EntryProcessor;
import org.apache.ignite.IgniteCheckedException;
@@ -48,7 +47,6 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteUuid;
import org.jetbrains.annotations.Nullable;
-import org.jsr166.ConcurrentHashMap8;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
@@ -67,39 +65,42 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
protected static IgniteLogger log;
/** Cache context. */
- private GridCacheContext cctx;
+ private final GridCacheContext cctx;
/** Future version. */
- private GridCacheVersion futVer;
+ private final GridCacheVersion futVer;
/** Write version. */
- private GridCacheVersion writeVer;
+ private final GridCacheVersion writeVer;
/** Force transform backup flag. */
private boolean forceTransformBackups;
/** Completion callback. */
@GridToStringExclude
- private CI2<GridNearAtomicUpdateRequest, GridNearAtomicUpdateResponse> completionCb;
+ private final CI2<GridNearAtomicUpdateRequest, GridNearAtomicUpdateResponse> completionCb;
/** Mappings. */
@GridToStringInclude
- private ConcurrentMap<UUID, GridDhtAtomicUpdateRequest> mappings = new ConcurrentHashMap8<>();
+ private final Map<UUID, GridDhtAtomicUpdateRequest> mappings;
/** Entries with readers. */
private Map<KeyCacheObject, GridDhtCacheEntry> nearReadersEntries;
/** Update request. */
- private GridNearAtomicUpdateRequest updateReq;
+ private final GridNearAtomicUpdateRequest updateReq;
/** Update response. */
- private GridNearAtomicUpdateResponse updateRes;
+ private final GridNearAtomicUpdateResponse updateRes;
/** Future keys. */
- private Collection<KeyCacheObject> keys;
+ private final Collection<KeyCacheObject> keys;
/** */
- private boolean waitForExchange;
+ private final boolean waitForExchange;
+
+ /** Response count. */
+ private volatile int resCnt;
/**
* @param cctx Cache context.
@@ -128,6 +129,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
log = U.logger(cctx.kernalContext(), logRef, GridDhtAtomicUpdateFuture.class);
keys = new ArrayList<>(updateReq.keys().size());
+ mappings = U.newHashMap(updateReq.keys().size());
boolean topLocked = updateReq.topologyLocked() || (updateReq.fastMap() && !updateReq.clientRequest());
@@ -145,22 +147,37 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
}
/** {@inheritDoc} */
- @Override public Collection<? extends ClusterNode> nodes() {
- return F.view(F.viewReadOnly(mappings.keySet(), U.id2Node(cctx.kernalContext())), F.notNull());
- }
-
- /** {@inheritDoc} */
@Override public boolean onNodeLeft(UUID nodeId) {
if (log.isDebugEnabled())
log.debug("Processing node leave event [fut=" + this + ", nodeId=" + nodeId + ']');
+ return registerResponse(nodeId);
+ }
+
+ /**
+ * @param nodeId Node ID.
+ * @return {@code True} if request found.
+ */
+ private boolean registerResponse(UUID nodeId) {
+ int resCnt0;
+
GridDhtAtomicUpdateRequest req = mappings.get(nodeId);
if (req != null) {
- // Remove only after added keys to failed set.
- mappings.remove(nodeId);
+ synchronized (this) {
+ if (req.onResponse()) {
+ resCnt0 = resCnt;
+
+ resCnt0 += 1;
+
+ resCnt = resCnt0;
+ }
+ else
+ return false;
+ }
- checkComplete();
+ if (resCnt0 == mappings.size())
+ onDone();
return true;
}
@@ -343,18 +360,18 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
U.warn(log, "Failed to send update request to backup node because it left grid: " +
req.nodeId());
- mappings.remove(req.nodeId());
+ registerResponse(req.nodeId());
}
catch (IgniteCheckedException e) {
U.error(log, "Failed to send update request to backup node (did node leave the grid?): "
+ req.nodeId(), e);
- mappings.remove(req.nodeId());
+ registerResponse(req.nodeId());
}
}
}
-
- checkComplete();
+ else
+ onDone();
// Send response right away if no ACKs from backup is required.
// Backups will send ACKs anyway, future will be completed after all backups have replied.
@@ -389,9 +406,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
}
}
- mappings.remove(nodeId);
-
- checkComplete();
+ registerResponse(nodeId);
}
/**
@@ -403,22 +418,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
if (log.isDebugEnabled())
log.debug("Received deferred DHT atomic update future result [nodeId=" + nodeId + ']');
- mappings.remove(nodeId);
-
- checkComplete();
- }
-
- /**
- * Checks if all required responses are received.
- */
- private void checkComplete() {
- // Always wait for replies from all backups.
- if (mappings.isEmpty()) {
- if (log.isDebugEnabled())
- log.debug("Completing DHT atomic update future: " + this);
-
- onDone();
- }
+ registerResponse(nodeId);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
index e55cac9..1219f2f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
@@ -139,6 +139,10 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
/** Task name hash. */
private int taskNameHash;
+ /** On response flag. Access should be synced on future. */
+ @GridDirectTransient
+ private boolean onRes;
+
/**
* Empty constructor required by {@link Externalizable}.
*/
@@ -527,6 +531,13 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
}
/**
+ * @return {@code True} if on response flag changed.
+ */
+ public boolean onResponse() {
+ return !onRes && (onRes = true);
+ }
+
+ /**
* @return Optional arguments for entry processor.
*/
@Nullable public Object[] invokeArguments() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
index ae662c8..a786803 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
@@ -238,11 +238,6 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter<Object>
return state.futureVersion();
}
- /** {@inheritDoc} */
- @Override public Collection<? extends ClusterNode> nodes() {
- throw new UnsupportedOperationException();
- }
-
/**
* @return {@code True} if this future should block partition map exchange.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 7131aa5..47b7aea 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
@@ -53,8 +53,10 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvali
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTransactionalCacheAdapter;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedGetFuture;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTransactionalCache;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearUnlockRequest;
@@ -67,6 +69,7 @@ import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.lang.IgnitePair;
import org.apache.ignite.internal.util.typedef.C2;
import org.apache.ignite.internal.util.typedef.CI2;
+import org.apache.ignite.internal.util.typedef.CX1;
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;
@@ -138,7 +141,13 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
ctx.io().addHandler(ctx.cacheId(), GridNearGetResponse.class, new CI2<UUID, GridNearGetResponse>() {
@Override public void apply(UUID nodeId, GridNearGetResponse res) {
- processGetResponse(nodeId, res);
+ processNearGetResponse(nodeId, res);
+ }
+ });
+
+ ctx.io().addHandler(ctx.cacheId(), GridNearSingleGetResponse.class, new CI2<UUID, GridNearSingleGetResponse>() {
+ @Override public void apply(UUID nodeId, GridNearSingleGetResponse res) {
+ processNearSingleGetResponse(nodeId, res);
}
});
@@ -185,6 +194,80 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
}
/** {@inheritDoc} */
+ @Override protected IgniteInternalFuture<V> getAsync(final K key,
+ boolean forcePrimary,
+ boolean skipTx,
+ @Nullable UUID subjId,
+ String taskName,
+ final boolean deserializePortable,
+ final boolean skipVals,
+ boolean canRemap) {
+ ctx.checkSecurity(SecurityPermission.CACHE_READ);
+
+ if (keyCheck)
+ validateCacheKey(key);
+
+ IgniteTxLocalAdapter tx = ctx.tm().threadLocalTx(ctx);
+
+ final CacheOperationContext opCtx = ctx.operationContextPerCall();
+
+ if (tx != null && !tx.implicit() && !skipTx) {
+ return asyncOp(tx, new AsyncOp<V>() {
+ @Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
+ IgniteInternalFuture<Map<Object, Object>> fut = tx.getAllAsync(ctx,
+ Collections.singleton(ctx.toCacheKeyObject(key)),
+ deserializePortable,
+ skipVals,
+ false,
+ opCtx != null && opCtx.skipStore());
+
+ return fut.chain(new CX1<IgniteInternalFuture<Map<Object, Object>>, V>() {
+ @SuppressWarnings("unchecked")
+ @Override public V applyx(IgniteInternalFuture<Map<Object, Object>> e)
+ throws IgniteCheckedException {
+ Map<Object, Object> map = e.get();
+
+ assert map.isEmpty() || map.size() == 1 : map.size();
+
+ if (skipVals) {
+ Boolean val = map.isEmpty() ? false : (Boolean)F.firstValue(map);
+
+ return (V)(val);
+ }
+
+ return (V)map.get(key);
+ }
+ });
+ }
+ });
+ }
+
+ AffinityTopologyVersion topVer = tx == null ?
+ (canRemap ? ctx.affinity().affinityTopologyVersion() : ctx.shared().exchange().readyAffinityVersion()) :
+ tx.topologyVersion();
+
+ subjId = ctx.subjectIdPerCall(subjId, opCtx);
+
+ GridPartitionedSingleGetFuture fut = new GridPartitionedSingleGetFuture(ctx,
+ ctx.toCacheKeyObject(key),
+ topVer,
+ opCtx == null || !opCtx.skipStore(),
+ forcePrimary,
+ subjId,
+ taskName,
+ deserializePortable,
+ skipVals ? null : expiryPolicy(opCtx != null ? opCtx.expiry() : null),
+ skipVals,
+ canRemap,
+ /*needVer*/false,
+ /*keepCacheObjects*/false);
+
+ fut.init();
+
+ return (IgniteInternalFuture<V>)fut;
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteInternalFuture<Map<K, V>> getAllAsync(
@Nullable final Collection<? extends K> keys,
boolean forcePrimary,
@@ -290,6 +373,54 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
}
/**
+ * @param key Key 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.
+ * @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 keepCacheObj Keep cache objects flag.
+ * @return Load future.
+ */
+ public final IgniteInternalFuture<Object> loadAsync(
+ KeyCacheObject key,
+ boolean readThrough,
+ boolean forcePrimary,
+ AffinityTopologyVersion topVer,
+ @Nullable UUID subjId,
+ String taskName,
+ boolean deserializePortable,
+ @Nullable IgniteCacheExpiryPolicy expiryPlc,
+ boolean skipVals,
+ boolean canRemap,
+ boolean needVer,
+ boolean keepCacheObj
+ ) {
+ GridPartitionedSingleGetFuture fut = new GridPartitionedSingleGetFuture(ctx,
+ ctx.toCacheKeyObject(key),
+ topVer,
+ readThrough,
+ forcePrimary,
+ subjId,
+ taskName,
+ deserializePortable,
+ expiryPlc,
+ skipVals,
+ canRemap,
+ needVer,
+ keepCacheObj);
+
+ fut.init();
+
+ return fut;
+ }
+
+ /**
* @param keys Keys to load.
* @param readThrough Read through flag.
* @param forcePrimary Force get from primary node flag.
@@ -299,9 +430,12 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
* @param deserializePortable Deserialize portable flag.
* @param expiryPlc Expiry policy.
* @param skipVals Skip values flag.
- * @return Loaded values.
+ * @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 keepCacheObj Keep cache objects flag.
+ * @return Load future.
*/
- public IgniteInternalFuture<Map<K, V>> loadAsync(
+ public final IgniteInternalFuture<Map<K, V>> loadAsync(
@Nullable Collection<KeyCacheObject> keys,
boolean readThrough,
boolean forcePrimary,
@@ -931,24 +1065,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
}
/**
- * @param nodeId Sender ID.
- * @param res Response.
- */
- private void processGetResponse(UUID nodeId, GridNearGetResponse res) {
- GridPartitionedGetFuture<K, V> fut = (GridPartitionedGetFuture<K, V>)ctx.mvcc().<Map<K, V>>future(
- res.version(), res.futureId());
-
- if (fut == null) {
- if (log.isDebugEnabled())
- log.debug("Failed to find future for get response [sender=" + nodeId + ", res=" + res + ']');
-
- return;
- }
-
- fut.onResult(nodeId, res);
- }
-
- /**
* @param nodeId Node ID.
* @param res Response.
*/
@@ -957,7 +1073,7 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
assert res != null;
GridDhtColocatedLockFuture fut = (GridDhtColocatedLockFuture)ctx.mvcc().
- <Boolean>future(res.version(), res.futureId());
+ <Boolean>mvccFuture(res.version(), res.futureId());
if (fut != null)
fut.onResult(nodeId, res);
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 abeb509..8245d88 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
@@ -35,10 +35,11 @@ import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
import org.apache.ignite.internal.processors.cache.CacheObject;
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.GridCacheFuture;
import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException;
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
+import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
@@ -78,7 +79,7 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;
* Colocated cache lock future.
*/
public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture<Boolean>
- implements GridCacheFuture<Boolean> {
+ implements GridCacheMvccFuture<Boolean> {
/** */
private static final long serialVersionUID = 0L;
@@ -198,25 +199,16 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
valMap = new ConcurrentHashMap8<>(keys.size(), 1f);
}
- /**
- * @return Participating nodes.
- */
- @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 GridCacheVersion version() {
return lockVer;
}
+ /** {@inheritDoc} */
+ @Override public boolean onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
+ return false;
+ }
+
/**
* @return Future ID.
*/
@@ -538,7 +530,7 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
log.debug("Completing future: " + this);
// Clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeMvccFuture(this);
if (timeoutObj != null)
cctx.time().removeTimeoutObject(timeoutObj);
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java
index 1559a91..c14621a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/CacheVersionedValue.java
@@ -53,7 +53,7 @@ public class CacheVersionedValue implements Message {
* @param val Cache value.
* @param ver Cache version.
*/
- CacheVersionedValue(CacheObject val, GridCacheVersion ver) {
+ public CacheVersionedValue(CacheObject val, GridCacheVersion ver) {
this.val = val;
this.ver = ver;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 3c3527a..eb0b637 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
@@ -52,6 +52,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheValueCollection;
import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheAdapter;
+import org.apache.ignite.internal.processors.cache.distributed.dht.CacheGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
@@ -292,8 +293,7 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
* @param res Response.
*/
protected void processGetResponse(UUID nodeId, GridNearGetResponse res) {
- GridNearGetFuture<K, V> fut = (GridNearGetFuture<K, V>)ctx.mvcc().<Map<K, V>>future(
- res.version(), res.futureId());
+ CacheGetFuture fut = (CacheGetFuture)ctx.mvcc().future(res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 ae1d43c..dfaa44e 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
@@ -170,24 +170,6 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
}
/** {@inheritDoc} */
- @Override public GridCacheVersion version() {
- return ver;
- }
-
- /** {@inheritDoc} */
- @Override public Collection<? extends ClusterNode> nodes() {
- return
- F.viewReadOnly(futures(), new IgniteClosure<IgniteInternalFuture<Map<K, V>>, ClusterNode>() {
- @Nullable @Override public ClusterNode apply(IgniteInternalFuture<Map<K, V>> f) {
- if (isMini(f))
- return ((MiniFuture)f).node();
-
- return cctx.discovery().localNode();
- }
- });
- }
-
- /** {@inheritDoc} */
@Override public boolean onNodeLeft(UUID nodeId) {
boolean found = false;
@@ -227,7 +209,7 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
if (super.onDone(res, err)) {
// Don't forget to clean up.
if (trackable)
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeFuture(futId);
cache().dht().sendTtlUpdateRequest(expiryPlc);
@@ -343,7 +325,7 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
if (!trackable) {
trackable = true;
- cctx.mvcc().addFuture(this);
+ cctx.mvcc().addFuture(this, futId);
}
MiniFuture fut = new MiniFuture(n, mappedKeys, saved, topVer);
@@ -386,6 +368,7 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
* @param saved Reserved near cache entries.
* @return Map.
*/
+ @SuppressWarnings("unchecked")
private Map<KeyCacheObject, GridNearCacheEntry> map(
KeyCacheObject key,
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings,
@@ -538,11 +521,17 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
}
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);
+ V val0;
+
+ if (!skipVals) {
+ val0 = v.value(cctx.cacheObjectContext(), true);
+ val0 = (V)cctx.unwrapPortableIfNeeded(val0, !deserializePortable);
+ }
+ else
+ val0 = (V)Boolean.TRUE;
+
add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
}
}
@@ -618,28 +607,6 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
}
/**
- * Affinity node to send get request to.
- *
- * @param key Key to get.
- * @param topVer Topology version.
- * @return Affinity node to get key from.
- */
- private ClusterNode affinityNode(KeyCacheObject key, AffinityTopologyVersion topVer) {
- if (!canRemap) {
- List<ClusterNode> affNodes = cctx.affinity().nodes(key, topVer);
-
- for (ClusterNode node : affNodes) {
- if (cctx.discovery().alive(node))
- return node;
- }
-
- return null;
- }
- else
- return cctx.affinity().primary(key, topVer);
- }
-
- /**
* @return Near cache.
*/
private GridNearCacheAdapter<K, V> cache() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 8482217..6d60298 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
@@ -133,7 +133,6 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
) {
assert futId != null;
assert miniId != null;
- assert ver != null;
assert keys != null;
this.cacheId = cacheId;
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
index fc06ab1..15a791f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
@@ -100,8 +100,6 @@ public class GridNearGetResponse extends GridCacheMessage implements GridCacheDe
boolean addDepInfo
) {
assert futId != null;
- assert miniId != null;
- assert ver != null;
this.cacheId = cacheId;
this.futId = futId;
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
index 9c3701f..76f2fbe 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
@@ -209,20 +209,6 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
valMap = new ConcurrentHashMap8<>(keys.size(), 1f);
}
- /**
- * @return Participating nodes.
- */
- @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 GridCacheVersion version() {
return lockVer;
@@ -672,7 +658,7 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
log.debug("Completing future: " + this);
// Clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeMvccFuture(this);
if (timeoutObj != null)
cctx.time().removeTimeoutObject(timeoutObj);
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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
index 1569b14..770c47a 100644
--- 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
@@ -73,8 +73,7 @@ import static org.apache.ignite.transactions.TransactionState.PREPARING;
/**
*
*/
-public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter
- implements GridCacheMvccFuture<IgniteInternalTx> {
+public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter {
/** */
public static final IgniteProductVersion SER_TX_SINCE = IgniteProductVersion.fromString("1.5.0");
@@ -148,18 +147,6 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
}
/** {@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;
@@ -287,7 +274,7 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
tx.setRollbackOnly();
// Don't forget to clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeMvccFuture(this);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 82e3868..eaf476c 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
@@ -35,7 +35,6 @@ 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;
@@ -54,7 +53,6 @@ import org.apache.ignite.internal.util.typedef.F;
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.lang.IgniteUuid;
import org.apache.ignite.transactions.TransactionTimeoutException;
import org.jetbrains.annotations.Nullable;
@@ -66,8 +64,7 @@ import static org.apache.ignite.transactions.TransactionState.PREPARING;
/**
*
*/
-public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter
- implements GridCacheMvccFuture<IgniteInternalTx> {
+public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter {
/** */
@GridToStringInclude
private Collection<IgniteTxKey> lockKeys = new GridConcurrentHashSet<>();
@@ -100,18 +97,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
}
/** {@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;
@@ -261,7 +246,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
if (super.onDone(tx, err0)) {
// Don't forget to clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeMvccFuture(this);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 103105e..ffe5373 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
@@ -28,6 +28,8 @@ import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
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.GridCacheMvccCandidate;
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;
@@ -42,7 +44,6 @@ import org.apache.ignite.internal.util.typedef.F;
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.IgniteUuid;
import org.jetbrains.annotations.Nullable;
@@ -68,15 +69,6 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
}
/** {@inheritDoc} */
- @Override public Collection<? extends ClusterNode> nodes() {
- return F.viewReadOnly(futures(), new IgniteClosure<IgniteInternalFuture<?>, ClusterNode>() {
- @Nullable @Override public ClusterNode apply(IgniteInternalFuture<?> f) {
- return ((MiniFuture)f).node();
- }
- });
- }
-
- /** {@inheritDoc} */
@Override public boolean onNodeLeft(UUID nodeId) {
boolean found = false;
@@ -280,6 +272,11 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
}
/** {@inheritDoc} */
+ @Override public boolean onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
+ return false;
+ }
+
+ /** {@inheritDoc} */
@Override public boolean onDone(@Nullable IgniteInternalTx res, @Nullable Throwable err) {
if (err != null)
this.err.compareAndSet(null, err);
@@ -290,7 +287,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
tx.state(PREPARED);
if (super.onDone(tx, err)) {
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeMvccFuture(this);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java
new file mode 100644
index 0000000..a506007
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearSingleGetRequest.java
@@ -0,0 +1,396 @@
+/*
+ * 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.nio.ByteBuffer;
+import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
+import org.apache.ignite.internal.processors.cache.GridCacheMessage;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.KeyCacheObject;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.ignite.internal.processors.cache.GridCacheUtils.SKIP_STORE_FLAG_MASK;
+
+/**
+ *
+ */
+public class GridNearSingleGetRequest extends GridCacheMessage implements GridCacheDeployable {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ public static final int READ_THROUGH_FLAG_MASK = 0x01;
+
+ /** */
+ public static final int SKIP_VALS_FLAG_MASK = 0x02;
+
+ /** */
+ public static final int ADD_READER_FLAG_MASK = 0x04;
+
+ /** */
+ public static final int NEED_VER_FLAG_MASK = 0x08;
+
+ /** */
+ public static final int NEED_ENTRY_INFO_FLAG_MASK = 0x10;
+
+ /** Future ID. */
+ private IgniteUuid futId;
+
+ /** */
+ private KeyCacheObject key;
+
+ /** Flags. */
+ private byte flags;
+
+ /** Topology version. */
+ private AffinityTopologyVersion topVer;
+
+ /** Subject ID. */
+ private UUID subjId;
+
+ /** Task name hash. */
+ private int taskNameHash;
+
+ /** TTL for read operation. */
+ private long accessTtl;
+
+ /**
+ * Empty constructor required for {@link Message}.
+ */
+ public GridNearSingleGetRequest() {
+ // No-op.
+ }
+
+ /**
+ * @param cacheId Cache ID.
+ * @param futId Future ID.
+ * @param key Key.
+ * @param readThrough Read through 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.
+ * @param subjId Subject ID.
+ * @param taskNameHash Task name hash.
+ * @param accessTtl New TTL to set after entry is accessed, -1 to leave unchanged.
+ * @param addReader Add reader flag.
+ * @param needVer {@code True} if entry version is needed.
+ * @param addDepInfo Deployment info.
+ */
+ public GridNearSingleGetRequest(
+ int cacheId,
+ IgniteUuid futId,
+ KeyCacheObject key,
+ boolean readThrough,
+ @NotNull AffinityTopologyVersion topVer,
+ UUID subjId,
+ int taskNameHash,
+ long accessTtl,
+ boolean skipVals,
+ boolean addReader,
+ boolean needVer,
+ boolean addDepInfo
+ ) {
+ assert futId != null;
+ assert key != null;
+
+ this.cacheId = cacheId;
+ this.futId = futId;
+ this.key = key;
+ this.topVer = topVer;
+ this.subjId = subjId;
+ this.taskNameHash = taskNameHash;
+ this.accessTtl = accessTtl;
+ this.addDepInfo = addDepInfo;
+
+ if (readThrough)
+ flags = (byte)(flags | READ_THROUGH_FLAG_MASK);
+
+ if (skipVals)
+ flags = (byte)(flags | SKIP_VALS_FLAG_MASK);
+
+ if (addReader)
+ flags = (byte)(flags | ADD_READER_FLAG_MASK);
+
+ if (needVer)
+ flags = (byte)(flags | NEED_VER_FLAG_MASK);
+ }
+
+ /**
+ * @return Key.
+ */
+ public KeyCacheObject key() {
+ return key;
+ }
+
+ /**
+ * @return Future ID.
+ */
+ public IgniteUuid futureId() {
+ return futId;
+ }
+
+ /**
+ * @return Subject ID.
+ */
+ public UUID subjectId() {
+ return subjId;
+ }
+
+ /**
+ * Gets task name hash.
+ *
+ * @return Task name hash.
+ */
+ public int taskNameHash() {
+ return taskNameHash;
+ }
+
+ /**
+ * @return Topology version.
+ */
+ @Override public AffinityTopologyVersion topologyVersion() {
+ return topVer;
+ }
+
+ /**
+ * @return New TTL to set after entry is accessed, -1 to leave unchanged.
+ */
+ public long accessTtl() {
+ return accessTtl;
+ }
+
+ /**
+ * @return Read through flag.
+ */
+ public boolean readThrough() {
+ return (flags & SKIP_STORE_FLAG_MASK) != 0;
+ }
+
+ /**
+ * @return Read through flag.
+ */
+ public boolean skipValues() {
+ return (flags & SKIP_VALS_FLAG_MASK) != 0;
+ }
+
+ /**
+ * @return Add reader flag.
+ */
+ public boolean addReader() {
+ return (flags & ADD_READER_FLAG_MASK) != 0;
+ }
+
+ /**
+ * @return {@code True} if entry version is needed.
+ */
+ public boolean needVersion() {
+ return (flags & NEED_VER_FLAG_MASK) != 0;
+ }
+
+ /**
+ * @return {@code True} if full entry information is needed.
+ */
+ public boolean needEntryInfo() {
+ return (flags & NEED_ENTRY_INFO_FLAG_MASK) != 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
+ super.prepareMarshal(ctx);
+
+ assert key != null;
+
+ GridCacheContext cctx = ctx.cacheContext(cacheId);
+
+ prepareMarshalCacheObject(key, cctx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException {
+ super.finishUnmarshal(ctx, ldr);
+
+ assert key != null;
+
+ GridCacheContext cctx = ctx.cacheContext(cacheId);
+
+ key.finishUnmarshal(cctx.cacheObjectContext(), ldr);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
+ reader.setBuffer(buf);
+
+ if (!reader.beforeMessageRead())
+ return false;
+
+ if (!super.readFrom(buf, reader))
+ return false;
+
+ switch (reader.state()) {
+ case 3:
+ accessTtl = reader.readLong("accessTtl");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 4:
+ flags = reader.readByte("flags");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 5:
+ futId = reader.readIgniteUuid("futId");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 6:
+ key = reader.readMessage("key");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 7:
+ subjId = reader.readUuid("subjId");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 8:
+ taskNameHash = reader.readInt("taskNameHash");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 9:
+ topVer = reader.readMessage("topVer");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ }
+
+ return reader.afterMessageRead(GridNearSingleGetRequest.class);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
+ writer.setBuffer(buf);
+
+ if (!super.writeTo(buf, writer))
+ return false;
+
+ if (!writer.isHeaderWritten()) {
+ if (!writer.writeHeader(directType(), fieldsCount()))
+ return false;
+
+ writer.onHeaderWritten();
+ }
+
+ switch (writer.state()) {
+ case 3:
+ if (!writer.writeLong("accessTtl", accessTtl))
+ return false;
+
+ writer.incrementState();
+
+ case 4:
+ if (!writer.writeByte("flags", flags))
+ return false;
+
+ writer.incrementState();
+
+ case 5:
+ if (!writer.writeIgniteUuid("futId", futId))
+ return false;
+
+ writer.incrementState();
+
+ case 6:
+ if (!writer.writeMessage("key", key))
+ return false;
+
+ writer.incrementState();
+
+ case 7:
+ if (!writer.writeUuid("subjId", subjId))
+ return false;
+
+ writer.incrementState();
+
+ case 8:
+ if (!writer.writeInt("taskNameHash", taskNameHash))
+ return false;
+
+ writer.incrementState();
+
+ case 9:
+ if (!writer.writeMessage("topVer", topVer))
+ return false;
+
+ writer.incrementState();
+
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean addDeploymentInfo() {
+ return addDepInfo;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte directType() {
+ return 116;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte fieldsCount() {
+ return 10;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridNearSingleGetRequest.class, this);
+ }
+}
[14/23] ignite git commit: Added benchmark:
IgniteSqlQueryPutSeparatedBenchmark
Posted by sb...@apache.org.
Added benchmark: IgniteSqlQueryPutSeparatedBenchmark
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/96483be6
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/96483be6
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/96483be6
Branch: refs/heads/ignite-sql-opt
Commit: 96483be6543e223282eaf8d5c8dbabbab1715baf
Parents: 4c9ea58
Author: ashutak <as...@gridgain.com>
Authored: Thu Nov 19 19:31:28 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Thu Nov 19 19:31:28 2015 +0300
----------------------------------------------------------------------
.../config/benchmark-multicast.properties | 6 +-
.../benchmark-query-put-separated.properties | 88 ++++++++++++++++++++
.../IgniteSqlQueryPutSeparatedBenchmark.java | 84 +++++++++++++++++++
3 files changed, 175 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/96483be6/modules/yardstick/config/benchmark-multicast.properties
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/benchmark-multicast.properties b/modules/yardstick/config/benchmark-multicast.properties
index 85f6c11..03cfddb 100644
--- a/modules/yardstick/config/benchmark-multicast.properties
+++ b/modules/yardstick/config/benchmark-multicast.properties
@@ -113,7 +113,7 @@ CONFIGS="\
-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 100 -dn IgnitePutAllBenchmark -sn IgniteNode -ds ${ver}atomic-putAll-1-backup,\
-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 100 -dn IgnitePutAllTxBenchmark -sn IgniteNode -ds ${ver}tx-putAll-1-backup,\
-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 100 -dn IgnitePutAllSerializableTxBenchmark -sn IgniteNode -ds ${ver}tx-putAllSerializable-1-backup,\
--cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 10 -txc OPTIMISTIC -dn IgniteGetAllPutAllTxBenchmark -sn IgniteNode -ds tx-optimistic-getAllPutAll-1-backup,\
--cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 10 -txc PESSIMISTIC -dn IgniteGetAllPutAllTxBenchmark -sn IgniteNode -ds tx-pessimistic-getAllPutAll-1-backup,\
--cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 10 -txc OPTIMISTIC -txi SERIALIZABLE -dn IgniteGetAllPutAllTxBenchmark -sn IgniteNode -ds tx-opt-serializable-getAllPutAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 10 -txc OPTIMISTIC -dn IgniteGetAllPutAllTxBenchmark -sn IgniteNode -ds ${ver}tx-optimistic-getAllPutAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 10 -txc PESSIMISTIC -dn IgniteGetAllPutAllTxBenchmark -sn IgniteNode -ds ${ver}tx-pessimistic-getAllPutAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b ${b} -w ${w} -d ${d} -t ${t} -sm ${sm} -bs 10 -txc OPTIMISTIC -txi SERIALIZABLE -dn IgniteGetAllPutAllTxBenchmark -sn IgniteNode -ds ${ver}tx-opt-serializable-getAllPutAll-1-backup,\
"
http://git-wip-us.apache.org/repos/asf/ignite/blob/96483be6/modules/yardstick/config/benchmark-query-put-separated.properties
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/benchmark-query-put-separated.properties b/modules/yardstick/config/benchmark-query-put-separated.properties
new file mode 100644
index 0000000..b1b2942
--- /dev/null
+++ b/modules/yardstick/config/benchmark-query-put-separated.properties
@@ -0,0 +1,88 @@
+# 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.
+
+#
+# Contains all multicast benchmarks
+#
+
+now0=`date +'%H%M%S'`
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+JVM_OPTS=${JVM_OPTS}" \
+-Xloggc:./gc${now0}.log \
+-XX:+PrintGCDetails \
+-verbose:gc \
+-XX:+UseParNewGC \
+-XX:+UseConcMarkSweepGC \
+-XX:+UseTLAB \
+-XX:NewSize=128m \
+-XX:MaxNewSize=128m \
+-XX:MaxTenuringThreshold=0 \
+-XX:SurvivorRatio=1024 \
+-XX:+UseCMSInitiatingOccupancyOnly \
+-XX:CMSInitiatingOccupancyFraction=60 \
+"
+
+#Ignite version
+ver="RELEASE-"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe,DStatProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Restart servers for each benchmark.
+RESTART_SERVERS=true
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# Comma-separated list of the hosts to run BenchmarkServers on.
+SERVER_HOSTS=localhost,localhost,localhost
+
+# Comma-separated list of the hosts to run BenchmarkDrivers on.
+DRIVER_HOSTS=localhost,localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Backups count.
+b=1
+
+# Warmup.
+w=10
+
+# Duration.
+d=30
+
+# Threads count.
+t=64
+
+# Sync mode.
+sm=PRIMARY_SYNC
+
+# Run configuration which contains all benchmarks.
+# Note that each benchmark is set to run for 300 seconds (5 mins) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w ${w} -d ${d} -t ${t} -sm PRIMARY_SYNC -dn IgniteSqlQueryPutSeparatedBenchmark -sn IgniteNode -ds query-put-1b,\
+"
http://git-wip-us.apache.org/repos/asf/ignite/blob/96483be6/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryPutSeparatedBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryPutSeparatedBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryPutSeparatedBenchmark.java
new file mode 100644
index 0000000..b74978e
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryPutSeparatedBenchmark.java
@@ -0,0 +1,84 @@
+/*
+ * 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.Collection;
+import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.yardstick.cache.model.Person;
+import org.yardstickframework.BenchmarkConfiguration;
+
+/**
+ * Ignite benchmark that performs put and query operations.
+ */
+public class IgniteSqlQueryPutSeparatedBenchmark extends IgniteCacheAbstractBenchmark<Integer, Object> {
+ /** {@inheritDoc} */
+ @Override public void setUp(BenchmarkConfiguration cfg) throws Exception {
+ super.setUp(cfg);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ if (cfg.memberId() % 2 == 0) {
+ double salary = rnd.nextDouble() * args.range() * 1000;
+
+ double maxSalary = salary + 1000;
+
+ Collection<Cache.Entry<Integer, Object>> entries = executeQuery(salary, maxSalary);
+
+ for (Cache.Entry<Integer, Object> entry : entries) {
+ Person p = (Person)entry.getValue();
+
+ if (p.getSalary() < salary || p.getSalary() > maxSalary)
+ throw new Exception("Invalid person retrieved [min=" + salary + ", max=" + maxSalary +
+ ", person=" + p + ']');
+ }
+ }
+ else {
+ int i = rnd.nextInt(args.range());
+
+ cache.put(i, new Person(i, "firstName" + i, "lastName" + i, i * 1000));
+ }
+
+ return true;
+ }
+
+ /**
+ * @param minSalary Min salary.
+ * @param maxSalary Max salary.
+ * @return Query result.
+ * @throws Exception If failed.
+ */
+ private Collection<Cache.Entry<Integer, Object>> executeQuery(double minSalary, double maxSalary) throws Exception {
+ SqlQuery qry = new SqlQuery(Person.class, "salary >= ? and salary <= ?");
+
+ qry.setArgs(minSalary, maxSalary);
+
+ return cache.query(qry).getAll();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteCache<Integer, Object> cache() {
+ return ignite().cache("query");
+ }
+}
[19/23] ignite git commit: IGNITE-426 Implemented failover for
Continuous query.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
index c7bf091..b2e7490 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
@@ -23,6 +23,7 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Map;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -46,12 +47,14 @@ import org.apache.ignite.cache.CacheEntryEventSerializableFilter;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.query.ContinuousQuery;
import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheManagerAdapter;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.continuous.GridContinuousHandler;
+import org.apache.ignite.internal.util.typedef.CI2;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgnitePredicate;
@@ -82,6 +85,9 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
/** */
private static final byte EXPIRED_FLAG = 0b1000;
+ /** */
+ private static final long BACKUP_ACK_FREQ = 5000;
+
/** Listeners. */
private final ConcurrentMap<UUID, CacheContinuousQueryListener> lsnrs = new ConcurrentHashMap8<>();
@@ -108,6 +114,18 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
@Override protected void start0() throws IgniteCheckedException {
// Append cache name to the topic.
topicPrefix = "CONTINUOUS_QUERY" + (cctx.name() == null ? "" : "_" + cctx.name());
+
+ cctx.io().addHandler(cctx.cacheId(), CacheContinuousQueryBatchAck.class,
+ new CI2<UUID, CacheContinuousQueryBatchAck>() {
+ @Override public void apply(UUID uuid, CacheContinuousQueryBatchAck msg) {
+ CacheContinuousQueryListener lsnr = lsnrs.get(msg.routineId());
+
+ if (lsnr != null)
+ lsnr.cleanupBackupQueue(msg.updateCntrs());
+ }
+ });
+
+ cctx.time().schedule(new BackupCleaner(lsnrs, cctx.kernalContext()), BACKUP_ACK_FREQ, BACKUP_ACK_FREQ);
}
/** {@inheritDoc} */
@@ -137,25 +155,55 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
}
/**
- * @param e Cache entry.
+ * @param partId Partition id.
+ * @param updCntr Updated counter.
+ * @param topVer Topology version.
+ */
+ public void skipUpdateEvent(KeyCacheObject key, int partId, long updCntr, AffinityTopologyVersion topVer) {
+ if (lsnrCnt.get() > 0) {
+ CacheContinuousQueryEntry e0 = new CacheContinuousQueryEntry(
+ cctx.cacheId(),
+ UPDATED,
+ key,
+ null,
+ null,
+ partId,
+ updCntr,
+ topVer);
+
+ CacheContinuousQueryEvent evt = new CacheContinuousQueryEvent<>(
+ cctx.kernalContext().cache().jcache(cctx.name()), cctx, e0);
+
+ for (CacheContinuousQueryListener lsnr : lsnrs.values())
+ lsnr.skipUpdateEvent(evt, topVer);
+ }
+ }
+
+ /**
* @param key Key.
* @param newVal New value.
* @param oldVal Old value.
+ * @param internal Internal entry (internal key or not user cache),
+ * @param primary {@code True} if called on primary node.
* @param preload Whether update happened during preloading.
+ * @param updateCntr Update counter.
+ * @param topVer Topology version.
* @throws IgniteCheckedException In case of error.
*/
- public void onEntryUpdated(GridCacheEntryEx e,
+ public void onEntryUpdated(
KeyCacheObject key,
CacheObject newVal,
CacheObject oldVal,
- boolean preload)
+ boolean internal,
+ int partId,
+ boolean primary,
+ boolean preload,
+ long updateCntr,
+ AffinityTopologyVersion topVer)
throws IgniteCheckedException
{
- assert e != null;
assert key != null;
- boolean internal = e.isInternal() || !e.context().userCache();
-
if (preload && !internal)
return;
@@ -179,8 +227,7 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
boolean initialized = false;
- boolean primary = cctx.affinity().primary(cctx.localNode(), key, AffinityTopologyVersion.NONE);
- boolean recordIgniteEvt = !internal && cctx.gridEvents().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
+ boolean recordIgniteEvt = primary && !internal && cctx.gridEvents().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
for (CacheContinuousQueryListener lsnr : lsnrCol.values()) {
if (preload && !lsnr.notifyExisting())
@@ -205,7 +252,10 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
evtType,
key,
newVal,
- lsnr.oldValueRequired() ? oldVal : null);
+ lsnr.oldValueRequired() ? oldVal : null,
+ partId,
+ updateCntr,
+ topVer);
CacheContinuousQueryEvent evt = new CacheContinuousQueryEvent<>(
cctx.kernalContext().cache().jcache(cctx.name()), cctx, e0);
@@ -250,12 +300,15 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
initialized = true;
}
- CacheContinuousQueryEntry e0 = new CacheContinuousQueryEntry(
- cctx.cacheId(),
- EXPIRED,
- key,
- null,
- lsnr.oldValueRequired() ? oldVal : null);
+ CacheContinuousQueryEntry e0 = new CacheContinuousQueryEntry(
+ cctx.cacheId(),
+ EXPIRED,
+ key,
+ null,
+ lsnr.oldValueRequired() ? oldVal : null,
+ e.partition(),
+ -1,
+ null);
CacheContinuousQueryEvent evt = new CacheContinuousQueryEvent(
cctx.kernalContext().cache().jcache(cctx.name()), cctx, e0);
@@ -373,6 +426,27 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
}
/**
+ * @param topVer Topology version.
+ */
+ public void beforeExchange(AffinityTopologyVersion topVer) {
+ for (CacheContinuousQueryListener lsnr : lsnrs.values())
+ lsnr.flushBackupQueue(cctx.kernalContext(), topVer);
+ }
+
+ /**
+ * Partition evicted callback.
+ *
+ * @param part Partition number.
+ */
+ public void onPartitionEvicted(int part) {
+ for (CacheContinuousQueryListener lsnr : lsnrs.values())
+ lsnr.onPartitionEvicted(part);
+
+ for (CacheContinuousQueryListener lsnr : intLsnrs.values())
+ lsnr.onPartitionEvicted(part);
+ }
+
+ /**
* @param locLsnr Local listener.
* @param rmtFilter Remote filter.
* @param bufSize Buffer size.
@@ -417,7 +491,8 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
sync,
ignoreExpired,
taskNameHash,
- skipPrimaryCheck);
+ skipPrimaryCheck,
+ cctx.isLocal());
IgnitePredicate<ClusterNode> pred = (loc || cctx.config().getCacheMode() == CacheMode.LOCAL) ?
F.nodeForNodeId(cctx.localNodeId()) : F.<ClusterNode>alwaysTrue();
@@ -469,10 +544,19 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
GridCacheEntryEx e = it.next();
+ CacheContinuousQueryEntry entry = new CacheContinuousQueryEntry(
+ cctx.cacheId(),
+ CREATED,
+ e.key(),
+ e.rawGet(),
+ null,
+ 0,
+ -1,
+ null);
+
next = new CacheContinuousQueryEvent<>(
cctx.kernalContext().cache().jcache(cctx.name()),
- cctx,
- new CacheContinuousQueryEntry(cctx.cacheId(), CREATED, e.key(), e.rawGet(), null));
+ cctx, entry);
if (rmtFilter != null && !rmtFilter.evaluate(next))
next = null;
@@ -590,10 +674,11 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
CacheEntryEventFilter fltr = null;
if (cfg.getCacheEntryEventFilterFactory() != null) {
- fltr = (CacheEntryEventFilter) cfg.getCacheEntryEventFilterFactory().create();
+ fltr = (CacheEntryEventFilter)cfg.getCacheEntryEventFilterFactory().create();
if (!(fltr instanceof Serializable))
- throw new IgniteCheckedException("Cache entry event filter must implement java.io.Serializable: " + fltr);
+ throw new IgniteCheckedException("Cache entry event filter must implement java.io.Serializable: "
+ + fltr);
}
CacheEntryEventSerializableFilter rmtFilter = new JCacheQueryRemoteFilter(fltr, types);
@@ -637,6 +722,7 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
/**
* @param impl Listener.
+ * @param log Logger.
*/
JCacheQueryLocalListener(CacheEntryListener<K, V> impl, IgniteLogger log) {
assert impl != null;
@@ -789,4 +875,29 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
}
}
}
+
+ /**
+ * Task flash backup queue.
+ */
+ private static final class BackupCleaner implements Runnable {
+ /** Listeners. */
+ private final Map<UUID, CacheContinuousQueryListener> lsnrs;
+
+ /** Context. */
+ private final GridKernalContext ctx;
+
+ /**
+ * @param lsnrs Listeners.
+ */
+ public BackupCleaner(Map<UUID, CacheContinuousQueryListener> lsnrs, GridKernalContext ctx) {
+ this.lsnrs = lsnrs;
+ this.ctx = ctx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void run() {
+ for (CacheContinuousQueryListener lsnr : lsnrs.values())
+ lsnr.acknowledgeBackupOnTimeout(ctx);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 23f83be..ff413d3 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
@@ -181,6 +181,10 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
*/
private byte flags;
+ /** Partition update counter. */
+ @GridDirectTransient
+ private long partUpdateCntr;
+
/** */
private GridCacheVersion serReadVer;
@@ -373,6 +377,22 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
}
/**
+ * Sets partition counter.
+ *
+ * @param partCntr Partition counter.
+ */
+ public void updateCounter(long partCntr) {
+ this.partUpdateCntr = partCntr;
+ }
+
+ /**
+ * @return Partition index.
+ */
+ public long updateCounter() {
+ return partUpdateCntr;
+ }
+
+ /**
* @param val Value to set.
*/
void setAndMarkValid(CacheObject val) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 a9846ef..63a4cbe 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
@@ -964,6 +964,9 @@ public class IgniteTxHandler {
// Complete remote candidates.
tx.doneRemote(req.baseVersion(), null, null, null);
+ tx.setPartitionUpdateCounters(
+ req.partUpdateCounters() != null ? req.partUpdateCounters().array() : null);
+
tx.commit();
}
else {
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 ecb0595..cff62d9 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
@@ -1012,7 +1012,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
cached.isNear() ? null : explicitVer,
CU.subjectId(this, cctx),
resolveTaskName(),
- dhtVer);
+ dhtVer,
+ null);
+
+ if (updRes.success())
+ txEntry.updateCounter(updRes.updatePartitionCounter());
if (nearCached != null && updRes.success()) {
nearCached.innerSet(
@@ -1032,7 +1036,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
null,
CU.subjectId(this, cctx),
resolveTaskName(),
- dhtVer);
+ dhtVer,
+ null);
}
}
else if (op == DELETE) {
@@ -1049,7 +1054,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
cached.isNear() ? null : explicitVer,
CU.subjectId(this, cctx),
resolveTaskName(),
- dhtVer);
+ dhtVer,
+ null);
+
+ if (updRes.success())
+ txEntry.updateCounter(updRes.updatePartitionCounter());
if (nearCached != null && updRes.success()) {
nearCached.innerRemove(
@@ -1065,7 +1074,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
null,
CU.subjectId(this, cctx),
resolveTaskName(),
- dhtVer);
+ dhtVer,
+ null);
}
}
else if (op == RELOAD) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
index b80909f..8ceca3f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
@@ -34,4 +34,9 @@ public interface IgniteTxRemoteEx extends IgniteInternalTx {
Collection<GridCacheVersion> committedVers,
Collection<GridCacheVersion> rolledbackVers,
Collection<GridCacheVersion> pendingVers);
-}
\ No newline at end of file
+
+ /**
+ * @param cntrs Partition update indexes.
+ */
+ public void setPartitionUpdateCounters(long[] cntrs);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatch.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatch.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatch.java
new file mode 100644
index 0000000..67b8c82
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatch.java
@@ -0,0 +1,44 @@
+/*
+ * 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.continuous;
+
+import java.util.Collection;
+
+/**
+ * Continuous routine batch.
+ */
+public interface GridContinuousBatch {
+ /**
+ * Adds element to this batch.
+ *
+ * @param obj Element to add.
+ */
+ public void add(Object obj);
+
+ /**
+ * Collects elements that are currently in this batch.
+ *
+ * @return Elements in this batch.
+ */
+ public Collection<Object> collect();
+
+ /**
+ * @return Current batch size.
+ */
+ public int size();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatchAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatchAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatchAdapter.java
new file mode 100644
index 0000000..4540de1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousBatchAdapter.java
@@ -0,0 +1,46 @@
+/*
+ * 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.continuous;
+
+import java.util.Collection;
+import org.jsr166.ConcurrentLinkedDeque8;
+
+/**
+ * Continuous routine batch adapter.
+ */
+public class GridContinuousBatchAdapter implements GridContinuousBatch {
+ /** Buffer. */
+ private final ConcurrentLinkedDeque8<Object> buf = new ConcurrentLinkedDeque8<>();
+
+ /** {@inheritDoc} */
+ @Override public void add(Object obj) {
+ assert obj != null;
+
+ buf.add(obj);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<Object> collect() {
+ return buf;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int size() {
+ return buf.sizex();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
index 30e596a..d8698b3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousHandler.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.continuous;
import java.io.Externalizable;
import java.util.Collection;
+import java.util.Map;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridKernalContext;
@@ -98,6 +99,22 @@ public interface GridContinuousHandler extends Externalizable, Cloneable {
public void p2pUnmarshal(UUID nodeId, GridKernalContext ctx) throws IgniteCheckedException;
/**
+ * Creates new batch.
+ *
+ * @return New batch.
+ */
+ public GridContinuousBatch createBatch();
+
+ /**
+ * Called when ack for a batch is received from client.
+ *
+ * @param routineId Routine ID.
+ * @param batch Acknowledged batch.
+ * @param ctx Kernal context.
+ */
+ public void onBatchAcknowledged(UUID routineId, GridContinuousBatch batch, GridKernalContext ctx);
+
+ /**
* @return Topic for ordered notifications. If {@code null}, notifications
* will be sent in non-ordered messages.
*/
@@ -129,4 +146,9 @@ public interface GridContinuousHandler extends Externalizable, Cloneable {
* @return Cache name if this is a continuous query handler.
*/
public String cacheName();
+
+ /**
+ * @param cntrs Init state for partition counters.
+ */
+ public void updateCounters(Map<Integer, Long> cntrs);
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
index d1cb3a9..c07cc13 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
@@ -35,6 +35,7 @@ import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.events.DiscoveryEvent;
import org.apache.ignite.events.Event;
@@ -52,17 +53,21 @@ import org.apache.ignite.internal.managers.discovery.CustomEventListener;
import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
import org.apache.ignite.internal.processors.GridProcessorAdapter;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
+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.internal.util.worker.GridWorker;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteFuture;
+import org.apache.ignite.lang.IgniteInClosure;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.marshaller.Marshaller;
@@ -70,7 +75,6 @@ import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.thread.IgniteThread;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
-import org.jsr166.ConcurrentLinkedDeque8;
import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
@@ -203,8 +207,38 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
StartFuture fut = startFuts.remove(msg.routineId());
if (fut != null) {
- if (msg.errs().isEmpty())
+ if (msg.errs().isEmpty()) {
+ LocalRoutineInfo routine = locInfos.get(msg.routineId());
+
+ if (routine != null) {
+ try {
+ Map<Integer, Long> cntrs = msg.updateCounters();
+
+ GridCacheAdapter<Object, Object> interCache =
+ ctx.cache().internalCache(routine.handler().cacheName());
+
+ if (interCache != null && cntrs != null && interCache.context() != null
+ && !interCache.isLocal() && !CU.clientNode(ctx.grid().localNode())) {
+ Map<Integer, Long> map = interCache.context().topology().updateCounters();
+
+ for (Map.Entry<Integer, Long> e : map.entrySet()) {
+ Long cntr0 = cntrs.get(e.getKey());
+ Long cntr1 = e.getValue();
+
+ if (cntr0 == null || cntr1 > cntr0)
+ cntrs.put(e.getKey(), cntr1);
+ }
+ }
+ }
+ catch (Exception e) {
+ U.warn(log, "Failed to load update counters.", e);
+ }
+
+ routine.handler().updateCounters(msg.updateCounters());
+ }
+
fut.onRemoteRegistered();
+ }
else {
IgniteCheckedException firstEx = F.first(msg.errs().values());
@@ -651,6 +685,30 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
/**
* @param nodeId ID of the node that started routine.
* @param routineId Routine ID.
+ * @param objs Notification objects.
+ * @param orderedTopic Topic for ordered notifications. If {@code null}, non-ordered message will be sent.
+ * @throws IgniteCheckedException In case of error.
+ */
+ public void addBackupNotification(UUID nodeId,
+ final UUID routineId,
+ Collection<?> objs,
+ @Nullable Object orderedTopic)
+ throws IgniteCheckedException {
+ if (processorStopped)
+ return;
+
+ final RemoteRoutineInfo info = rmtInfos.get(routineId);
+
+ if (info != null) {
+ final GridContinuousBatch batch = info.addAll(objs);
+
+ sendNotification(nodeId, routineId, null, batch.collect(), orderedTopic, true, null);
+ }
+ }
+
+ /**
+ * @param nodeId ID of the node that started routine.
+ * @param routineId Routine ID.
* @param obj Notification object.
* @param orderedTopic Topic for ordered notifications. If {@code null}, non-ordered message will be sent.
* @param sync If {@code true} then waits for event acknowledgment.
@@ -658,7 +716,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
* @throws IgniteCheckedException In case of error.
*/
public void addNotification(UUID nodeId,
- UUID routineId,
+ final UUID routineId,
@Nullable Object obj,
@Nullable Object orderedTopic,
boolean sync,
@@ -673,7 +731,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
if (processorStopped)
return;
- RemoteRoutineInfo info = rmtInfos.get(routineId);
+ final RemoteRoutineInfo info = rmtInfos.get(routineId);
if (info != null) {
assert info.interval == 0 || !sync;
@@ -686,7 +744,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
syncMsgFuts.put(futId, fut);
try {
- sendNotification(nodeId, routineId, futId, F.asList(obj), orderedTopic, msg);
+ sendNotification(nodeId, routineId, futId, F.asList(obj), orderedTopic, msg, null);
}
catch (IgniteCheckedException e) {
syncMsgFuts.remove(futId);
@@ -697,10 +755,18 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
fut.get();
}
else {
- Collection<Object> toSnd = info.add(obj);
+ final GridContinuousBatch batch = info.add(obj);
+
+ if (batch != null) {
+ CI1<IgniteException> ackC = new CI1<IgniteException>() {
+ @Override public void apply(IgniteException e) {
+ if (e == null)
+ info.hnd.onBatchAcknowledged(routineId, batch, ctx);
+ }
+ };
- if (toSnd != null)
- sendNotification(nodeId, routineId, null, toSnd, orderedTopic, msg);
+ sendNotification(nodeId, routineId, null, batch.collect(), orderedTopic, msg, ackC);
+ }
}
}
}
@@ -725,6 +791,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
* @param orderedTopic Topic for ordered notifications.
* If {@code null}, non-ordered message will be sent.
* @param msg If {@code true} then sent data is collection of messages.
+ * @param ackC Ack closure.
* @throws IgniteCheckedException In case of error.
*/
private void sendNotification(UUID nodeId,
@@ -732,7 +799,8 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
@Nullable IgniteUuid futId,
Collection<Object> toSnd,
@Nullable Object orderedTopic,
- boolean msg) throws IgniteCheckedException {
+ boolean msg,
+ IgniteInClosure<IgniteException> ackC) throws IgniteCheckedException {
assert nodeId != null;
assert routineId != null;
assert toSnd != null;
@@ -740,7 +808,8 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
sendWithRetries(nodeId,
new GridContinuousMessage(MSG_EVT_NOTIFICATION, routineId, futId, toSnd, msg),
- orderedTopic);
+ orderedTopic,
+ ackC);
}
/**
@@ -819,6 +888,18 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
}
}
+ try {
+ if (ctx.cache() != null && ctx.cache().internalCache(hnd.cacheName()) != null) {
+ Map<Integer, Long> cntrs = ctx.cache().internalCache(hnd.cacheName())
+ .context().topology().updateCounters();
+
+ req.addUpdateCounters(cntrs);
+ }
+ }
+ catch (Exception e) {
+ U.warn(log, "Failed to load partition counters.");
+ }
+
if (err != null)
req.addError(ctx.localNodeId(), err);
@@ -859,6 +940,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
try {
sendWithRetries(nodeId,
new GridContinuousMessage(MSG_EVT_ACK, null, msg.futureId(), null, false),
+ null,
null);
}
catch (IgniteCheckedException e) {
@@ -922,15 +1004,30 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
break;
}
- IgniteBiTuple<Collection<Object>, Long> t = info.checkInterval();
+ IgniteBiTuple<GridContinuousBatch, Long> t = info.checkInterval();
- Collection<Object> toSnd = t.get1();
+ final GridContinuousBatch batch = t.get1();
- if (toSnd != null && !toSnd.isEmpty()) {
+ if (batch != null && batch.size() > 0) {
try {
+ Collection<Object> toSnd = batch.collect();
+
boolean msg = toSnd.iterator().next() instanceof Message;
- sendNotification(nodeId, routineId, null, toSnd, hnd.orderedTopic(), msg);
+ CI1<IgniteException> ackC = new CI1<IgniteException>() {
+ @Override public void apply(IgniteException e) {
+ if (e == null)
+ info.hnd.onBatchAcknowledged(routineId, batch, ctx);
+ }
+ };
+
+ sendNotification(nodeId,
+ routineId,
+ null,
+ toSnd,
+ hnd.orderedTopic(),
+ msg,
+ ackC);
}
catch (ClusterTopologyCheckedException ignored) {
if (log.isDebugEnabled())
@@ -1013,9 +1110,11 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
* @param msg Message.
* @param orderedTopic Topic for ordered notifications.
* If {@code null}, non-ordered message will be sent.
+ * @param ackC Ack closure.
* @throws IgniteCheckedException In case of error.
*/
- private void sendWithRetries(UUID nodeId, GridContinuousMessage msg, @Nullable Object orderedTopic)
+ private void sendWithRetries(UUID nodeId, GridContinuousMessage msg, @Nullable Object orderedTopic,
+ IgniteInClosure<IgniteException> ackC)
throws IgniteCheckedException {
assert nodeId != null;
assert msg != null;
@@ -1023,7 +1122,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
ClusterNode node = ctx.discovery().node(nodeId);
if (node != null)
- sendWithRetries(node, msg, orderedTopic);
+ sendWithRetries(node, msg, orderedTopic, ackC);
else
throw new ClusterTopologyCheckedException("Node for provided ID doesn't exist (did it leave the grid?): " + nodeId);
}
@@ -1033,14 +1132,15 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
* @param msg Message.
* @param orderedTopic Topic for ordered notifications.
* If {@code null}, non-ordered message will be sent.
+ * @param ackC Ack closure.
* @throws IgniteCheckedException In case of error.
*/
- private void sendWithRetries(ClusterNode node, GridContinuousMessage msg, @Nullable Object orderedTopic)
- throws IgniteCheckedException {
+ private void sendWithRetries(ClusterNode node, GridContinuousMessage msg, @Nullable Object orderedTopic,
+ IgniteInClosure<IgniteException> ackC) throws IgniteCheckedException {
assert node != null;
assert msg != null;
- sendWithRetries(F.asList(node), msg, orderedTopic);
+ sendWithRetries(F.asList(node), msg, orderedTopic, ackC);
}
/**
@@ -1048,10 +1148,11 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
* @param msg Message.
* @param orderedTopic Topic for ordered notifications.
* If {@code null}, non-ordered message will be sent.
+ * @param ackC Ack closure.
* @throws IgniteCheckedException In case of error.
*/
private void sendWithRetries(Collection<? extends ClusterNode> nodes, GridContinuousMessage msg,
- @Nullable Object orderedTopic) throws IgniteCheckedException {
+ @Nullable Object orderedTopic, IgniteInClosure<IgniteException> ackC) throws IgniteCheckedException {
assert !F.isEmpty(nodes);
assert msg != null;
@@ -1074,10 +1175,11 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
msg,
SYSTEM_POOL,
0,
- true);
+ true,
+ ackC);
}
else
- ctx.io().send(node, TOPIC_CONTINUOUS, msg, SYSTEM_POOL);
+ ctx.io().send(node, TOPIC_CONTINUOUS, msg, SYSTEM_POOL, ackC);
break;
}
@@ -1178,8 +1280,8 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
/** Lock. */
private final ReadWriteLock lock = new ReentrantReadWriteLock();
- /** Buffer. */
- private ConcurrentLinkedDeque8<Object> buf;
+ /** Batch. */
+ private GridContinuousBatch batch;
/** Last send time. */
private long lastSndTime = U.currentTimeMillis();
@@ -1210,7 +1312,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
this.interval = interval;
this.autoUnsubscribe = autoUnsubscribe;
- buf = new ConcurrentLinkedDeque8<>();
+ batch = hnd.createBatch();
}
/**
@@ -1238,21 +1340,53 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
}
/**
+ * @param objs Objects to add.
+ * @return Batch to send.
+ */
+ GridContinuousBatch addAll(Collection<?> objs) {
+ assert objs != null;
+ assert objs.size() > 0;
+
+ GridContinuousBatch toSnd = null;
+
+ lock.writeLock().lock();
+
+ try {
+ for (Object obj : objs)
+ batch.add(obj);
+
+ toSnd = batch;
+
+ batch = hnd.createBatch();
+
+ if (interval > 0)
+ lastSndTime = U.currentTimeMillis();
+ }
+ finally {
+ lock.writeLock().unlock();
+ }
+
+ return toSnd;
+ }
+
+ /**
* @param obj Object to add.
- * @return Object to send or {@code null} if there is nothing to send for now.
+ * @return Batch to send or {@code null} if there is nothing to send for now.
*/
- @Nullable Collection<Object> add(@Nullable Object obj) {
- ConcurrentLinkedDeque8 buf0 = null;
+ @Nullable GridContinuousBatch add(Object obj) {
+ assert obj != null;
+
+ GridContinuousBatch toSnd = null;
- if (buf.sizex() >= bufSize - 1) {
+ if (batch.size() >= bufSize - 1) {
lock.writeLock().lock();
try {
- buf.add(obj);
+ batch.add(obj);
- buf0 = buf;
+ toSnd = batch;
- buf = new ConcurrentLinkedDeque8<>();
+ batch = hnd.createBatch();
if (interval > 0)
lastSndTime = U.currentTimeMillis();
@@ -1265,34 +1399,25 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
lock.readLock().lock();
try {
- buf.add(obj);
+ batch.add(obj);
}
finally {
lock.readLock().unlock();
}
}
- Collection<Object> toSnd = null;
-
- if (buf0 != null) {
- toSnd = new ArrayList<>(buf0.sizex());
-
- for (Object o : buf0)
- toSnd.add(o);
- }
-
return toSnd;
}
/**
- * @return Tuple with objects to sleep (or {@code null} if there is nothing to
+ * @return Tuple with batch to send (or {@code null} if there is nothing to
* send for now) and time interval after next check is needed.
*/
@SuppressWarnings("TooBroadScope")
- IgniteBiTuple<Collection<Object>, Long> checkInterval() {
+ IgniteBiTuple<GridContinuousBatch, Long> checkInterval() {
assert interval > 0;
- Collection<Object> toSnd = null;
+ GridContinuousBatch toSnd = null;
long diff;
long now = U.currentTimeMillis();
@@ -1302,10 +1427,10 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
try {
diff = now - lastSndTime;
- if (diff >= interval && !buf.isEmpty()) {
- toSnd = buf;
+ if (diff >= interval && batch.size() > 0) {
+ toSnd = batch;
- buf = new ConcurrentLinkedDeque8<>();
+ batch = hnd.createBatch();
lastSndTime = now;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineAckDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineAckDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineAckDiscoveryMessage.java
index bd4aae3..9644372 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineAckDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineAckDiscoveryMessage.java
@@ -35,14 +35,19 @@ public class StartRoutineAckDiscoveryMessage extends AbstractContinuousMessage {
/** */
private final Map<UUID, IgniteCheckedException> errs;
+ /** */
+ private final Map<Integer, Long> updateCntrs;
+
/**
* @param routineId Routine id.
* @param errs Errs.
*/
- public StartRoutineAckDiscoveryMessage(UUID routineId, Map<UUID, IgniteCheckedException> errs) {
+ public StartRoutineAckDiscoveryMessage(UUID routineId, Map<UUID, IgniteCheckedException> errs,
+ Map<Integer, Long> cntrs) {
super(routineId);
this.errs = new HashMap<>(errs);
+ this.updateCntrs = cntrs;
}
/** {@inheritDoc} */
@@ -51,6 +56,13 @@ public class StartRoutineAckDiscoveryMessage extends AbstractContinuousMessage {
}
/**
+ * @return Update counters for partitions.
+ */
+ public Map<Integer, Long> updateCounters() {
+ return updateCntrs;
+ }
+
+ /**
* @return Errs.
*/
public Map<UUID, IgniteCheckedException> errs() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
index 892adac..82c0377 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
@@ -37,6 +37,9 @@ public class StartRoutineDiscoveryMessage extends AbstractContinuousMessage {
/** */
private final Map<UUID, IgniteCheckedException> errs = new HashMap<>();
+ /** */
+ private Map<Integer, Long> updateCntrs;
+
/**
* @param routineId Routine id.
* @param startReqData Start request data.
@@ -63,6 +66,22 @@ public class StartRoutineDiscoveryMessage extends AbstractContinuousMessage {
}
/**
+ * @param cntrs Update counters.
+ */
+ public void addUpdateCounters(Map<Integer, Long> cntrs) {
+ if (updateCntrs == null)
+ updateCntrs = new HashMap<>();
+
+ for (Map.Entry<Integer, Long> e : cntrs.entrySet()) {
+ Long cntr0 = updateCntrs.get(e.getKey());
+ Long cntr1 = e.getValue();
+
+ if (cntr0 == null || cntr1 > cntr0)
+ updateCntrs.put(e.getKey(), cntr1);
+ }
+ }
+
+ /**
* @return Errs.
*/
public Map<UUID, IgniteCheckedException> errs() {
@@ -76,7 +95,7 @@ public class StartRoutineDiscoveryMessage extends AbstractContinuousMessage {
/** {@inheritDoc} */
@Override public DiscoveryCustomMessage ackMessage() {
- return new StartRoutineAckDiscoveryMessage(routineId, errs);
+ return new StartRoutineAckDiscoveryMessage(routineId, errs, updateCntrs);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 b93acf5..97696bb 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
@@ -479,7 +479,8 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
@Nullable GridCacheVersion drVer,
UUID subjId,
String taskName,
- @Nullable GridCacheVersion dhtVer)
+ @Nullable GridCacheVersion dhtVer,
+ @Nullable Long updateCntr)
throws IgniteCheckedException, GridCacheEntryRemovedException {
return new GridCacheUpdateTxResult(true, rawPut(val, ttl));
}
@@ -529,7 +530,9 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
boolean conflictResolve,
boolean intercept,
UUID subjId,
- String taskName) throws IgniteCheckedException,
+ String taskName,
+ @Nullable CacheObject prevVal,
+ @Nullable Long updateCntr) throws IgniteCheckedException,
GridCacheEntryRemovedException {
assert false;
@@ -550,7 +553,8 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
@Nullable GridCacheVersion drVer,
UUID subjId,
String taskName,
- @Nullable GridCacheVersion dhtVer
+ @Nullable GridCacheVersion dhtVer,
+ @Nullable Long updateCntr
) throws IgniteCheckedException, GridCacheEntryRemovedException {
obsoleteVer = ver;
[23/23] ignite git commit: ignite-sql-opt
Posted by sb...@apache.org.
ignite-sql-opt
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d46109fc
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d46109fc
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d46109fc
Branch: refs/heads/ignite-sql-opt
Commit: d46109fc46107e9997bba105ad71511a1a8bd7f4
Parents: f939df4
Author: sboikov <sb...@gridgain.com>
Authored: Fri Nov 20 08:47:46 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Fri Nov 20 08:48:35 2015 +0300
----------------------------------------------------------------------
.../processors/query/GridQueryProcessor.java | 51 ++------------------
.../query/GridQueryTypeDescriptor.java | 2 -
.../processors/query/h2/IgniteH2Indexing.java | 14 +-----
.../h2/GridIndexingSpiAbstractSelfTest.java | 6 ---
.../cache/IgniteSqlQueryBenchmark.java | 5 +-
5 files changed, 8 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/d46109fc/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 910bfb0..84db145 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -60,7 +60,6 @@ import org.apache.ignite.internal.processors.cache.query.CacheQueryFuture;
import org.apache.ignite.internal.processors.cache.query.CacheQueryType;
import org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery;
import org.apache.ignite.internal.util.GridSpinBusyLock;
-import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.lang.GridCloseableIterator;
@@ -79,7 +78,6 @@ import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.spi.indexing.IndexingQueryFilter;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
-import sun.misc.Unsafe;
import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_EXECUTED;
import static org.apache.ignite.internal.IgniteComponentType.INDEXING;
@@ -1541,7 +1539,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
/**
*
*/
- public abstract static class Property {
+ private abstract static class Property {
/**
* Gets this property value from the given object.
*
@@ -1563,12 +1561,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
public abstract Class<?> type();
}
- enum FieldType {
- INT,
- DOUBLE,
- OBJ
- }
-
/**
* Description of type property.
*/
@@ -1588,12 +1580,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
/** */
private boolean key;
- private static Unsafe unsafe = GridUnsafe.unsafe();
-
- private long off;
-
- private FieldType type;
-
/**
* Constructor.
*
@@ -1609,21 +1595,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
((AccessibleObject) member).setAccessible(true);
field = member instanceof Field;
-
- if (field) {
- Field field0 = (Field) member;
-
- Class<?> t = field0.getType();
-
- if (t.equals(int.class))
- type = FieldType.INT;
- else if (t.equals(double.class))
- type = FieldType.DOUBLE;
- else
- type = FieldType.OBJ;
-
- off = unsafe.objectFieldOffset(field0);
- }
}
/** {@inheritDoc} */
@@ -1638,18 +1609,9 @@ public class GridQueryProcessor extends GridProcessorAdapter {
try {
if (field) {
- switch (type) {
- case INT:
- return unsafe.getInt(x, off);
- case DOUBLE:
- return unsafe.getDouble(x, off);
- case OBJ:
- return unsafe.getObject(x, off);
- }
- return null;
-// Field field = (Field)member;
-//
-// return field.get(x);
+ Field field = (Field)member;
+
+ return field.get(x);
}
else {
Method mtd = (Method)member;
@@ -1845,11 +1807,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
return fields;
}
- @Override
- public Property property(String name) {
- return props.get(name);
- }
-
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override public <T> T value(String field, Object key, Object val) throws IgniteCheckedException {
http://git-wip-us.apache.org/repos/asf/ignite/blob/d46109fc/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
index 3b16274..b05e1d8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
@@ -38,8 +38,6 @@ public interface GridQueryTypeDescriptor {
*/
public Map<String, Class<?>> fields();
- public GridQueryProcessor.Property property(String name);
-
/**
* Gets field value for given key and value.
*
http://git-wip-us.apache.org/repos/asf/ignite/blob/d46109fc/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index f6ea9f6..4c07132 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -79,7 +79,6 @@ import org.apache.ignite.internal.processors.query.GridQueryFieldsResult;
import org.apache.ignite.internal.processors.query.GridQueryFieldsResultAdapter;
import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
import org.apache.ignite.internal.processors.query.GridQueryIndexing;
-import org.apache.ignite.internal.processors.query.GridQueryProcessor;
import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueRowOffheap;
@@ -174,7 +173,7 @@ import static org.h2.result.SortOrder.DESCENDING;
public class IgniteH2Indexing implements GridQueryIndexing {
/** Default DB options. */
private static final String DB_OPTIONS = ";LOCK_MODE=3;MULTI_THREADED=1;DB_CLOSE_ON_EXIT=FALSE" +
- ";DEFAULT_LOCK_TIMEOUT=10000;FUNCTIONS_IN_SCHEMA=true;OPTIMIZE_REUSE_RESULTS=0;QUERY_CACHE_SIZE=100;" +
+ ";DEFAULT_LOCK_TIMEOUT=10000;FUNCTIONS_IN_SCHEMA=true;OPTIMIZE_REUSE_RESULTS=0;QUERY_CACHE_SIZE=0;" +
"RECOMPILE_ALWAYS=1;MAX_OPERATION_MEMORY=0";
/** Field name for key. */
@@ -2111,9 +2110,6 @@ public class IgniteH2Indexing implements GridQueryIndexing {
/** */
private final boolean preferSwapVal;
- /** */
- private final GridQueryProcessor.Property[] properties;
-
/**
* @param type Type descriptor.
* @param schema Schema.
@@ -2144,11 +2140,6 @@ public class IgniteH2Indexing implements GridQueryIndexing {
valType = DataType.getTypeFromClass(type.valueClass());
preferSwapVal = schema.ccfg.getMemoryMode() == CacheMemoryMode.OFFHEAP_TIERED;
-
- properties = new GridQueryProcessor.Property[fields.length];
-
- for (int i = 0; i < fields.length; i++)
- properties[i] = type.property(fields[i]);
}
/** {@inheritDoc} */
@@ -2302,8 +2293,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
/** {@inheritDoc} */
@Override public Object columnValue(Object key, Object val, int col) {
try {
- return properties[col].value(key, val);
- //return type.value(fields[col], key, val);
+ return type.value(fields[col], key, val);
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
http://git-wip-us.apache.org/repos/asf/ignite/blob/d46109fc/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index f635df7..acfe3b6 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -34,7 +34,6 @@ import org.apache.ignite.internal.processors.cache.CacheObjectContext;
import org.apache.ignite.internal.processors.query.GridQueryFieldsResult;
import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
import org.apache.ignite.internal.processors.query.GridQueryIndexType;
-import org.apache.ignite.internal.processors.query.GridQueryProcessor;
import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -505,11 +504,6 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
return valFields;
}
- @Override
- public GridQueryProcessor.Property property(String name) {
- return null;
- }
-
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override public <T> T value(String field, Object key, Object val) throws IgniteSpiException {
http://git-wip-us.apache.org/repos/asf/ignite/blob/d46109fc/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
index 4c0f670..8e31455 100644
--- a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
@@ -64,10 +64,9 @@ public class IgniteSqlQueryBenchmark extends IgniteCacheAbstractBenchmark<Intege
for (Cache.Entry<Integer, Object> entry : entries) {
Person p = (Person)entry.getValue();
- if (p.getSalary() < salary || p.getSalary() > maxSalary) {
+ if (p.getSalary() < salary || p.getSalary() > maxSalary)
throw new Exception("Invalid person retrieved [min=" + salary + ", max=" + maxSalary +
- ", person=" + p + ']');
- }
+ ", person=" + p + ']');
}
return true;
[10/23] ignite git commit: Fix existing typos and coding guidelines
violations.
Posted by sb...@apache.org.
Fix existing typos and coding guidelines violations.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f0db0d9f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f0db0d9f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f0db0d9f
Branch: refs/heads/ignite-sql-opt
Commit: f0db0d9fa579dda394a470aa1a314ed2b5c60a2d
Parents: 1f10306
Author: Raul Kripalani <ra...@apache.org>
Authored: Thu Nov 19 14:35:42 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Thu Nov 19 14:35:49 2015 +0000
----------------------------------------------------------------------
modules/core/src/main/java/org/apache/ignite/IgniteCache.java | 3 ++-
modules/core/src/main/java/org/apache/ignite/IgniteCompute.java | 3 ++-
.../core/src/main/java/org/apache/ignite/compute/ComputeJob.java | 2 +-
.../java/org/apache/ignite/marshaller/MarshallerExclusions.java | 4 ++--
4 files changed, 7 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/f0db0d9f/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
index 6c4b507..0b7f368 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
@@ -325,7 +325,8 @@ public interface IgniteCache<K, V> extends javax.cache.Cache<K, V>, IgniteAsyncS
* <code>null</code> value for a key.
*/
@IgniteAsyncSupported
- <T> Map<K, EntryProcessorResult<T>> invokeAll(Map<? extends K, ? extends EntryProcessor<K, V, T>> map, Object... args);
+ <T> Map<K, EntryProcessorResult<T>> invokeAll(Map<? extends K, ? extends EntryProcessor<K, V, T>> map,
+ Object... args);
/** {@inheritDoc} */
@IgniteAsyncSupported
http://git-wip-us.apache.org/repos/asf/ignite/blob/f0db0d9f/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java b/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java
index 9aa4b87..f7d4bc5 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java
@@ -272,7 +272,8 @@ public interface IgniteCompute extends IgniteAsyncSupport {
* @throws IgniteException If execution failed.
*/
@IgniteAsyncSupported
- public <R1, R2> R2 call(Collection<? extends IgniteCallable<R1>> jobs, IgniteReducer<R1, R2> rdc) throws IgniteException;
+ public <R1, R2> R2 call(Collection<? extends IgniteCallable<R1>> jobs, IgniteReducer<R1, R2> rdc)
+ throws IgniteException;
/**
* Executes provided closure job on a node within the underlying cluster group. This method is different
http://git-wip-us.apache.org/repos/asf/ignite/blob/f0db0d9f/modules/core/src/main/java/org/apache/ignite/compute/ComputeJob.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/compute/ComputeJob.java b/modules/core/src/main/java/org/apache/ignite/compute/ComputeJob.java
index d8664e8..9558255 100644
--- a/modules/core/src/main/java/org/apache/ignite/compute/ComputeJob.java
+++ b/modules/core/src/main/java/org/apache/ignite/compute/ComputeJob.java
@@ -142,7 +142,7 @@ public interface ComputeJob extends Serializable {
* {@link ComputeTaskFuture#cancel()} is called.
* <p>
* Note that job cancellation is only a hint, and just like with
- * {@link Thread#interrupt()} method, it is really up to the actual job
+ * {@link Thread#interrupt()} method, it is really up to the actual job
* instance to gracefully finish execution and exit.
*/
public void cancel();
http://git-wip-us.apache.org/repos/asf/ignite/blob/f0db0d9f/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerExclusions.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerExclusions.java b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerExclusions.java
index 2701ead..fba35e2 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerExclusions.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerExclusions.java
@@ -41,7 +41,7 @@ public final class MarshallerExclusions {
* Classes that must be included in serialization. All marshallers must
* included these classes.
* <p>
- * Note that this list supercedes {@link #EXCL_CLASSES}.
+ * Note that this list supersedes {@link #EXCL_CLASSES}.
*/
private static final Class<?>[] INCL_CLASSES = new Class[] {
// Ignite classes.
@@ -57,7 +57,7 @@ public final class MarshallerExclusions {
* Excluded grid classes from serialization. All marshallers must omit
* these classes. Fields of these types should be serialized as {@code null}.
* <p>
- * Note that {@link #INCL_CLASSES} supercedes this list.
+ * Note that {@link #INCL_CLASSES} supersedes this list.
*/
private static final Class<?>[] EXCL_CLASSES;
[11/23] ignite git commit: IGNITE-529 Readme fix
Posted by sb...@apache.org.
IGNITE-529 Readme fix
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/dae3de0b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/dae3de0b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/dae3de0b
Branch: refs/heads/ignite-sql-opt
Commit: dae3de0b72afd7dc0a0e32db3c5c6015166cb80f
Parents: ba1d563
Author: Anton Vinogradov <av...@apache.org>
Authored: Thu Nov 19 17:42:12 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Thu Nov 19 17:42:12 2015 +0300
----------------------------------------------------------------------
modules/flume/README.md | 40 ------------------------
modules/flume/README.txt | 72 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/dae3de0b/modules/flume/README.md
----------------------------------------------------------------------
diff --git a/modules/flume/README.md b/modules/flume/README.md
deleted file mode 100644
index 2247cf3..0000000
--- a/modules/flume/README.md
+++ /dev/null
@@ -1,40 +0,0 @@
-#Flume NG sink
-
-## Setting up and running
-
-1. Create a transformer by implementing EventTransformer interface.
-2. Build it and copy to ${FLUME_HOME}/plugins.d/ignite-sink/lib.
-3. Copy other Ignite-related jar files to ${FLUME_HOME}/plugins.d/ignite-sink/libext to have them as shown below.
-
-```
-plugins.d/
-`-- ignite
- |-- lib
- | `-- ignite-flume-transformer-x.x.x.jar <-- your jar
- `-- libext
- |-- cache-api-1.0.0.jar
- |-- ignite-core-x.x.x.jar
- |-- ignite-flume-x.x.x.jar
- |-- ignite-spring-x.x.x.jar
- |-- spring-aop-4.1.0.RELEASE.jar
- |-- spring-beans-4.1.0.RELEASE.jar
- |-- spring-context-4.1.0.RELEASE.jar
- |-- spring-core-4.1.0.RELEASE.jar
- `-- spring-expression-4.1.0.RELEASE.jar
-```
-
-4. In Flume configuration file, specify Ignite configuration XML file's location with cache properties
-(see [Apache Ignite](https://apacheignite.readme.io/) with cache name specified for cache creation,
-cache name (same as in Ignite configuration file), your EventTransformer's implementation class,
-and, optionally, batch size (default -- 100).
-
-```
-# Describe the sink
-a1.sinks.k1.type = org.apache.ignite.stream.flume.IgniteSink
-a1.sinks.k1.igniteCfg = /some-path/ignite.xml
-a1.sinks.k1.cacheName = testCache
-a1.sinks.k1.eventTransformer = my.company.MyEventTransformer
-a1.sinks.k1.batchSize = 100
-```
-
-After specifying your source and channel (see Flume's docs), you are ready to run a Flume agent.
http://git-wip-us.apache.org/repos/asf/ignite/blob/dae3de0b/modules/flume/README.txt
----------------------------------------------------------------------
diff --git a/modules/flume/README.txt b/modules/flume/README.txt
new file mode 100644
index 0000000..5b574e3
--- /dev/null
+++ b/modules/flume/README.txt
@@ -0,0 +1,72 @@
+Apache Ignite Flume Streamer Module
+------------------------
+
+Apache Ignite Flume Streamer module provides streaming from Flume to Ignite cache.
+
+To enable Flume Streamer module when starting a standalone node, move 'optional/ignite-Flume' folder to
+'libs' folder before running 'ignite.{sh|bat}' script. The content of the module folder will
+be added to classpath in this case.
+
+Importing Ignite Flume Streamer Module In Maven Project
+-------------------------------------
+
+If you are using Maven to manage dependencies of your project, you can add JCL module
+dependency like this (replace '${ignite.version}' with actual Ignite version you are
+interested in):
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ ...
+ <dependencies>
+ ...
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-Flume</artifactId>
+ <version>${ignite.version}</version>
+ </dependency>
+ ...
+ </dependencies>
+ ...
+</project>
+
+
+## Setting up and running
+
+1. Create a transformer by implementing EventTransformer interface.
+2. Build it and copy to ${FLUME_HOME}/plugins.d/ignite-sink/lib.
+3. Copy other Ignite-related jar files to ${FLUME_HOME}/plugins.d/ignite-sink/libext to have them as shown below.
+
+```
+plugins.d/
+`-- ignite
+ |-- lib
+ | `-- ignite-flume-transformer-x.x.x.jar <-- your jar
+ `-- libext
+ |-- cache-api-1.0.0.jar
+ |-- ignite-core-x.x.x.jar
+ |-- ignite-flume-x.x.x.jar
+ |-- ignite-spring-x.x.x.jar
+ |-- spring-aop-4.1.0.RELEASE.jar
+ |-- spring-beans-4.1.0.RELEASE.jar
+ |-- spring-context-4.1.0.RELEASE.jar
+ |-- spring-core-4.1.0.RELEASE.jar
+ `-- spring-expression-4.1.0.RELEASE.jar
+```
+
+4. In Flume configuration file, specify Ignite configuration XML file's location with cache properties
+(see [Apache Ignite](https://apacheignite.readme.io/) with cache name specified for cache creation,
+cache name (same as in Ignite configuration file), your EventTransformer's implementation class,
+and, optionally, batch size (default -- 100).
+
+```
+# Describe the sink
+a1.sinks.k1.type = org.apache.ignite.stream.flume.IgniteSink
+a1.sinks.k1.igniteCfg = /some-path/ignite.xml
+a1.sinks.k1.cacheName = testCache
+a1.sinks.k1.eventTransformer = my.company.MyEventTransformer
+a1.sinks.k1.batchSize = 100
+```
+
+After specifying your source and channel (see Flume's docs), you are ready to run a Flume agent.
[04/23] ignite git commit: ignite-sql-opt
Posted by sb...@apache.org.
ignite-sql-opt
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/da3af86b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/da3af86b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/da3af86b
Branch: refs/heads/ignite-sql-opt
Commit: da3af86bb113c742e33e015eefa5094a80190f19
Parents: 930166c
Author: sboikov <sb...@gridgain.com>
Authored: Thu Nov 19 15:14:36 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Nov 19 15:14:36 2015 +0300
----------------------------------------------------------------------
.../apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/da3af86b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
index d5f6f4f..4c0f670 100644
--- a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteSqlQueryBenchmark.java
@@ -65,8 +65,8 @@ public class IgniteSqlQueryBenchmark extends IgniteCacheAbstractBenchmark<Intege
Person p = (Person)entry.getValue();
if (p.getSalary() < salary || p.getSalary() > maxSalary) {
-// throw new Exception("Invalid person retrieved [min=" + salary + ", max=" + maxSalary +
-// ", person=" + p + ']');
+ throw new Exception("Invalid person retrieved [min=" + salary + ", max=" + maxSalary +
+ ", person=" + p + ']');
}
}
[18/23] ignite git commit: IGNITE-426 Implemented failover for
Continuous query.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAbstractSelfTest.java
new file mode 100644
index 0000000..b311272
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAbstractSelfTest.java
@@ -0,0 +1,2235 @@
+/*
+ * 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.query.continuous;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+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 java.util.concurrent.atomic.AtomicReference;
+import javax.cache.Cache;
+import javax.cache.CacheException;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.CacheEntryUpdatedListener;
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.MutableEntry;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheEntryEventSerializableFilter;
+import org.apache.ignite.cache.CacheEntryProcessor;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.affinity.Affinity;
+import org.apache.ignite.cache.query.ContinuousQuery;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.cluster.ClusterTopologyException;
+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.IgniteKernal;
+import org.apache.ignite.internal.managers.communication.GridIoMessage;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
+import org.apache.ignite.internal.processors.continuous.GridContinuousHandler;
+import org.apache.ignite.internal.processors.continuous.GridContinuousMessage;
+import org.apache.ignite.internal.processors.continuous.GridContinuousProcessor;
+import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.internal.util.typedef.C1;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.PA;
+import org.apache.ignite.internal.util.typedef.PAX;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.T3;
+import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.lang.IgniteOutClosure;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.resources.LoggerResource;
+import org.apache.ignite.spi.IgniteSpiException;
+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;
+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 org.apache.ignite.transactions.Transaction;
+
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.PRIMARY;
+import static org.apache.ignite.cache.CacheMode.REPLICATED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public abstract class CacheContinuousQueryFailoverAbstractSelfTest extends GridCommonAbstractTest {
+ /** */
+ private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ private static final int BACKUP_ACK_THRESHOLD = 100;
+
+ /** */
+ private static volatile boolean err;
+
+ /** */
+ private boolean client;
+
+ /** */
+ private int backups = 1;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+ ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setForceServerMode(true);
+ ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder);
+
+ TestCommunicationSpi commSpi = new TestCommunicationSpi();
+
+ commSpi.setSharedMemoryPort(-1);
+ commSpi.setIdleConnectionTimeout(100);
+
+ cfg.setCommunicationSpi(commSpi);
+
+ CacheConfiguration ccfg = new CacheConfiguration();
+
+ ccfg.setCacheMode(cacheMode());
+ ccfg.setAtomicityMode(atomicityMode());
+ ccfg.setAtomicWriteOrderMode(writeOrderMode());
+ ccfg.setBackups(backups);
+ ccfg.setWriteSynchronizationMode(FULL_SYNC);
+ ccfg.setNearConfiguration(nearCacheConfiguration());
+
+ cfg.setCacheConfiguration(ccfg);
+
+ cfg.setClientMode(client);
+
+ return cfg;
+ }
+
+ /**
+ * @return Near cache configuration.
+ */
+ protected NearCacheConfiguration nearCacheConfiguration() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected long getTestTimeout() {
+ return 5 * 60_000;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ err = false;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ stopAllGrids();
+ }
+
+ /**
+ * @return Cache mode.
+ */
+ protected abstract CacheMode cacheMode();
+
+ /**
+ * @return Atomicity mode.
+ */
+ protected abstract CacheAtomicityMode atomicityMode();
+
+ /**
+ * @return Write order mode for atomic cache.
+ */
+ protected CacheAtomicWriteOrderMode writeOrderMode() {
+ return PRIMARY;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testFirstFilteredEvent() throws Exception {
+ this.backups = 2;
+
+ final int SRV_NODES = 4;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ IgniteCache<Object, Object> qryClnCache = qryClient.cache(null);
+
+ final CacheEventListener3 lsnr = new CacheEventListener3();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ qry.setRemoteFilter(new CacheEventFilter());
+
+ try (QueryCursor<?> cur = qryClnCache.query(qry)) {
+ List<Integer> keys = testKeys(grid(0).cache(null), 1);
+
+ for (Integer key : keys)
+ qryClnCache.put(key, -1);
+
+ qryClnCache.put(keys.get(0), 100);
+ }
+
+ assertEquals(lsnr.evts.size(), 1);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRebalanceVersion() throws Exception {
+ Ignite ignite0 = startGrid(0);
+ GridDhtPartitionTopology top0 = ((IgniteKernal)ignite0).context().cache().context().cacheContext(1).topology();
+
+ assertTrue(top0.rebalanceFinished(new AffinityTopologyVersion(1)));
+ assertFalse(top0.rebalanceFinished(new AffinityTopologyVersion(2)));
+
+ Ignite ignite1 = startGrid(1);
+ GridDhtPartitionTopology top1 = ((IgniteKernal)ignite1).context().cache().context().cacheContext(1).topology();
+
+ waitRebalanceFinished(ignite0, 2);
+ waitRebalanceFinished(ignite1, 2);
+
+ assertFalse(top0.rebalanceFinished(new AffinityTopologyVersion(3)));
+ assertFalse(top1.rebalanceFinished(new AffinityTopologyVersion(3)));
+
+ Ignite ignite2 = startGrid(2);
+ GridDhtPartitionTopology top2 = ((IgniteKernal)ignite2).context().cache().context().cacheContext(1).topology();
+
+ waitRebalanceFinished(ignite0, 3);
+ waitRebalanceFinished(ignite1, 3);
+ waitRebalanceFinished(ignite2, 3);
+
+ assertFalse(top0.rebalanceFinished(new AffinityTopologyVersion(4)));
+ assertFalse(top1.rebalanceFinished(new AffinityTopologyVersion(4)));
+ assertFalse(top2.rebalanceFinished(new AffinityTopologyVersion(4)));
+
+ client = true;
+
+ Ignite ignite3 = startGrid(3);
+ GridDhtPartitionTopology top3 = ((IgniteKernal)ignite3).context().cache().context().cacheContext(1).topology();
+
+ assertTrue(top0.rebalanceFinished(new AffinityTopologyVersion(4)));
+ assertTrue(top1.rebalanceFinished(new AffinityTopologyVersion(4)));
+ assertTrue(top2.rebalanceFinished(new AffinityTopologyVersion(4)));
+ assertTrue(top3.rebalanceFinished(new AffinityTopologyVersion(4)));
+
+ stopGrid(1);
+
+ waitRebalanceFinished(ignite0, 5);
+ waitRebalanceFinished(ignite2, 5);
+ waitRebalanceFinished(ignite3, 5);
+ }
+
+ /**
+ * @param ignite Ignite.
+ * @param topVer Topology version.
+ * @throws Exception If failed.
+ */
+ private void waitRebalanceFinished(Ignite ignite, long topVer) throws Exception {
+ final AffinityTopologyVersion topVer0 = new AffinityTopologyVersion(topVer);
+
+ final GridDhtPartitionTopology top =
+ ((IgniteKernal)ignite).context().cache().context().cacheContext(1).topology();
+
+ GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return top.rebalanceFinished(topVer0);
+ }
+ }, 5000);
+
+ assertTrue(top.rebalanceFinished(topVer0));
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testOneBackup() throws Exception {
+ checkBackupQueue(1, false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testOneBackupClientUpdate() throws Exception {
+ checkBackupQueue(1, true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testUpdatePartitionCounter() throws Exception {
+ this.backups = 2;
+
+ final int SRV_NODES = 4;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ final Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ Map<Integer, Long> updateCntrs = new HashMap<>();
+
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ int killedNode = rnd.nextInt(SRV_NODES);
+
+ for (int i = 0; i < 10; i++) {
+ List<Integer> keys = testKeys(grid(0).cache(null), 10);
+
+ for (Integer key : keys) {
+ IgniteCache cache = null;
+
+ if (rnd.nextBoolean())
+ cache = qryClient.cache(null);
+ else {
+ for (int j = 0; j < 10; j++) {
+ int nodeIdx = rnd.nextInt(SRV_NODES);
+
+ if (killedNode != nodeIdx) {
+ cache = grid(nodeIdx).cache(null);
+
+ break;
+ }
+ }
+
+ if (cache == null)
+ throw new Exception("Failed to find a server node.");
+ }
+
+ cache.put(key, key);
+
+ int part = qryClient.affinity(null).partition(key);
+
+ Long cntr = updateCntrs.get(part);
+
+ if (cntr == null)
+ cntr = 0L;
+
+ updateCntrs.put(part, ++cntr);
+ }
+
+ checkPartCounter(SRV_NODES, killedNode, updateCntrs);
+
+ stopGrid(killedNode);
+
+ awaitPartitionMapExchange();
+
+ checkPartCounter(SRV_NODES, killedNode, updateCntrs);
+
+ startGrid(killedNode);
+
+ awaitPartitionMapExchange();
+
+ checkPartCounter(SRV_NODES, killedNode, updateCntrs);
+
+ killedNode = rnd.nextInt(SRV_NODES);
+ }
+ }
+
+ /**
+ * @param nodes Count nodes.
+ * @param killedNodeIdx Killed node index.
+ * @param updCntrs Update counters.
+ * @return {@code True} if counters matches.
+ */
+ private boolean checkPartCounter(int nodes, int killedNodeIdx, Map<Integer, Long> updCntrs) {
+ for (int i = 0; i < nodes; i++) {
+ if (i == killedNodeIdx)
+ continue;
+
+ Affinity<Object> aff = grid(i).affinity(null);
+
+ Map<Integer, Long> act = grid(i).cachex(null).context().topology().updateCounters();
+
+ for (Map.Entry<Integer, Long> e : updCntrs.entrySet()) {
+ if (aff.mapPartitionToPrimaryAndBackups(e.getKey()).contains(grid(i).localNode()))
+ assertEquals(e.getValue(), act.get(e.getKey()));
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testStartStopQuery() throws Exception {
+ this.backups = 1;
+
+ final int SRV_NODES = 3;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ final Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ IgniteCache<Object, Object> clnCache = qryClient.cache(null);
+
+ IgniteOutClosure<IgniteCache<Integer, Integer>> rndCache =
+ new IgniteOutClosure<IgniteCache<Integer, Integer>>() {
+ int cnt = 0;
+
+ @Override public IgniteCache<Integer, Integer> apply() {
+ ++cnt;
+
+ return grid(cnt % SRV_NODES + 1).cache(null);
+ }
+ };
+
+ Ignite igniteSrv = ignite(0);
+
+ IgniteCache<Object, Object> srvCache = igniteSrv.cache(null);
+
+ List<Integer> keys = testKeys(srvCache, 3);
+
+ int keyCnt = keys.size();
+
+ for (int j = 0; j < 50; ++j) {
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ final CacheEventListener3 lsnr = new CacheEventListener3();
+
+ qry.setLocalListener(lsnr);
+
+ qry.setRemoteFilter(lsnr);
+
+ int keyIter = 0;
+
+ for (; keyIter < keyCnt / 2; keyIter++) {
+ int key = keys.get(keyIter);
+
+ rndCache.apply().put(key, key);
+ }
+
+ assert lsnr.evts.isEmpty();
+
+ QueryCursor<Cache.Entry<Object, Object>> query = clnCache.query(qry);
+
+ Map<Object, T2<Object, Object>> updates = new HashMap<>();
+
+ final List<T3<Object, Object, Object>> expEvts = new ArrayList<>();
+
+ Affinity<Object> aff = affinity(srvCache);
+
+ boolean filtered = false;
+
+ for (; keyIter < keys.size(); keyIter++) {
+ int key = keys.get(keyIter);
+
+ int val = filtered ? 1 : 2;
+
+ log.info("Put [key=" + key + ", val=" + val + ", part=" + aff.partition(key) + ']');
+
+ T2<Object, Object> t = updates.get(key);
+
+ if (t == null) {
+ // Check filtered.
+ if (!filtered) {
+ updates.put(key, new T2<>((Object)val, null));
+
+ expEvts.add(new T3<>((Object)key, (Object)val, null));
+ }
+ }
+ else {
+ // Check filtered.
+ if (!filtered) {
+ updates.put(key, new T2<>((Object)val, (Object)t.get1()));
+
+ expEvts.add(new T3<>((Object)key, (Object)val, (Object)t.get1()));
+ }
+ }
+
+ rndCache.apply().put(key, val);
+
+ filtered = !filtered;
+ }
+
+ checkEvents(expEvts, lsnr, false);
+
+ query.close();
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testLeftPrimaryAndBackupNodes() throws Exception {
+ if (cacheMode() == REPLICATED)
+ return;
+
+ this.backups = 1;
+
+ final int SRV_NODES = 3;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ final Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ final CacheEventListener3 lsnr = new CacheEventListener3();
+
+ qry.setLocalListener(lsnr);
+
+ qry.setRemoteFilter(lsnr);
+
+ IgniteCache<Object, Object> clnCache = qryClient.cache(null);
+
+ QueryCursor<Cache.Entry<Object, Object>> query = clnCache.query(qry);
+
+ Ignite igniteSrv = ignite(0);
+
+ IgniteCache<Object, Object> srvCache = igniteSrv.cache(null);
+
+ Affinity<Object> aff = affinity(srvCache);
+
+ List<Integer> keys = testKeys(srvCache, 1);
+
+ Collection<ClusterNode> nodes = aff.mapPartitionToPrimaryAndBackups(keys.get(0));
+
+ Collection<UUID> ids = F.transform(nodes, new C1<ClusterNode, UUID>() {
+ @Override public UUID apply(ClusterNode node) {
+ return node.id();
+ }
+ });
+
+ int keyIter = 0;
+
+ boolean filtered = false;
+
+ Map<Object, T2<Object, Object>> updates = new HashMap<>();
+
+ final List<T3<Object, Object, Object>> expEvts = new ArrayList<>();
+
+ for (; keyIter < keys.size() / 2; keyIter++) {
+ int key = keys.get(keyIter);
+
+ log.info("Put [key=" + key + ", part=" + aff.partition(key)
+ + ", filtered=" + filtered + ']');
+
+ T2<Object, Object> t = updates.get(key);
+
+ Integer val = filtered ?
+ (key % 2 == 0 ? key + 1 : key) :
+ key * 2;
+
+ if (t == null) {
+ updates.put(key, new T2<>((Object)val, null));
+
+ if (!filtered)
+ expEvts.add(new T3<>((Object)key, (Object)val, null));
+ }
+ else {
+ updates.put(key, new T2<>((Object)val, (Object)key));
+
+ if (!filtered)
+ expEvts.add(new T3<>((Object)key, (Object)val, (Object)key));
+ }
+
+ srvCache.put(key, val);
+
+ filtered = !filtered;
+ }
+
+ checkEvents(expEvts, lsnr, false);
+
+ List<Thread> stopThreads = new ArrayList<>(3);
+
+ // Stop nodes which owning this partition.
+ for (int i = 0; i < SRV_NODES; i++) {
+ Ignite ignite = ignite(i);
+
+ if (ids.contains(ignite.cluster().localNode().id())) {
+ final int i0 = i;
+
+ TestCommunicationSpi spi = (TestCommunicationSpi)ignite.configuration().getCommunicationSpi();
+
+ spi.skipAllMsg = true;
+
+ stopThreads.add(new Thread() {
+ @Override public void run() {
+ stopGrid(i0, true);
+ }
+ });
+ }
+ }
+
+ // Stop and join threads.
+ for (Thread t : stopThreads)
+ t.start();
+
+ for (Thread t : stopThreads)
+ t.join();
+
+ assert GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ // (SRV_NODES + 1 client node) - 1 primary - backup nodes.
+ return qryClient.cluster().nodes().size() == (SRV_NODES + 1 /** client node */)
+ - 1 /** Primary node */ - backups;
+ }
+ }, 5000L);
+
+ for (; keyIter < keys.size(); keyIter++) {
+ int key = keys.get(keyIter);
+
+ log.info("Put [key=" + key + ", filtered=" + filtered + ']');
+
+ T2<Object, Object> t = updates.get(key);
+
+ Integer val = filtered ?
+ (key % 2 == 0 ? key + 1 : key) :
+ key * 2;
+
+ if (t == null) {
+ updates.put(key, new T2<>((Object)val, null));
+
+ if (!filtered)
+ expEvts.add(new T3<>((Object)key, (Object)val, null));
+ }
+ else {
+ updates.put(key, new T2<>((Object)val, (Object)key));
+
+ if (!filtered)
+ expEvts.add(new T3<>((Object)key, (Object)val, (Object)key));
+ }
+
+ clnCache.put(key, val);
+
+ filtered = !filtered;
+ }
+
+ checkEvents(expEvts, lsnr, false);
+
+ query.close();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRemoteFilter() throws Exception {
+ this.backups = 2;
+
+ final int SRV_NODES = 4;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ IgniteCache<Object, Object> qryClientCache = qryClient.cache(null);
+
+ if (cacheMode() != REPLICATED)
+ assertEquals(backups, qryClientCache.getConfiguration(CacheConfiguration.class).getBackups());
+
+ Affinity<Object> aff = qryClient.affinity(null);
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ final CacheEventListener3 lsnr = new CacheEventListener3();
+
+ qry.setLocalListener(lsnr);
+
+ qry.setRemoteFilter(lsnr);
+
+ int PARTS = 10;
+
+ QueryCursor<?> cur = qryClientCache.query(qry);
+
+ Map<Object, T2<Object, Object>> updates = new HashMap<>();
+
+ final List<T3<Object, Object, Object>> expEvts = new ArrayList<>();
+
+ for (int i = 0; i < (atomicityMode() == CacheAtomicityMode.ATOMIC ? SRV_NODES - 1 : SRV_NODES - 2); i++) {
+ log.info("Stop iteration: " + i);
+
+ TestCommunicationSpi spi = (TestCommunicationSpi)ignite(i).configuration().getCommunicationSpi();
+
+ Ignite ignite = ignite(i);
+
+ IgniteCache<Object, Object> cache = ignite.cache(null);
+
+ List<Integer> keys = testKeys(cache, PARTS);
+
+ boolean first = true;
+
+ boolean filtered = false;
+
+ for (Integer key : keys) {
+ log.info("Put [node=" + ignite.name() + ", key=" + key + ", part=" + aff.partition(key)
+ + ", filtered=" + filtered + ']');
+
+ T2<Object, Object> t = updates.get(key);
+
+ Integer val = filtered ?
+ (key % 2 == 0 ? key + 1 : key) :
+ key * 2;
+
+ if (t == null) {
+ updates.put(key, new T2<>((Object)val, null));
+
+ if (!filtered)
+ expEvts.add(new T3<>((Object)key, (Object)val, null));
+ }
+ else {
+ updates.put(key, new T2<>((Object)val, (Object)key));
+
+ if (!filtered)
+ expEvts.add(new T3<>((Object)key, (Object)val, (Object)key));
+ }
+
+ cache.put(key, val);
+
+ if (first) {
+ spi.skipMsg = true;
+
+ first = false;
+ }
+
+ filtered = !filtered;
+ }
+
+ stopGrid(i);
+
+ boolean check = GridTestUtils.waitForCondition(new PAX() {
+ @Override public boolean applyx() throws IgniteCheckedException {
+ return expEvts.size() == lsnr.keys.size();
+ }
+ }, 5000L);
+
+ if (!check) {
+ Set<Integer> keys0 = new HashSet<>(keys);
+
+ keys0.removeAll(lsnr.keys);
+
+ log.info("Missed events for keys: " + keys0);
+
+ fail("Failed to wait for notifications [exp=" + keys.size() + ", left=" + keys0.size() + ']');
+ }
+
+ checkEvents(expEvts, lsnr, false);
+ }
+
+ cur.close();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testThreeBackups() throws Exception {
+ if (cacheMode() == REPLICATED)
+ return;
+
+ checkBackupQueue(3, false);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDebug() {
+ return true;
+ }
+
+ /**
+ * @param backups Number of backups.
+ * @param updateFromClient If {@code true} executes cache update from client node.
+ * @throws Exception If failed.
+ */
+ private void checkBackupQueue(int backups, boolean updateFromClient) throws Exception {
+ this.backups = atomicityMode() == CacheAtomicityMode.ATOMIC ? backups :
+ backups < 2 ? 2 : backups;
+
+ final int SRV_NODES = 4;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ IgniteCache<Object, Object> qryClientCache = qryClient.cache(null);
+
+ Affinity<Object> aff = qryClient.affinity(null);
+
+ CacheEventListener1 lsnr = new CacheEventListener1(false);
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ QueryCursor<?> cur = qryClientCache.query(qry);
+
+ int PARTS = 10;
+
+ Map<Object, T2<Object, Object>> updates = new HashMap<>();
+
+ List<T3<Object, Object, Object>> expEvts = new ArrayList<>();
+
+ for (int i = 0; i < (atomicityMode() == CacheAtomicityMode.ATOMIC ? SRV_NODES - 1 : SRV_NODES - 2); i++) {
+ log.info("Stop iteration: " + i);
+
+ TestCommunicationSpi spi = (TestCommunicationSpi)ignite(i).configuration().getCommunicationSpi();
+
+ Ignite ignite = ignite(i);
+
+ IgniteCache<Object, Object> cache = ignite.cache(null);
+
+ List<Integer> keys = testKeys(cache, PARTS);
+
+ CountDownLatch latch = new CountDownLatch(keys.size());
+
+ lsnr.latch = latch;
+
+ boolean first = true;
+
+ for (Integer key : keys) {
+ log.info("Put [node=" + ignite.name() + ", key=" + key + ", part=" + aff.partition(key) + ']');
+
+ T2<Object, Object> t = updates.get(key);
+
+ if (updateFromClient) {
+ if (atomicityMode() == CacheAtomicityMode.TRANSACTIONAL) {
+ try (Transaction tx = qryClient.transactions().txStart()) {
+ qryClientCache.put(key, key);
+
+ tx.commit();
+ }
+ catch (CacheException | ClusterTopologyException e) {
+ log.warning("Failed put. [Key=" + key + ", val=" + key + "]");
+
+ continue;
+ }
+ }
+ else
+ qryClientCache.put(key, key);
+ }
+ else {
+ if (atomicityMode() == CacheAtomicityMode.TRANSACTIONAL) {
+ try (Transaction tx = ignite.transactions().txStart()) {
+ cache.put(key, key);
+
+ tx.commit();
+ }
+ catch (CacheException | ClusterTopologyException e) {
+ log.warning("Failed put. [Key=" + key + ", val=" + key + "]");
+
+ continue;
+ }
+ }
+ else
+ cache.put(key, key);
+ }
+
+ if (t == null) {
+ updates.put(key, new T2<>((Object)key, null));
+
+ expEvts.add(new T3<>((Object)key, (Object)key, null));
+ }
+ else {
+ updates.put(key, new T2<>((Object)key, (Object)key));
+
+ expEvts.add(new T3<>((Object)key, (Object)key, (Object)key));
+ }
+
+ if (first) {
+ spi.skipMsg = true;
+
+ first = false;
+ }
+ }
+
+ stopGrid(i);
+
+ if (!latch.await(5, SECONDS)) {
+ Set<Integer> keys0 = new HashSet<>(keys);
+
+ keys0.removeAll(lsnr.keys);
+
+ log.info("Missed events for keys: " + keys0);
+
+ fail("Failed to wait for notifications [exp=" + keys.size() + ", left=" + lsnr.latch.getCount() + ']');
+ }
+
+ checkEvents(expEvts, lsnr);
+ }
+
+ for (int i = 0; i < (atomicityMode() == CacheAtomicityMode.ATOMIC ? SRV_NODES - 1 : SRV_NODES - 2); i++) {
+ log.info("Start iteration: " + i);
+
+ Ignite ignite = startGrid(i);
+
+ IgniteCache<Object, Object> cache = ignite.cache(null);
+
+ List<Integer> keys = testKeys(cache, PARTS);
+
+ CountDownLatch latch = new CountDownLatch(keys.size());
+
+ lsnr.latch = latch;
+
+ for (Integer key : keys) {
+ log.info("Put [node=" + ignite.name() + ", key=" + key + ", part=" + aff.partition(key) + ']');
+
+ T2<Object, Object> t = updates.get(key);
+
+ if (t == null) {
+ updates.put(key, new T2<>((Object)key, null));
+
+ expEvts.add(new T3<>((Object)key, (Object)key, null));
+ }
+ else {
+ updates.put(key, new T2<>((Object)key, (Object)key));
+
+ expEvts.add(new T3<>((Object)key, (Object)key, (Object)key));
+ }
+
+ if (updateFromClient)
+ qryClientCache.put(key, key);
+ else
+ cache.put(key, key);
+ }
+
+ if (!latch.await(10, SECONDS)) {
+ Set<Integer> keys0 = new HashSet<>(keys);
+
+ keys0.removeAll(lsnr.keys);
+
+ log.info("Missed events for keys: " + keys0);
+
+ fail("Failed to wait for notifications [exp=" + keys.size() + ", left=" + lsnr.latch.getCount() + ']');
+ }
+
+ checkEvents(expEvts, lsnr);
+ }
+
+ cur.close();
+
+ assertFalse("Unexpected error during test, see log for details.", err);
+ }
+
+ /**
+ * @param expEvts Expected events.
+ * @param lsnr Listener.
+ */
+ private void checkEvents(List<T3<Object, Object, Object>> expEvts, CacheEventListener1 lsnr) {
+ for (T3<Object, Object, Object> exp : expEvts) {
+ CacheEntryEvent<?, ?> e = lsnr.evts.get(exp.get1());
+
+ assertNotNull("No event for key: " + exp.get1(), e);
+ assertEquals("Unexpected value: " + e, exp.get2(), e.getValue());
+ }
+
+ expEvts.clear();
+
+ lsnr.evts.clear();
+ }
+
+ /**
+ * @param expEvts Expected events.
+ * @param lsnr Listener.
+ * @param lostAllow If {@code true} than won't assert on lost events.
+ */
+ private void checkEvents(final List<T3<Object, Object, Object>> expEvts, final CacheEventListener2 lsnr,
+ boolean lostAllow) throws Exception {
+ checkEvents(expEvts, lsnr, lostAllow, true);
+ }
+
+ /**
+ * @param expEvts Expected events.
+ * @param lsnr Listener.
+ * @param lostAllow If {@code true} than won't assert on lost events.
+ */
+ private void checkEvents(final List<T3<Object, Object, Object>> expEvts, final CacheEventListener2 lsnr,
+ boolean lostAllow, boolean wait) throws Exception {
+ if (wait)
+ GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return expEvts.size() == lsnr.size();
+ }
+ }, 2000L);
+
+ Map<Integer, List<CacheEntryEvent<?, ?>>> prevMap = new HashMap<>(lsnr.evts.size());
+
+ for (Map.Entry<Integer, List<CacheEntryEvent<?, ?>>> e : lsnr.evts.entrySet())
+ prevMap.put(e.getKey(), new ArrayList<>(e.getValue()));
+
+ List<T3<Object, Object, Object>> lostEvents = new ArrayList<>();
+
+ for (T3<Object, Object, Object> exp : expEvts) {
+ List<CacheEntryEvent<?, ?>> rcvdEvts = lsnr.evts.get(exp.get1());
+
+ if (F.eq(exp.get2(), exp.get3()))
+ continue;
+
+ if (rcvdEvts == null || rcvdEvts.isEmpty()) {
+ lostEvents.add(exp);
+
+ continue;
+ }
+
+ Iterator<CacheEntryEvent<?, ?>> iter = rcvdEvts.iterator();
+
+ boolean found = false;
+
+ while (iter.hasNext()) {
+ CacheEntryEvent<?, ?> e = iter.next();
+
+ if ((exp.get2() != null && e.getValue() != null && exp.get2().equals(e.getValue()))
+ && equalOldValue(e, exp)) {
+ found = true;
+
+ iter.remove();
+
+ break;
+ }
+ }
+
+ // Lost event is acceptable.
+ if (!found)
+ lostEvents.add(exp);
+ }
+
+ boolean dup = false;
+
+ // Check duplicate.
+ if (!lsnr.evts.isEmpty()) {
+ for (List<CacheEntryEvent<?, ?>> evts : lsnr.evts.values()) {
+ if (!evts.isEmpty()) {
+ for (CacheEntryEvent<?, ?> e : evts) {
+ boolean found = false;
+
+ for (T3<Object, Object, Object> lostEvt : lostEvents) {
+ if (e.getKey().equals(lostEvt.get1()) && e.getValue().equals(lostEvt.get2())) {
+ found = true;
+
+ lostEvents.remove(lostEvt);
+
+ break;
+ }
+ }
+
+ if (!found) {
+ dup = true;
+
+ break;
+ }
+ }
+ }
+ }
+
+ if (dup) {
+ for (List<CacheEntryEvent<?, ?>> e : lsnr.evts.values()) {
+ if (!e.isEmpty()) {
+ for (CacheEntryEvent<?, ?> event : e)
+ log.error("Got duplicate event: " + event);
+ }
+ }
+ }
+ }
+
+ if (!lostAllow && lostEvents.size() > 100) {
+ log.error("Lost event cnt: " + lostEvents.size());
+
+ for (T3<Object, Object, Object> e : lostEvents)
+ log.error("Lost event: " + e);
+
+ fail("Lose events, see log for details.");
+ }
+
+ log.error("Lost event cnt: " + lostEvents.size());
+
+ expEvts.clear();
+
+ lsnr.evts.clear();
+ lsnr.vals.clear();
+ }
+
+ /**
+ * @param e Event
+ * @param expVals expected value
+ * @return {@code True} if entries has the same key, value and oldValue. If cache start without backups
+ * than oldValue ignoring in comparison.
+ */
+ private boolean equalOldValue(CacheEntryEvent<?, ?> e, T3<Object, Object, Object> expVals) {
+ return (e.getOldValue() == null && expVals.get3() == null) // Both null
+ || (e.getOldValue() != null && expVals.get3() != null // Equals
+ && e.getOldValue().equals(expVals.get3()))
+ || (backups == 0); // If we start without backup than oldValue might be lose.
+ }
+
+ /**
+ * @param expEvts Expected events.
+ * @param lsnr Listener.
+ */
+ private void checkEvents(final List<T3<Object, Object, Object>> expEvts, final CacheEventListener3 lsnr,
+ boolean allowLoseEvent) throws Exception {
+ if (!allowLoseEvent)
+ assert GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return lsnr.evts.size() == expEvts.size();
+ }
+ }, 2000L);
+
+ for (T3<Object, Object, Object> exp : expEvts) {
+ CacheEntryEvent<?, ?> e = lsnr.evts.get(exp.get1());
+
+ assertNotNull("No event for key: " + exp.get1(), e);
+ assertEquals("Unexpected value: " + e, exp.get2(), e.getValue());
+
+ if (allowLoseEvent)
+ lsnr.evts.remove(exp.get1());
+ }
+
+ if (allowLoseEvent)
+ assert lsnr.evts.isEmpty();
+
+ expEvts.clear();
+
+ lsnr.evts.clear();
+ lsnr.keys.clear();
+ }
+
+ /**
+ * @param cache Cache.
+ * @param parts Number of partitions.
+ * @return Keys.
+ */
+ private List<Integer> testKeys(IgniteCache<Object, Object> cache, int parts) {
+ Ignite ignite = cache.unwrap(Ignite.class);
+
+ List<Integer> res = new ArrayList<>();
+
+ Affinity<Object> aff = ignite.affinity(cache.getName());
+
+ ClusterNode node = ignite.cluster().localNode();
+
+ int[] nodeParts = aff.primaryPartitions(node);
+
+ final int KEYS_PER_PART = 50;
+
+ for (int i = 0; i < parts; i++) {
+ int part = nodeParts[i];
+
+ int cnt = 0;
+
+ for (int key = 0; key < 100_000; key++) {
+ if (aff.partition(key) == part && aff.isPrimary(node, key)) {
+ res.add(key);
+
+ if (++cnt == KEYS_PER_PART)
+ break;
+ }
+ }
+
+ assertEquals(KEYS_PER_PART, cnt);
+ }
+
+ assertEquals(parts * KEYS_PER_PART, res.size());
+
+ return res;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBackupQueueCleanupClientQuery() throws Exception {
+ startGridsMultiThreaded(2);
+
+ client = true;
+
+ Ignite qryClient = startGrid(2);
+
+ CacheEventListener1 lsnr = new CacheEventListener1(false);
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ QueryCursor<?> cur = qryClient.cache(null).query(qry);
+
+ final Collection<Object> backupQueue = backupQueue(ignite(1));
+
+ assertEquals(0, backupQueue.size());
+
+ IgniteCache<Object, Object> cache0 = ignite(0).cache(null);
+
+ List<Integer> keys = primaryKeys(cache0, BACKUP_ACK_THRESHOLD);
+
+ CountDownLatch latch = new CountDownLatch(keys.size());
+
+ lsnr.latch = latch;
+
+ for (Integer key : keys) {
+ log.info("Put: " + key);
+
+ cache0.put(key, key);
+ }
+
+ GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return backupQueue.isEmpty();
+ }
+ }, 2000);
+
+ assertTrue("Backup queue is not cleared: " + backupQueue, backupQueue.size() < BACKUP_ACK_THRESHOLD);
+
+ if (!latch.await(5, SECONDS))
+ fail("Failed to wait for notifications [exp=" + keys.size() + ", left=" + lsnr.latch.getCount() + ']');
+
+ keys = primaryKeys(cache0, BACKUP_ACK_THRESHOLD / 2);
+
+ latch = new CountDownLatch(keys.size());
+
+ lsnr.latch = latch;
+
+ for (Integer key : keys)
+ cache0.put(key, key);
+
+ final long ACK_FREQ = 5000;
+
+ GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return backupQueue.isEmpty();
+ }
+ }, ACK_FREQ + 2000);
+
+ assertTrue("Backup queue is not cleared: " + backupQueue, backupQueue.isEmpty());
+
+ if (!latch.await(5, SECONDS))
+ fail("Failed to wait for notifications [exp=" + keys.size() + ", left=" + lsnr.latch.getCount() + ']');
+
+ cur.close();
+
+ assertFalse("Unexpected error during test, see log for details.", err);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBackupQueueCleanupServerQuery() throws Exception {
+ Ignite qryClient = startGridsMultiThreaded(2);
+
+ CacheEventListener1 lsnr = new CacheEventListener1(false);
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ IgniteCache<Object, Object> cache = qryClient.cache(null);
+
+ QueryCursor<?> cur = cache.query(qry);
+
+ final Collection<Object> backupQueue = backupQueue(ignite(1));
+
+ assertEquals(0, backupQueue.size());
+
+ List<Integer> keys = primaryKeys(cache, BACKUP_ACK_THRESHOLD);
+
+ CountDownLatch latch = new CountDownLatch(keys.size());
+
+ lsnr.latch = latch;
+
+ for (Integer key : keys) {
+ log.info("Put: " + key);
+
+ cache.put(key, key);
+ }
+
+ GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return backupQueue.isEmpty();
+ }
+ }, 3000);
+
+ assertTrue("Backup queue is not cleared: " + backupQueue, backupQueue.size() < BACKUP_ACK_THRESHOLD);
+
+ if (!latch.await(5, SECONDS))
+ fail("Failed to wait for notifications [exp=" + keys.size() + ", left=" + lsnr.latch.getCount() + ']');
+
+ cur.close();
+ }
+
+ /**
+ * @param ignite Ignite.
+ * @return Backup queue for test query.
+ */
+ private Collection<Object> backupQueue(Ignite ignite) {
+ GridContinuousProcessor proc = ((IgniteKernal)ignite).context().continuous();
+
+ ConcurrentMap<Object, Object> infos = GridTestUtils.getFieldValue(proc, "rmtInfos");
+
+ Collection<Object> backupQueue = null;
+
+ for (Object info : infos.values()) {
+ GridContinuousHandler hnd = GridTestUtils.getFieldValue(info, "hnd");
+
+ if (hnd.isForQuery() && hnd.cacheName() == null) {
+ backupQueue = GridTestUtils.getFieldValue(hnd, "backupQueue");
+
+ break;
+ }
+ }
+
+ assertNotNull(backupQueue);
+
+ return backupQueue;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testFailoverStartStopBackup() throws Exception {
+ failoverStartStopFilter(2);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testStartStop() throws Exception {
+ this.backups = 2;
+
+ final int SRV_NODES = 4;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ IgniteCache<Object, Object> qryClnCache = qryClient.cache(null);
+
+ Affinity<Object> aff = qryClient.affinity(null);
+
+ final CacheEventListener2 lsnr = new CacheEventListener2();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ qry.setRemoteFilter(new CacheEventFilter());
+
+ QueryCursor<?> cur = qryClnCache.query(qry);
+
+ for (int i = 0; i < 10; i++) {
+ final int idx = i % (SRV_NODES - 1);
+
+ log.info("Stop node: " + idx);
+
+ stopGrid(idx);
+
+ awaitPartitionMapExchange();
+
+ List<T3<Object, Object, Object>> afterRestEvents = new ArrayList<>();
+
+ for (int j = 0; j < aff.partitions(); j++) {
+ Integer oldVal = (Integer)qryClnCache.get(j);
+
+ qryClnCache.put(j, i);
+
+ afterRestEvents.add(new T3<>((Object)j, (Object)i, (Object)oldVal));
+ }
+
+ checkEvents(new ArrayList<>(afterRestEvents), lsnr, false);
+
+ log.info("Start node: " + idx);
+
+ startGrid(idx);
+ }
+
+ cur.close();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void failoverStartStopFilter(int backups) throws Exception {
+ this.backups = backups;
+
+ final int SRV_NODES = 4;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ Ignite qryClient = startGrid(SRV_NODES);
+
+ client = false;
+
+ IgniteCache<Object, Object> qryClnCache = qryClient.cache(null);
+
+ final CacheEventListener2 lsnr = new CacheEventListener2();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ qry.setRemoteFilter(new CacheEventFilter());
+
+ QueryCursor<?> cur = qryClnCache.query(qry);
+
+ CacheEventListener2 dinLsnr = null;
+
+ QueryCursor<?> dinQry = null;
+
+ final AtomicBoolean stop = new AtomicBoolean();
+
+ final AtomicReference<CountDownLatch> checkLatch = new AtomicReference<>();
+
+ IgniteInternalFuture<?> restartFut = GridTestUtils.runAsync(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ while (!stop.get() && !err) {
+ final int idx = ThreadLocalRandom.current().nextInt(SRV_NODES - 1);
+
+ log.info("Stop node: " + idx);
+
+ awaitPartitionMapExchange();
+
+ Thread.sleep(400);
+
+ stopGrid(idx);
+
+ awaitPartitionMapExchange();
+
+ Thread.sleep(400);
+
+ log.info("Start node: " + idx);
+
+ startGrid(idx);
+
+ Thread.sleep(200);
+
+ CountDownLatch latch = new CountDownLatch(1);
+
+ assertTrue(checkLatch.compareAndSet(null, latch));
+
+ if (!stop.get()) {
+ log.info("Wait for event check.");
+
+ assertTrue(latch.await(1, MINUTES));
+ }
+ }
+
+ return null;
+ }
+ });
+
+ final Map<Integer, Integer> vals = new HashMap<>();
+
+ final Map<Integer, List<T2<Integer, Integer>>> expEvts = new HashMap<>();
+
+ final List<T3<Object, Object, Object>> expEvtsNewLsnr = new ArrayList<>();
+
+ final List<T3<Object, Object, Object>> expEvtsLsnr = new ArrayList<>();
+
+ try {
+ long stopTime = System.currentTimeMillis() + 60_000;
+
+ // Start new filter each 5 sec.
+ long startFilterTime = System.currentTimeMillis() + 5_000;
+
+ final int PARTS = qryClient.affinity(null).partitions();
+
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ boolean filtered = false;
+
+ boolean processorPut = false;
+
+ while (System.currentTimeMillis() < stopTime) {
+ Integer key = rnd.nextInt(PARTS);
+
+ Integer prevVal = vals.get(key);
+ Integer val = vals.get(key);
+
+ if (System.currentTimeMillis() > startFilterTime) {
+ // Stop filter and check events.
+ if (dinQry != null) {
+ dinQry.close();
+
+ log.info("Continuous query listener closed. Await events: " + expEvtsNewLsnr.size());
+
+ checkEvents(expEvtsNewLsnr, dinLsnr, backups == 0);
+ }
+
+ dinLsnr = new CacheEventListener2();
+
+ ContinuousQuery<Object, Object> newQry = new ContinuousQuery<>();
+
+ newQry.setLocalListener(dinLsnr);
+
+ newQry.setRemoteFilter(new CacheEventFilter());
+
+ dinQry = qryClnCache.query(newQry);
+
+ log.info("Continuous query listener started.");
+
+ startFilterTime = System.currentTimeMillis() + 5_000;
+ }
+
+ if (val == null)
+ val = 0;
+ else
+ val = Math.abs(val) + 1;
+
+ if (filtered)
+ val = -val;
+
+ if (processorPut && prevVal != null) {
+ qryClnCache.invoke(key, new CacheEntryProcessor<Object, Object, Void>() {
+ @Override public Void process(MutableEntry<Object, Object> entry,
+ Object... arguments) throws EntryProcessorException {
+ entry.setValue(arguments[0]);
+
+ return null;
+ }
+ }, val);
+ }
+ else
+ qryClnCache.put(key, val);
+
+ processorPut = !processorPut;
+
+ vals.put(key, val);
+
+ if (val >= 0) {
+ List<T2<Integer, Integer>> keyEvts = expEvts.get(key);
+
+ if (keyEvts == null) {
+ keyEvts = new ArrayList<>();
+
+ expEvts.put(key, keyEvts);
+ }
+
+ keyEvts.add(new T2<>(val, prevVal));
+
+ T3<Object, Object, Object> tupVal = new T3<>((Object)key, (Object)val, (Object)prevVal);
+
+ expEvtsLsnr.add(tupVal);
+
+ if (dinQry != null)
+ expEvtsNewLsnr.add(tupVal);
+ }
+
+ filtered = !filtered;
+
+ CountDownLatch latch = checkLatch.get();
+
+ if (latch != null) {
+ log.info("Check events.");
+
+ checkLatch.set(null);
+
+ boolean success = false;
+
+ try {
+ if (err)
+ break;
+
+ checkEvents(expEvtsLsnr, lsnr, backups == 0);
+
+ success = true;
+
+ log.info("Events checked.");
+ }
+ finally {
+ if (!success)
+ err = true;
+
+ latch.countDown();
+ }
+ }
+ }
+ }
+ finally {
+ stop.set(true);
+ }
+
+ CountDownLatch latch = checkLatch.get();
+
+ if (latch != null)
+ latch.countDown();
+
+ restartFut.get();
+
+ checkEvents(expEvtsLsnr, lsnr, backups == 0);
+
+ lsnr.evts.clear();
+ lsnr.vals.clear();
+
+ if (dinQry != null) {
+ checkEvents(expEvtsNewLsnr, dinLsnr, backups == 0);
+
+ dinLsnr.evts.clear();
+ dinLsnr.vals.clear();
+ }
+
+ List<T3<Object, Object, Object>> afterRestEvents = new ArrayList<>();
+
+ for (int i = 0; i < qryClient.affinity(null).partitions(); i++) {
+ Integer oldVal = (Integer)qryClnCache.get(i);
+
+ qryClnCache.put(i, i);
+
+ afterRestEvents.add(new T3<>((Object)i, (Object)i, (Object)oldVal));
+ }
+
+ checkEvents(new ArrayList<>(afterRestEvents), lsnr, false);
+
+ cur.close();
+
+ if (dinQry != null) {
+ checkEvents(new ArrayList<>(afterRestEvents), dinLsnr, false);
+
+ dinQry.close();
+ }
+
+ assertFalse("Unexpected error during test, see log for details.", err);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testMultiThreadedFailover() throws Exception {
+ this.backups = 2;
+
+ final int SRV_NODES = 4;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ final Ignite qryCln = startGrid(SRV_NODES);
+
+ client = false;
+
+ final IgniteCache<Object, Object> qryClnCache = qryCln.cache(null);
+
+ final CacheEventListener2 lsnr = new CacheEventListener2();
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ QueryCursor<?> cur = qryClnCache.query(qry);
+
+ final AtomicBoolean stop = new AtomicBoolean();
+
+ final int THREAD = 4;
+
+ final int PARTS = THREAD;
+
+ final List<List<T3<Object, Object, Object>>> expEvts = new ArrayList<>(THREAD + 5);
+
+ for (int i = 0; i < THREAD; i++)
+ expEvts.add(i, new ArrayList<T3<Object, Object, Object>>());
+
+ final AtomicReference<CyclicBarrier> checkBarrier = new AtomicReference<>();
+
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ IgniteInternalFuture<?> restartFut = GridTestUtils.runAsync(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ while (!stop.get() && !err) {
+ final int idx = rnd.nextInt(SRV_NODES);
+
+ log.info("Stop node: " + idx);
+
+ stopGrid(idx);
+
+ Thread.sleep(300);
+
+ GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return qryCln.cluster().nodes().size() == SRV_NODES;
+ }
+ }, 5000L);
+
+ try {
+ log.info("Start node: " + idx);
+
+ startGrid(idx);
+
+ Thread.sleep(300);
+
+ GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return qryCln.cluster().nodes().size() == SRV_NODES + 1;
+ }
+ }, 5000L);
+ }
+ catch (Exception e) {
+ log.warning("Failed to stop nodes.", e);
+ }
+
+ CyclicBarrier bar = new CyclicBarrier(THREAD + 1 /* plus start/stop thread */, new Runnable() {
+ @Override public void run() {
+ try {
+ int size0 = 0;
+
+ for (List<T3<Object, Object, Object>> evt : expEvts)
+ size0 += evt.size();
+
+ final int size = size0;
+
+ GridTestUtils.waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return lsnr.size() <= size;
+ }
+ }, 2000L);
+
+ List<T3<Object, Object, Object>> expEvts0 = new ArrayList<>();
+
+ for (List<T3<Object, Object, Object>> evt : expEvts)
+ expEvts0.addAll(evt);
+
+ checkEvents(expEvts0, lsnr, false, false);
+
+ for (List<T3<Object, Object, Object>> evt : expEvts)
+ evt.clear();
+ }
+ catch (Exception e) {
+ log.error("Failed.", e);
+
+ err = true;
+
+ stop.set(true);
+ }
+ finally {
+ checkBarrier.set(null);
+ }
+ }
+ });
+
+ assertTrue(checkBarrier.compareAndSet(null, bar));
+
+ if (!stop.get() && !err)
+ bar.await(1, MINUTES);
+ }
+
+ return null;
+ }
+ });
+
+ final long stopTime = System.currentTimeMillis() + 60_000;
+
+ final AtomicInteger valCntr = new AtomicInteger(0);
+
+ final AtomicInteger threadSeq = new AtomicInteger(0);
+
+ GridTestUtils.runMultiThreaded(new Runnable() {
+ @Override public void run() {
+ try {
+ final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ final int threadId = threadSeq.getAndIncrement();
+
+ log.error("Thread id: " + threadId);
+
+ while (System.currentTimeMillis() < stopTime && !stop.get() && !err) {
+ Integer key = rnd.nextInt(PARTS);
+
+ Integer val = valCntr.incrementAndGet();
+
+ Integer prevVal = (Integer)qryClnCache.getAndPut(key, val);
+
+ expEvts.get(threadId).add(new T3<>((Object)key, (Object)val, (Object)prevVal));
+
+ CyclicBarrier bar = checkBarrier.get();
+
+ if (bar != null)
+ bar.await();
+ }
+ }
+ catch (Exception e){
+ log.error("Failed.", e);
+
+ err = true;
+
+ stop.set(true);
+ }
+ finally {
+ stop.set(true);
+ }
+ }
+ }, THREAD, "update-thread");
+
+ restartFut.get();
+
+ List<T3<Object, Object, Object>> expEvts0 = new ArrayList<>();
+
+ for (List<T3<Object, Object, Object>> evt : expEvts) {
+ expEvts0.addAll(evt);
+
+ evt.clear();
+ }
+
+ if (!expEvts0.isEmpty())
+ checkEvents(expEvts0, lsnr, true);
+
+ cur.close();
+
+ assertFalse("Unexpected error during test, see log for details.", err);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testMultiThreaded() throws Exception {
+ this.backups = 2;
+
+ final int SRV_NODES = 3;
+
+ startGridsMultiThreaded(SRV_NODES);
+
+ client = true;
+
+ Ignite qryClient = startGrid(SRV_NODES);
+
+ final IgniteCache<Object, Object> cache = qryClient.cache(null);
+
+ CacheEventListener1 lsnr = new CacheEventListener1(true);
+
+ ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
+
+ qry.setLocalListener(lsnr);
+
+ QueryCursor<?> cur = cache.query(qry);
+
+ client = false;
+
+ final int SRV_IDX = SRV_NODES - 1;
+
+ List<Integer> keys = primaryKeys(ignite(SRV_IDX).cache(null), 10);
+
+ final int THREADS = 10;
+
+ for (int i = 0; i < keys.size(); i++) {
+ log.info("Iteration: " + i);
+
+ Ignite srv = ignite(SRV_IDX);
+
+ TestCommunicationSpi spi = (TestCommunicationSpi)srv.configuration().getCommunicationSpi();
+
+ spi.sndFirstOnly = new AtomicBoolean(false);
+
+ final Integer key = keys.get(i);
+
+ final AtomicInteger val = new AtomicInteger();
+
+ CountDownLatch latch = new CountDownLatch(THREADS);
+
+ lsnr.latch = latch;
+
+ IgniteInternalFuture<?> fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ Integer val0 = val.getAndIncrement();
+
+ cache.put(key, val0);
+
+ return null;
+ }
+ }, THREADS, "update-thread");
+
+ fut.get();
+
+ stopGrid(SRV_IDX);
+
+ if (!latch.await(5, SECONDS))
+ fail("Failed to wait for notifications [exp=" + THREADS + ", left=" + lsnr.latch.getCount() + ']');
+
+ assertEquals(THREADS, lsnr.allEvts.size());
+
+ Set<Integer> vals = new HashSet<>();
+
+ boolean err = false;
+
+ for (CacheEntryEvent<?, ?> evt : lsnr.allEvts) {
+ assertEquals(key, evt.getKey());
+ assertNotNull(evt.getValue());
+
+ if (!vals.add((Integer)evt.getValue())) {
+ err = true;
+
+ log.info("Extra event: " + evt);
+ }
+ }
+
+ for (int v = 0; v < THREADS; v++) {
+ if (!vals.contains(v)) {
+ err = true;
+
+ log.info("Event for value not received: " + v);
+ }
+ }
+
+ assertFalse("Invalid events, see log for details.", err);
+
+ lsnr.allEvts.clear();
+
+ startGrid(SRV_IDX);
+ }
+
+ cur.close();
+ }
+
+ /**
+ * @param logAll If {@code true} logs all unexpected values.
+ * @param expEvts Expected values.
+ * @param lsnr Listener.
+ * @return Check status.
+ */
+ @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
+ private boolean checkEvents(boolean logAll,
+ Map<Integer, List<T2<Integer, Integer>>> expEvts,
+ CacheEventListener2 lsnr) {
+ assertTrue(!expEvts.isEmpty());
+
+ boolean pass = true;
+
+ for (Map.Entry<Integer, List<T2<Integer, Integer>>> e : expEvts.entrySet()) {
+ Integer key = e.getKey();
+ List<T2<Integer, Integer>> exp = e.getValue();
+
+ List<CacheEntryEvent<?, ?>> rcvdEvts = lsnr.evts.get(key);
+
+ if (rcvdEvts == null) {
+ pass = false;
+
+ log.info("No events for key [key=" + key + ", exp=" + e.getValue() + ']');
+
+ if (!logAll)
+ return false;
+ }
+ else {
+ synchronized (rcvdEvts) {
+ if (rcvdEvts.size() != exp.size()) {
+ pass = false;
+
+ log.info("Missed or extra events for key [key=" + key +
+ ", exp=" + e.getValue() +
+ ", rcvd=" + rcvdEvts + ']');
+
+ if (!logAll)
+ return false;
+ }
+
+ int cnt = Math.min(rcvdEvts.size(), exp.size());
+
+ for (int i = 0; i < cnt; i++) {
+ T2<Integer, Integer> expEvt = exp.get(i);
+ CacheEntryEvent<?, ?> rcvdEvt = rcvdEvts.get(i);
+
+ if (pass) {
+ assertEquals(key, rcvdEvt.getKey());
+ assertEquals(expEvt.get1(), rcvdEvt.getValue());
+ }
+ else {
+ if (!key.equals(rcvdEvt.getKey()) || !expEvt.get1().equals(rcvdEvt.getValue()))
+ log.warning("Missed events. [key=" + key + ", actKey=" + rcvdEvt.getKey()
+ + ", expVal=" + expEvt.get1() + ", actVal=" + rcvdEvt.getValue() + "]");
+ }
+ }
+
+ if (!pass) {
+ for (int i = cnt; i < exp.size(); i++) {
+ T2<Integer, Integer> val = exp.get(i);
+
+ log.warning("Missed events. [key=" + key + ", expVal=" + val.get1()
+ + ", prevVal=" + val.get2() + "]");
+ }
+ }
+ }
+ }
+ }
+
+ if (pass) {
+ expEvts.clear();
+ lsnr.evts.clear();
+ }
+
+ return pass;
+ }
+
+ /**
+ *
+ */
+ private static class CacheEventListener1 implements CacheEntryUpdatedListener<Object, Object> {
+ /** */
+ private volatile CountDownLatch latch;
+
+ /** */
+ private GridConcurrentHashSet<Integer> keys = new GridConcurrentHashSet<>();
+
+ /** */
+ private ConcurrentHashMap<Object, CacheEntryEvent<?, ?>> evts = new ConcurrentHashMap<>();
+
+ /** */
+ private List<CacheEntryEvent<?, ?>> allEvts;
+
+ /** */
+ @LoggerResource
+ private IgniteLogger log;
+
+ /**
+ * @param saveAll Save all events flag.
+ */
+ CacheEventListener1(boolean saveAll) {
+ if (saveAll)
+ allEvts = new ArrayList<>();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onUpdated(Iterable<CacheEntryEvent<?, ?>> evts) {
+ try {
+ for (CacheEntryEvent<?, ?> evt : evts) {
+ CountDownLatch latch = this.latch;
+
+ log.info("Received cache event [evt=" + evt +
+ ", left=" + (latch != null ? latch.getCount() : null) + ']');
+
+ this.evts.put(evt.getKey(), evt);
+
+ keys.add((Integer)evt.getKey());
+
+ if (allEvts != null)
+ allEvts.add(evt);
+
+ assertTrue(latch != null);
+ assertTrue(latch.getCount() > 0);
+
+ latch.countDown();
+
+ if (latch.getCount() == 0) {
+ this.latch = null;
+
+ keys.clear();
+ }
+ }
+ }
+ catch (Throwable e) {
+ err = true;
+
+ log.error("Unexpected error", e);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private static class CacheEventListener2 implements CacheEntryUpdatedListener<Object, Object> {
+ /** */
+ @LoggerResource
+ private IgniteLogger log;
+
+ /** */
+ private final ConcurrentHashMap<Integer, Integer> vals = new ConcurrentHashMap<>();
+
+ /** */
+ private final ConcurrentHashMap<Integer, List<CacheEntryEvent<?, ?>>> evts = new ConcurrentHashMap<>();
+
+ /**
+ * @return Count events.
+ */
+ public int size() {
+ int size = 0;
+
+ for (List<CacheEntryEvent<?, ?>> e : evts.values())
+ size += e.size();
+
+ return size;
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized void onUpdated(Iterable<CacheEntryEvent<?, ?>> evts)
+ throws CacheEntryListenerException {
+ try {
+ for (CacheEntryEvent<?, ?> evt : evts) {
+ Integer key = (Integer)evt.getKey();
+ Integer val = (Integer)evt.getValue();
+
+ assertNotNull(key);
+ assertNotNull(val);
+
+ Integer prevVal = vals.get(key);
+
+ boolean dup = false;
+
+ if (prevVal != null && prevVal.equals(val))
+ dup = true;
+
+ if (!dup) {
+ vals.put(key, val);
+
+ List<CacheEntryEvent<?, ?>> keyEvts = this.evts.get(key);
+
+ if (keyEvts == null) {
+ keyEvts = Collections.synchronizedList(new ArrayList<CacheEntryEvent<?, ?>>());
+
+ this.evts.put(key, keyEvts);
+ }
+
+ keyEvts.add(evt);
+ }
+ }
+ }
+ catch (Throwable e) {
+ err = true;
+
+ log.error("Unexpected error", e);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public static class CacheEventListener3 implements CacheEntryUpdatedListener<Object, Object>,
+ CacheEntryEventSerializableFilter<Object, Object> {
+ /** Keys. */
+ GridConcurrentHashSet<Integer> keys = new GridConcurrentHashSet<>();
+
+ /** Events. */
+ private final ConcurrentHashMap<Object, CacheEntryEvent<?, ?>> evts = new ConcurrentHashMap<>();
+
+ /** {@inheritDoc} */
+ @Override public void onUpdated(Iterable<CacheEntryEvent<?, ?>> events) throws CacheEntryListenerException {
+ for (CacheEntryEvent<?, ?> e : events) {
+ Integer key = (Integer)e.getKey();
+
+ keys.add(key);
+
+ assert evts.put(key, e) == null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean evaluate(CacheEntryEvent<?, ?> e) throws CacheEntryListenerException {
+ return (Integer)e.getValue() % 2 == 0;
+ }
+ }
+
+ /**
+ *
+ */
+ public static class CacheEventFilter implements CacheEntryEventSerializableFilter<Object, Object> {
+ /** {@inheritDoc} */
+ @Override public boolean evaluate(CacheEntryEvent<?, ?> event) throws CacheEntryListenerException {
+ return ((Integer)event.getValue()) >= 0;
+ }
+ }
+
+ /**
+ *
+ */
+ private static class TestCommunicationSpi extends TcpCommunicationSpi {
+ /** */
+ @LoggerResource
+ private IgniteLogger log;
+
+ /** */
+ private volatile boolean skipMsg;
+
+ /** */
+ private volatile boolean skipAllMsg;
+
+ /** */
+ private volatile AtomicBoolean sndFirstOnly;
+
+ /** {@inheritDoc} */
+ @Override public void sendMessage(ClusterNode node, Message msg, IgniteInClosure<IgniteException> ackC)
+ throws IgniteSpiException {
+ Object msg0 = ((GridIoMessage)msg).message();
+
+ if (skipAllMsg)
+ return;
+
+ if (msg0 instanceof GridContinuousMessage) {
+ if (skipMsg) {
+ if (log.isDebugEnabled())
+ log.debug("Skip continuous message: " + msg0);
+
+ return;
+ }
+ else {
+ AtomicBoolean sndFirstOnly = this.sndFirstOnly;
+
+ if (sndFirstOnly != null && !sndFirstOnly.compareAndSet(false, true)) {
+ if (log.isDebugEnabled())
+ log.debug("Skip continuous message: " + msg0);
+
+ return;
+ }
+ }
+ }
+
+ super.sendMessage(node, msg, ackC);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicNearEnabledSelfSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicNearEnabledSelfSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicNearEnabledSelfSelfTest.java
new file mode 100644
index 0000000..b3c18a9
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicNearEnabledSelfSelfTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.query.continuous;
+
+import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+
+import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.PRIMARY;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+
+/**
+ *
+ */
+public class CacheContinuousQueryFailoverAtomicNearEnabledSelfSelfTest
+ extends CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest {
+ /** {@inheritDoc} */
+ @Override protected CacheMode cacheMode() {
+ return PARTITIONED;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected CacheAtomicWriteOrderMode writeOrderMode() {
+ return PRIMARY;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected NearCacheConfiguration nearCacheConfiguration() {
+ return super.nearCacheConfiguration();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest.java
new file mode 100644
index 0000000..e33db45
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.query.continuous;
+
+import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+
+import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.PRIMARY;
+
+/**
+ *
+ */
+public class CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest extends CacheContinuousQueryFailoverAbstractSelfTest {
+ /** {@inheritDoc} */
+ @Override protected CacheAtomicWriteOrderMode writeOrderMode() {
+ return PRIMARY;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected CacheMode cacheMode() {
+ return CacheMode.PARTITIONED;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected CacheAtomicityMode atomicityMode() {
+ return CacheAtomicityMode.ATOMIC;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicReplicatedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicReplicatedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicReplicatedSelfTest.java
new file mode 100644
index 0000000..84c9131
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAtomicReplicatedSelfTest.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.internal.processors.cache.query.continuous;
+
+import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
+import org.apache.ignite.cache.CacheMode;
+
+import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.PRIMARY;
+import static org.apache.ignite.cache.CacheMode.REPLICATED;
+
+/**
+ *
+ */
+public class CacheContinuousQueryFailoverAtomicReplicatedSelfTest
+ extends CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest {
+ /** {@inheritDoc} */
+ @Override protected CacheMode cacheMode() {
+ return REPLICATED;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected CacheAtomicWriteOrderMode writeOrderMode() {
+ return PRIMARY;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxReplicatedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxReplicatedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxReplicatedSelfTest.java
new file mode 100644
index 0000000..7c4f180
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxReplicatedSelfTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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.query.continuous;
+
+import org.apache.ignite.cache.CacheMode;
+
+import static org.apache.ignite.cache.CacheMode.REPLICATED;
+
+/**
+ *
+ */
+public class CacheContinuousQueryFailoverTxReplicatedSelfTest extends CacheContinuousQueryFailoverTxSelfTest {
+ /** {@inheritDoc} */
+ @Override protected CacheMode cacheMode() {
+ return REPLICATED;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxSelfTest.java
new file mode 100644
index 0000000..789a105
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverTxSelfTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.query.continuous;
+
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+
+/**
+ *
+ */
+public class CacheContinuousQueryFailoverTxSelfTest extends CacheContinuousQueryFailoverAbstractSelfTest {
+ /** {@inheritDoc} */
+ @Override protected CacheMode cacheMode() {
+ return PARTITIONED;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected CacheAtomicityMode atomicityMode() {
+ return TRANSACTIONAL;
+ }
+}
[09/23] ignite git commit: Optimization for single key cache 'get'
operation.
Posted by sb...@apache.org.
Optimization for single key cache 'get' operation.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1f103067
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1f103067
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1f103067
Branch: refs/heads/ignite-sql-opt
Commit: 1f1030670a6e7f9fbad1d939301c884f29b7885a
Parents: ba1d563
Author: sboikov <sb...@gridgain.com>
Authored: Thu Nov 19 17:29:04 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Nov 19 17:29:04 2015 +0300
----------------------------------------------------------------------
.../communication/GridIoMessageFactory.java | 12 +
.../processors/cache/GridCacheAdapter.java | 103 ++-
.../processors/cache/GridCacheAtomicFuture.java | 6 +
.../processors/cache/GridCacheFuture.java | 13 -
.../processors/cache/GridCacheIoManager.java | 50 +-
.../processors/cache/GridCacheMessage.java | 20 +-
.../processors/cache/GridCacheMvccFuture.java | 7 +
.../processors/cache/GridCacheMvccManager.java | 108 +--
.../distributed/GridCacheTxRecoveryFuture.java | 13 +-
.../dht/CacheDistributedGetFutureAdapter.java | 27 +-
.../cache/distributed/dht/CacheGetFuture.java | 32 +
.../distributed/dht/GridDhtCacheAdapter.java | 141 ++++
.../distributed/dht/GridDhtLockFuture.java | 16 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 9 +-
.../distributed/dht/GridDhtTxFinishFuture.java | 24 +-
.../cache/distributed/dht/GridDhtTxLocal.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 17 +-
.../dht/GridPartitionedGetFuture.java | 69 +-
.../dht/GridPartitionedSingleGetFuture.java | 697 +++++++++++++++++++
.../dht/atomic/GridDhtAtomicCache.java | 127 +++-
.../dht/atomic/GridDhtAtomicUpdateFuture.java | 84 +--
.../dht/atomic/GridDhtAtomicUpdateRequest.java | 11 +
.../dht/atomic/GridNearAtomicUpdateFuture.java | 5 -
.../dht/colocated/GridDhtColocatedCache.java | 160 ++++-
.../colocated/GridDhtColocatedLockFuture.java | 26 +-
.../distributed/near/CacheVersionedValue.java | 2 +-
.../distributed/near/GridNearCacheAdapter.java | 4 +-
.../distributed/near/GridNearGetFuture.java | 57 +-
.../distributed/near/GridNearGetRequest.java | 1 -
.../distributed/near/GridNearGetResponse.java | 2 -
.../distributed/near/GridNearLockFuture.java | 16 +-
...arOptimisticSerializableTxPrepareFuture.java | 17 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 19 +-
.../GridNearPessimisticTxPrepareFuture.java | 19 +-
.../near/GridNearSingleGetRequest.java | 396 +++++++++++
.../near/GridNearSingleGetResponse.java | 321 +++++++++
.../near/GridNearTransactionalCache.java | 2 +-
.../near/GridNearTxFinishFuture.java | 24 +-
.../cache/distributed/near/GridNearTxLocal.java | 149 ++--
.../near/GridNearTxPrepareFutureAdapter.java | 6 +-
.../processors/cache/local/GridLocalCache.java | 4 +-
.../cache/local/GridLocalLockFuture.java | 5 -
.../cache/transactions/IgniteTxHandler.java | 19 +-
.../transactions/IgniteTxLocalAdapter.java | 2 +-
.../cache/transactions/IgniteTxManager.java | 2 +-
.../IgniteClientReconnectCacheTest.java | 11 +-
.../cache/GridCacheAbstractFullApiSelfTest.java | 75 ++
.../GridCacheConcurrentTxMultiNodeTest.java | 15 -
.../cache/GridCachePartitionedGetSelfTest.java | 3 +-
.../IgniteCacheAbstractStopBusySelfTest.java | 27 +-
.../IgniteCacheP2pUnmarshallingErrorTest.java | 184 +++--
.../CacheGetFutureHangsSelfTest.java | 6 +
.../GridCacheAbstractNodeRestartSelfTest.java | 2 +
.../IgniteCacheSingleGetMessageTest.java | 357 ++++++++++
.../GridCacheReplicatedMetricsSelfTest.java | 9 -
.../testsuites/IgniteCacheTestSuite4.java | 3 +
56 files changed, 2908 insertions(+), 632 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
index 2503eda..3548aac 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
@@ -83,6 +83,8 @@ 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.distributed.near.GridNearLockRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxFinishResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareRequest;
@@ -696,6 +698,16 @@ public class GridIoMessageFactory implements MessageFactory {
break;
+ case 116:
+ msg = new GridNearSingleGetRequest();
+
+ break;
+
+ case 117:
+ msg = new GridNearSingleGetResponse();
+
+ break;
+
// [-3..114] - this
// [120..123] - DR
// [-4..-22] - SQL
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 cbb7486..562a0eb 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
@@ -599,11 +599,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
/** {@inheritDoc} */
- @Override public IgniteInternalFuture<Boolean> containsKeyAsync(K key) {
+ @Override public final IgniteInternalFuture<Boolean> containsKeyAsync(K key) {
A.notNull(key, "key");
- return getAllAsync(
- Collections.singletonList(key),
+ return (IgniteInternalFuture)getAsync(
+ key,
/*force primary*/false,
/*skip tx*/false,
/*subj id*/null,
@@ -611,15 +611,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
/*deserialize portable*/false,
/*skip values*/true,
/*can remap*/true
- ).chain(new CX1<IgniteInternalFuture<Map<K, V>>, Boolean>() {
- @Override public Boolean applyx(IgniteInternalFuture<Map<K, V>> fut) throws IgniteCheckedException {
- Map<K, V> map = fut.get();
-
- assert map.isEmpty() || map.size() == 1 : map.size();
-
- return map.isEmpty() ? false : map.values().iterator().next() != null;
- }
- });
+ );
}
/** {@inheritDoc} */
@@ -1473,6 +1465,52 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
/**
+ * @param key Key.
+ * @param forcePrimary Force primary.
+ * @param skipTx Skip tx.
+ * @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.
+ */
+ protected IgniteInternalFuture<V> getAsync(
+ final K key,
+ boolean forcePrimary,
+ boolean skipTx,
+ @Nullable UUID subjId,
+ String taskName,
+ boolean deserializePortable,
+ final boolean skipVals,
+ boolean canRemap
+ ) {
+ return getAllAsync(Collections.singletonList(key),
+ forcePrimary,
+ skipTx,
+ subjId,
+ taskName,
+ deserializePortable,
+ skipVals,
+ canRemap).chain(
+ new CX1<IgniteInternalFuture<Map<K, V>>, V>() {
+ @Override public V applyx(IgniteInternalFuture<Map<K, V>> e) throws IgniteCheckedException {
+ Map<K, V> map = e.get();
+
+ assert map.isEmpty() || map.size() == 1 : map.size();
+
+ if (skipVals) {
+ Boolean val = map.isEmpty() ? false : (Boolean)F.firstValue(map);
+
+ return (V)(val);
+ }
+
+ return map.get(key);
+ }
+ });
+ }
+
+ /**
* @param keys Keys.
* @param forcePrimary Force primary.
* @param skipTx Skip tx.
@@ -1524,7 +1562,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
* @return Future for the get operation.
* @see GridCacheAdapter#getAllAsync(Collection)
*/
- public IgniteInternalFuture<Map<K, V>> getAllAsync(@Nullable final Collection<? extends K> keys,
+ public final IgniteInternalFuture<Map<K, V>> getAllAsync(@Nullable final Collection<? extends K> keys,
boolean readThrough,
boolean checkTx,
@Nullable final UUID subjId,
@@ -1605,11 +1643,20 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
final boolean storeEnabled = !skipVals && readThrough && ctx.readThrough();
+ final boolean needEntry = storeEnabled || ctx.isSwapOrOffheapEnabled();
+
Map<KeyCacheObject, GridCacheVersion> misses = null;
for (KeyCacheObject key : keys) {
while (true) {
- GridCacheEntryEx entry = entryEx(key);
+ GridCacheEntryEx entry = needEntry ? entryEx(key) : peekEx(key);
+
+ if (entry == null) {
+ if (!skipVals && ctx.config().isStatisticsEnabled())
+ ctx.cache().metrics0().onRead(false);
+
+ break;
+ }
try {
T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(null,
@@ -4389,11 +4436,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
*/
@Nullable public V get(K key, boolean deserializePortable)
throws IgniteCheckedException {
- Map<K, V> map = getAllAsync(F.asList(key), deserializePortable).get();
-
- assert map.isEmpty() || map.size() == 1 : map.size();
-
- return map.get(key);
+ return getAsync(key, deserializePortable).get();
}
/**
@@ -4409,16 +4452,16 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return new GridFinishedFuture<>(e);
}
- return getAllAsync(Collections.singletonList(key), deserializePortable).chain(
- new CX1<IgniteInternalFuture<Map<K, V>>, V>() {
- @Override public V applyx(IgniteInternalFuture<Map<K, V>> e) throws IgniteCheckedException {
- Map<K, V> map = e.get();
-
- assert map.isEmpty() || map.size() == 1 : map.size();
+ String taskName = ctx.kernalContext().job().currentTaskName();
- return map.get(key);
- }
- });
+ return getAsync(key,
+ !ctx.config().isReadFromBackup(),
+ /*skip tx*/false,
+ null,
+ taskName,
+ deserializePortable,
+ false,
+ /*can remap*/true);
}
/**
@@ -4445,10 +4488,10 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return getAllAsync(keys,
!ctx.config().isReadFromBackup(),
/*skip tx*/false,
- null,
+ /*subject id*/null,
taskName,
deserializePortable,
- false,
+ /*skip vals*/false,
/*can remap*/true);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java
index be35c5c..359909e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicFuture.java
@@ -20,12 +20,18 @@ package org.apache.ignite.internal.processors.cache;
import java.util.Collection;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
/**
* Update future for atomic cache.
*/
public interface GridCacheAtomicFuture<R> extends GridCacheFuture<R> {
/**
+ * @return Future version.
+ */
+ public GridCacheVersion version();
+
+ /**
* Gets future that will be completed when it is safe when update is finished on the given version of topology.
*
* @param topVer Topology version to finish.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheFuture.java
index caa3d3f..8bf8d40 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheFuture.java
@@ -17,11 +17,8 @@
package org.apache.ignite.internal.processors.cache;
-import java.util.Collection;
import java.util.UUID;
-import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.IgniteInternalFuture;
-import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.lang.IgniteUuid;
/**
@@ -34,16 +31,6 @@ public interface GridCacheFuture<R> extends IgniteInternalFuture<R> {
public IgniteUuid futureId();
/**
- * @return Future version.
- */
- public GridCacheVersion version();
-
- /**
- * @return Involved nodes.
- */
- public Collection<? extends ClusterNode> nodes();
-
- /**
* Callback for when node left.
*
* @param nodeId Left node ID.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
index 2334780..9afbca8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
@@ -34,22 +34,24 @@ import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.managers.communication.GridMessageListener;
import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.distributed.dht.CacheGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockRequest;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockResponse;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareRequest;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareResponse;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedGetFuture;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateRequest;
import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicUpdateResponse;
import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateRequest;
import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysRequest;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysResponse;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse;
import org.apache.ignite.internal.processors.cache.query.GridCacheQueryRequest;
@@ -437,7 +439,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
case 50: {
GridNearGetResponse res = (GridNearGetResponse)msg;
- GridCacheFuture fut = ctx.mvcc().future(res.version(), res.futureId());
+ CacheGetFuture fut = (CacheGetFuture)ctx.mvcc().future(res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
@@ -448,10 +450,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
res.error(res.classError());
- if (fut instanceof GridNearGetFuture)
- ((GridNearGetFuture)fut).onResult(nodeId, res);
- else
- ((GridPartitionedGetFuture)fut).onResult(nodeId, res);
+ fut.onResult(nodeId, res);
}
break;
@@ -521,6 +520,43 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
break;
+ case 116: {
+ GridNearSingleGetRequest req = (GridNearSingleGetRequest)msg;
+
+ GridNearSingleGetResponse res = new GridNearSingleGetResponse(
+ ctx.cacheId(),
+ req.futureId(),
+ req.topologyVersion(),
+ null,
+ false,
+ req.deployInfo() != null);
+
+ res.error(req.classError());
+
+ sendResponseOnFailedMessage(nodeId, res, cctx, ctx.ioPolicy());
+ }
+
+ break;
+
+ case 117: {
+ GridNearSingleGetResponse res = (GridNearSingleGetResponse)msg;
+
+ GridPartitionedSingleGetFuture fut = (GridPartitionedSingleGetFuture)ctx.mvcc().future(res.futureId());
+
+ if (fut == null) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to find future for get response [sender=" + nodeId + ", res=" + res + ']');
+
+ return;
+ }
+
+ res.error(res.classError());
+
+ fut.onResult(nodeId, res);
+ }
+
+ break;
+
default:
throw new IgniteCheckedException("Failed to send response to node. Unsupported direct type [message="
+ msg + "]");
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
index bdd2118..61136bf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
@@ -499,15 +499,21 @@ public abstract class GridCacheMessage implements Message {
int size = col.size();
- for (int i = 0 ; i < size; i++) {
- CacheObject obj = col.get(i);
+ for (int i = 0 ; i < size; i++)
+ prepareMarshalCacheObject(col.get(i), ctx);
+ }
- if (obj != null) {
- obj.prepareMarshal(ctx.cacheObjectContext());
+ /**
+ * @param obj Object.
+ * @param ctx Context.
+ * @throws IgniteCheckedException If failed.
+ */
+ protected final void prepareMarshalCacheObject(CacheObject obj, GridCacheContext ctx) throws IgniteCheckedException {
+ if (obj != null) {
+ obj.prepareMarshal(ctx.cacheObjectContext());
- if (addDepInfo)
- prepareObject(obj.value(ctx.cacheObjectContext(), false), ctx);
- }
+ if (addDepInfo)
+ prepareObject(obj.value(ctx.cacheObjectContext(), false), ctx);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFuture.java
index 67c1330..080a6f1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFuture.java
@@ -17,11 +17,18 @@
package org.apache.ignite.internal.processors.cache;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+
/**
* Distributed future aware of MVCC locking.
*/
public interface GridCacheMvccFuture<T> extends GridCacheFuture<T> {
/**
+ * @return Future version.
+ */
+ public GridCacheVersion version();
+
+ /**
* @param entry Entry which received new owner.
* @param owner Owner.
* @return {@code True} if future cares about this entry.
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
index 8562f37..9104acb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.processors.cache;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -31,7 +30,6 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.events.DiscoveryEvent;
import org.apache.ignite.events.Event;
import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
@@ -101,12 +99,15 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
/** Active futures mapped by version ID. */
@GridToStringExclude
- private final ConcurrentMap<GridCacheVersion, Collection<GridCacheFuture<?>>> futs = newMap();
+ private final ConcurrentMap<GridCacheVersion, Collection<GridCacheMvccFuture<?>>> mvccFuts = newMap();
/** Pending atomic futures. */
private final ConcurrentMap<GridCacheVersion, GridCacheAtomicFuture<?>> atomicFuts =
new ConcurrentHashMap8<>();
+ /** */
+ private final ConcurrentMap<IgniteUuid, GridCacheFuture<?>> futs = new ConcurrentHashMap8<>();
+
/** Near to DHT version mapping. */
private final ConcurrentMap<GridCacheVersion, GridCacheVersion> near2dht = newMap();
@@ -137,12 +138,12 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
prev + ']');
if (owner != null && (owner.local() || owner.nearLocal())) {
- Collection<? extends GridCacheFuture> futCol = futs.get(owner.version());
+ Collection<GridCacheMvccFuture<?>> futCol = mvccFuts.get(owner.version());
if (futCol != null) {
synchronized (futCol) {
- for (GridCacheFuture fut : futCol) {
- if (fut instanceof GridCacheMvccFuture && !fut.isDone()) {
+ for (GridCacheMvccFuture<?> fut : futCol) {
+ if (!fut.isDone()) {
GridCacheMvccFuture<Boolean> mvccFut = (GridCacheMvccFuture<Boolean>)fut;
// Since this method is called outside of entry synchronization,
@@ -206,18 +207,14 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
for (GridCacheFuture<?> fut : activeFutures())
fut.onNodeLeft(discoEvt.eventNode().id());
- for (IgniteInternalFuture<?> fut : atomicFuts.values()) {
- if (fut instanceof GridCacheFuture) {
- GridCacheFuture cacheFut = (GridCacheFuture)fut;
+ for (GridCacheAtomicFuture<?> cacheFut : atomicFuts.values()) {
+ cacheFut.onNodeLeft(discoEvt.eventNode().id());
- cacheFut.onNodeLeft(discoEvt.eventNode().id());
+ if (cacheFut.isCancelled() || cacheFut.isDone()) {
+ GridCacheVersion futVer = cacheFut.version();
- if (cacheFut.isCancelled() || cacheFut.isDone()) {
- GridCacheVersion futVer = cacheFut.version();
-
- if (futVer != null)
- atomicFuts.remove(futVer, fut);
- }
+ if (futVer != null)
+ atomicFuts.remove(futVer, cacheFut);
}
}
}
@@ -261,12 +258,14 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
public Collection<GridCacheFuture<?>> activeFutures() {
ArrayList<GridCacheFuture<?>> col = new ArrayList<>();
- for (Collection<GridCacheFuture<?>> verFuts : futs.values()) {
- synchronized (verFuts) {
- col.addAll(verFuts);
+ for (Collection<GridCacheMvccFuture<?>> futs : mvccFuts.values()) {
+ synchronized (futs) {
+ col.addAll(futs);
}
}
+ col.addAll(futs.values());
+
return col;
}
@@ -420,13 +419,25 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
}
/**
+ * @param fut Future.
+ * @param futId Future ID.
+ */
+ public void addFuture(final GridCacheFuture<?> fut, final IgniteUuid futId) {
+ GridCacheFuture<?> old = futs.put(futId, fut);
+
+ assert old == null : old;
+
+ onFutureAdded(fut);
+ }
+
+ /**
* Adds future.
*
* @param fut Future.
* @return {@code True} if added.
*/
@SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"})
- public boolean addFuture(final GridCacheFuture<?> fut) {
+ public boolean addFuture(final GridCacheMvccFuture<?> fut) {
if (fut.isDone()) {
fut.markNotTrackable();
@@ -437,10 +448,10 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
return true;
while (true) {
- Collection<GridCacheFuture<?>> old = futs.get(fut.version());
+ Collection<GridCacheMvccFuture<?>> old = mvccFuts.get(fut.version());
if (old == null) {
- Collection<GridCacheFuture<?>> col = new HashSet<GridCacheFuture<?>>(U.capacity(4), 0.75f) {
+ Collection<GridCacheMvccFuture<?>> col = new HashSet<GridCacheMvccFuture<?>>(U.capacity(4), 0.75f) {
{
// Make sure that we add future to queue before
// adding queue to the map of futures.
@@ -456,7 +467,7 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
}
};
- old = futs.putIfAbsent(fut.version(), col);
+ old = mvccFuts.putIfAbsent(fut.version(), col);
}
if (old != null) {
@@ -471,7 +482,7 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
// Future is being removed, so we force-remove here and try again.
if (empty) {
- if (futs.remove(fut.version(), old)) {
+ if (mvccFuts.remove(fut.version(), old)) {
if (log.isDebugEnabled())
log.debug("Removed future list from futures map for lock version: " + fut.version());
}
@@ -501,16 +512,9 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
break;
}
- // Close window in case of node is gone before the future got added to
- // the map of futures.
- for (ClusterNode n : fut.nodes()) {
- if (cctx.discovery().node(n.id()) == null)
- fut.onNodeLeft(n.id());
- }
-
// Just in case if future was completed before it was added.
if (fut.isDone())
- removeFuture(fut);
+ removeMvccFuture(fut);
else
onFutureAdded(fut);
@@ -537,15 +541,22 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
}
/**
+ * @param futId Future ID.
+ */
+ public void removeFuture(IgniteUuid futId) {
+ futs.remove(futId);
+ }
+
+ /**
* @param fut Future to remove.
* @return {@code True} if removed.
*/
@SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"})
- public boolean removeFuture(GridCacheFuture<?> fut) {
+ public boolean removeMvccFuture(GridCacheMvccFuture<?> fut) {
if (!fut.trackable())
return true;
- Collection<GridCacheFuture<?>> cur = futs.get(fut.version());
+ Collection<GridCacheMvccFuture<?>> cur = mvccFuts.get(fut.version());
if (cur == null)
return false;
@@ -565,7 +576,7 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
else if (log.isDebugEnabled())
log.debug("Attempted to remove a non-registered future (has it been already removed?): " + fut);
- if (empty && futs.remove(fut.version(), cur))
+ if (empty && mvccFuts.remove(fut.version(), cur))
if (log.isDebugEnabled())
log.debug("Removed future list from futures map for lock version: " + fut.version());
@@ -580,12 +591,12 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
* @return Future.
*/
@SuppressWarnings({"unchecked"})
- @Nullable public GridCacheFuture future(GridCacheVersion ver, IgniteUuid futId) {
- Collection<? extends GridCacheFuture> futs = this.futs.get(ver);
+ @Nullable public GridCacheMvccFuture<?> mvccFuture(GridCacheVersion ver, IgniteUuid futId) {
+ Collection<GridCacheMvccFuture<?>> futs = this.mvccFuts.get(ver);
if (futs != null) {
synchronized (futs) {
- for (GridCacheFuture<?> fut : futs) {
+ for (GridCacheMvccFuture<?> fut : futs) {
if (fut.futureId().equals(futId)) {
if (log.isDebugEnabled())
log.debug("Found future in futures map: " + fut);
@@ -603,22 +614,11 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
}
/**
- * Gets all futures for given lock version, possibly empty collection.
- *
- * @param ver Version.
- * @return All futures for given lock version.
+ * @param futId Future ID.
+ * @return Found future.
*/
- @SuppressWarnings("unchecked")
- public <T> Collection<? extends IgniteInternalFuture<T>> futures(GridCacheVersion ver) {
- Collection c = futs.get(ver);
-
- if (c == null)
- return Collections.<IgniteInternalFuture<T>>emptyList();
- else {
- synchronized (c) {
- return new ArrayList<>((Collection<IgniteInternalFuture<T>>)c);
- }
- }
+ @Nullable public GridCacheFuture future(IgniteUuid futId) {
+ return futs.get(futId);
}
/**
@@ -913,7 +913,7 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
X.println(">>> Mvcc manager memory stats [grid=" + cctx.gridName() + ']');
X.println(">>> rmvLocksSize: " + rmvLocks.sizex());
X.println(">>> lockedSize: " + locked.size());
- X.println(">>> futsSize: " + futs.size());
+ X.println(">>> futsSize: " + (mvccFuts.size() + futs.size()));
X.println(">>> near2dhtSize: " + near2dht.size());
X.println(">>> finishFutsSize: " + finishFuts.sizex());
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
index 01c4867..1648de0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
@@ -29,7 +29,6 @@ import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.processors.cache.GridCacheFuture;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
-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.GridFutureAdapter;
@@ -389,16 +388,6 @@ public class GridCacheTxRecoveryFuture extends GridCompoundIdentityFuture<Boolea
}
/** {@inheritDoc} */
- @Override public GridCacheVersion version() {
- return tx.xidVersion();
- }
-
- /** {@inheritDoc} */
- @Override public Collection<? extends ClusterNode> nodes() {
- return nodes.values();
- }
-
- /** {@inheritDoc} */
@Override public boolean onNodeLeft(UUID nodeId) {
for (IgniteInternalFuture<?> fut : futures())
if (isMini(fut)) {
@@ -424,7 +413,7 @@ public class GridCacheTxRecoveryFuture extends GridCompoundIdentityFuture<Boolea
/** {@inheritDoc} */
@Override public boolean onDone(@Nullable Boolean res, @Nullable Throwable err) {
if (super.onDone(res, err)) {
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeFuture(futId);
if (err == null) {
assert res != null;
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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
index 721ba4e..245ffc6 100644
--- 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
@@ -18,9 +18,12 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheFuture;
import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
@@ -40,7 +43,7 @@ import static org.apache.ignite.IgniteSystemProperties.getInteger;
*
*/
public abstract class CacheDistributedGetFutureAdapter<K, V> extends GridCompoundIdentityFuture<Map<K, V>>
- implements GridCacheFuture<Map<K, V>> {
+ implements GridCacheFuture<Map<K, V>>, CacheGetFuture {
/** Default max remap count value. */
public static final int DFLT_MAX_REMAP_CNT = 3;
@@ -155,4 +158,26 @@ public abstract class CacheDistributedGetFutureAdapter<K, V> extends GridCompoun
map.put(key, new T2<>(skipVals ? true : val, ver));
}
+
+ /**
+ * Affinity node to send get request to.
+ *
+ * @param key Key to get.
+ * @param topVer Topology version.
+ * @return Affinity node to get key from.
+ */
+ protected final ClusterNode affinityNode(KeyCacheObject key, AffinityTopologyVersion topVer) {
+ if (!canRemap) {
+ List<ClusterNode> affNodes = cctx.affinity().nodes(key, topVer);
+
+ for (ClusterNode node : affNodes) {
+ if (cctx.discovery().alive(node))
+ return node;
+ }
+
+ return null;
+ }
+ else
+ return cctx.affinity().primary(key, topVer);
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheGetFuture.java
new file mode 100644
index 0000000..ebe2cff
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheGetFuture.java
@@ -0,0 +1,32 @@
+/*
+ * 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.UUID;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
+
+/**
+ *
+ */
+public interface CacheGetFuture {
+ /**
+ * @param nodeId Node ID.
+ * @param res Response.
+ */
+ public void onResult(UUID nodeId, GridNearGetResponse res);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 bdd1140..8537357 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
@@ -57,9 +57,12 @@ import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCa
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.dht.colocated.GridDhtDetachedCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader;
+import org.apache.ignite.internal.processors.cache.distributed.near.CacheVersionedValue;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetResponse;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.platform.cache.PlatformCacheEntryFilter;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
@@ -76,6 +79,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiPredicate;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.plugin.extensions.communication.Message;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
@@ -110,6 +114,46 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
}
/**
+ * @param nodeId Sender node ID.
+ * @param res Near get response.
+ */
+ protected final void processNearGetResponse(UUID nodeId, GridNearGetResponse res) {
+ if (log.isDebugEnabled())
+ log.debug("Processing near get response [nodeId=" + nodeId + ", res=" + res + ']');
+
+ CacheGetFuture fut = (CacheGetFuture)ctx.mvcc().future(res.futureId());
+
+ if (fut == null) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to find future for get response [sender=" + nodeId + ", res=" + res + ']');
+
+ return;
+ }
+
+ fut.onResult(nodeId, res);
+ }
+
+ /**
+ * @param nodeId Sender node ID.
+ * @param res Near get response.
+ */
+ protected void processNearSingleGetResponse(UUID nodeId, GridNearSingleGetResponse res) {
+ if (log.isDebugEnabled())
+ log.debug("Processing near get response [nodeId=" + nodeId + ", res=" + res + ']');
+
+ GridPartitionedSingleGetFuture fut = (GridPartitionedSingleGetFuture)ctx.mvcc().future(res.futureId());
+
+ if (fut == null) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to find future for get response [sender=" + nodeId + ", res=" + res + ']');
+
+ return;
+ }
+
+ fut.onResult(nodeId, res);
+ }
+
+ /**
* @param ctx Context.
*/
protected GridDhtCacheAdapter(GridCacheContext<K, V> ctx) {
@@ -669,6 +713,103 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
* @param nodeId Node ID.
* @param req Get request.
*/
+ protected void processNearSingleGetRequest(final UUID nodeId, final GridNearSingleGetRequest req) {
+ assert ctx.affinityNode();
+
+ long ttl = req.accessTtl();
+
+ final CacheExpiryPolicy expiryPlc = CacheExpiryPolicy.forAccess(ttl);
+
+ LinkedHashMap<KeyCacheObject, Boolean> map = U.newLinkedHashMap(1);
+
+ map.put(req.key(), req.addReader());
+
+ IgniteInternalFuture<Collection<GridCacheEntryInfo>> fut =
+ getDhtAsync(nodeId,
+ req.messageId(),
+ map,
+ req.readThrough(),
+ req.topologyVersion(),
+ req.subjectId(),
+ req.taskNameHash(),
+ expiryPlc,
+ req.skipValues());
+
+ fut.listen(new CI1<IgniteInternalFuture<Collection<GridCacheEntryInfo>>>() {
+ @Override public void apply(IgniteInternalFuture<Collection<GridCacheEntryInfo>> f) {
+ GridNearSingleGetResponse res;
+
+ GridDhtFuture<Collection<GridCacheEntryInfo>> fut =
+ (GridDhtFuture<Collection<GridCacheEntryInfo>>)f;
+
+ try {
+ Collection<GridCacheEntryInfo> entries = fut.get();
+
+ if (F.isEmpty(fut.invalidPartitions())) {
+ GridCacheEntryInfo info = F.first(entries);
+
+ Message res0 = null;
+
+ if (info != null) {
+ if (req.needEntryInfo()) {
+ info.key(null);
+
+ res0 = info;
+ } else if (req.needVersion())
+ res0 = new CacheVersionedValue(info.value(), info.version());
+ else
+ res0 = info.value();
+ }
+
+ res = new GridNearSingleGetResponse(ctx.cacheId(),
+ req.futureId(),
+ req.topologyVersion(),
+ res0,
+ false,
+ req.addDeploymentInfo());
+
+ if (info != null && req.skipValues())
+ res.setContainsValue();
+ }
+ else {
+ res = new GridNearSingleGetResponse(ctx.cacheId(),
+ req.futureId(),
+ ctx.shared().exchange().readyAffinityVersion(),
+ null,
+ true,
+ req.addDeploymentInfo());
+ }
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed processing get request: " + req, e);
+
+ res = new GridNearSingleGetResponse(ctx.cacheId(),
+ req.futureId(),
+ req.topologyVersion(),
+ null,
+ false,
+ req.addDeploymentInfo());
+
+ res.error(e);
+ }
+
+ try {
+ ctx.io().send(nodeId, res, ctx.ioPolicy());
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed to send get response to node (is node still alive?) [nodeId=" + nodeId +
+ ",req=" + req + ", res=" + res + ']', e);
+ }
+
+ sendTtlUpdateRequest(expiryPlc);
+ }
+ });
+ }
+
+ /**
+ * @param nodeId Node ID.
+ * @param req Get request.
+ */
protected void processNearGetRequest(final UUID nodeId, final GridNearGetRequest req) {
assert ctx.affinityNode();
assert !req.reload() : req;
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 7284fd4..a7978c9 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
@@ -262,20 +262,6 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
log.debug("Added invalid partition to future [invalidPart=" + invalidPart + ", fut=" + this + ']');
}
- /**
- * @return Participating nodes.
- */
- @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 GridCacheVersion version() {
return lockVer;
@@ -756,7 +742,7 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
log.debug("Completing future: " + this);
// Clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeMvccFuture(this);
if (timeoutObj != null)
cctx.time().removeTimeoutObject(timeoutObj);
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 35f63e3..2468cf0 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
@@ -50,6 +50,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.Gri
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockResponse;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearSingleGetRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTransactionalCache;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxRemote;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearUnlockRequest;
@@ -126,6 +127,12 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
}
});
+ ctx.io().addHandler(ctx.cacheId(), GridNearSingleGetRequest.class, new CI2<UUID, GridNearSingleGetRequest>() {
+ @Override public void apply(UUID nodeId, GridNearSingleGetRequest req) {
+ processNearSingleGetRequest(nodeId, req);
+ }
+ });
+
ctx.io().addHandler(ctx.cacheId(), GridNearLockRequest.class, new CI2<UUID, GridNearLockRequest>() {
@Override public void apply(UUID nodeId, GridNearLockRequest req) {
processNearLockRequest(nodeId, req);
@@ -566,7 +573,7 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
private void processDhtLockResponse(UUID nodeId, GridDhtLockResponse res) {
assert nodeId != null;
assert res != null;
- GridDhtLockFuture fut = (GridDhtLockFuture)ctx.mvcc().<Boolean>future(res.version(), res.futureId());
+ GridDhtLockFuture fut = (GridDhtLockFuture)ctx.mvcc().<Boolean>mvccFuture(res.version(), res.futureId());
if (fut == null) {
if (log.isDebugEnabled())
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
index 992bd66..bb370a5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
@@ -66,7 +66,7 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
private GridCacheSharedContext<K, V> cctx;
/** Future ID. */
- private IgniteUuid futId;
+ private final IgniteUuid futId;
/** Transaction. */
@GridToStringExclude
@@ -115,26 +115,6 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
}
/** {@inheritDoc} */
- @Override public GridCacheVersion version() {
- return tx.xidVersion();
- }
-
- /**
- * @return Involved nodes.
- */
- @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) {
for (IgniteInternalFuture<?> fut : futures())
if (isMini(fut)) {
@@ -228,7 +208,7 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
this.tx.sendFinishReply(commit, error());
// Don't forget to clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeFuture(futId);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 2bed931..f344d48 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
@@ -490,7 +490,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
final GridDhtTxFinishFuture fut = new GridDhtTxFinishFuture<>(cctx, this, /*commit*/true);
- cctx.mvcc().addFuture(fut);
+ cctx.mvcc().addFuture(fut, fut.futureId());
GridDhtTxPrepareFuture prep = prepFut.get();
@@ -580,7 +580,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
final GridDhtTxFinishFuture fut = new GridDhtTxFinishFuture<>(cctx, this, /*rollback*/false);
- cctx.mvcc().addFuture(fut);
+ cctx.mvcc().addFuture(fut, fut.futureId());
if (prepFut == null) {
try {
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 d081c0c..4cb5d05 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
@@ -243,21 +243,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
return tx.xidVersion();
}
- /**
- * @return Involved nodes.
- */
- @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 onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
if (log.isDebugEnabled())
@@ -823,7 +808,7 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
if (super.onDone(res, err.get())) {
// Don't forget to clean up.
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeMvccFuture(this);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1f103067/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 febe9ba..c3d9836 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
@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
@@ -57,10 +56,11 @@ 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.IgniteClosure;
import org.apache.ignite.lang.IgniteUuid;
import org.jetbrains.annotations.Nullable;
+import static org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture.*;
+
/**
* Colocated get future.
*/
@@ -71,15 +71,15 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
/** Logger reference. */
private static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
+ /** Dummy version sent to older nodes for backward compatibility, */
+ private static final GridCacheVersion DUMMY_VER = new GridCacheVersion(0, 0, 0, 0);
+
/** Logger. */
private static IgniteLogger log;
/** Topology version. */
private AffinityTopologyVersion topVer;
- /** Version. */
- private GridCacheVersion ver;
-
/**
* @param cctx Context.
* @param keys Keys.
@@ -126,8 +126,6 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
this.topVer = topVer;
- ver = cctx.versions().next();
-
if (log == null)
log = U.logger(cctx.kernalContext(), logRef, GridPartitionedGetFuture.class);
}
@@ -160,25 +158,6 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
}
/** {@inheritDoc} */
- @Override public GridCacheVersion version() {
- return ver;
- }
-
- /** {@inheritDoc} */
- @SuppressWarnings("unchecked")
- @Override public Collection<? extends ClusterNode> nodes() {
- return
- F.viewReadOnly(futures(), new IgniteClosure<IgniteInternalFuture<Map<K, V>>, ClusterNode>() {
- @Nullable @Override public ClusterNode apply(IgniteInternalFuture<Map<K, V>> f) {
- if (isMini(f))
- return ((MiniFuture)f).node();
-
- return cctx.discovery().localNode();
- }
- });
- }
-
- /** {@inheritDoc} */
@Override public boolean onNodeLeft(UUID nodeId) {
boolean found = false;
@@ -219,7 +198,7 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
if (super.onDone(res, err)) {
// Don't forget to clean up.
if (trackable)
- cctx.mvcc().removeFuture(this);
+ cctx.mvcc().removeFuture(futId);
cache().sendTtlUpdateRequest(expiryPlc);
@@ -274,9 +253,11 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
add(new GridFinishedFuture<>(locVals));
if (hasRmtNodes) {
- trackable = true;
+ if (!trackable) {
+ trackable = true;
- cctx.mvcc().addFuture(this);
+ cctx.mvcc().addFuture(this, futId);
+ }
}
// Create mini futures.
@@ -343,7 +324,7 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
cctx.cacheId(),
futId,
fut.futureId(),
- ver,
+ n.version().compareTo(SINGLE_GET_MSG_SINCE) >= 0 ? null : DUMMY_VER,
mappedKeys,
readThrough,
topVer,
@@ -390,7 +371,8 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
boolean remote = false;
// Allow to get cached value from the local node.
- boolean allowLocRead = !forcePrimary || cctx.affinity().primary(cctx.localNode(), key, topVer);
+ boolean allowLocRead = (cctx.affinityNode() && !forcePrimary) ||
+ cctx.affinity().primary(cctx.localNode(), key, topVer);
while (true) {
GridCacheEntryEx entry;
@@ -521,28 +503,6 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
}
/**
- * Finds affinity node to send get request to.
- *
- * @param key Key to get.
- * @param topVer Topology version.
- * @return Affinity node from which the key will be requested.
- */
- private ClusterNode affinityNode(KeyCacheObject key, AffinityTopologyVersion topVer) {
- if (!canRemap) {
- List<ClusterNode> nodes = cctx.affinity().nodes(key, topVer);
-
- for (ClusterNode node : nodes) {
- if (cctx.discovery().alive(node))
- return node;
- }
-
- return null;
- }
- else
- return cctx.affinity().primary(key, topVer);
- }
-
- /**
* @param infos Entry infos.
* @return Result map.
*/
@@ -557,7 +517,7 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
if (needVer)
versionedResult(map, info.key(), info.value(), info.version());
- else
+ else {
cctx.addResult(map,
info.key(),
info.value(),
@@ -565,6 +525,7 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
keepCacheObjects,
deserializePortable,
false);
+ }
}
return map;
[22/23] ignite git commit: Merge remote-tracking branch
'remotes/origin/ignite-1.5' into ignite-sql-opt
Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/origin/ignite-1.5' into ignite-sql-opt
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f939df4d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f939df4d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f939df4d
Branch: refs/heads/ignite-sql-opt
Commit: f939df4d074803d7878429e51b49ca10627ba4ef
Parents: da3af86 ce63637
Author: sboikov <sb...@gridgain.com>
Authored: Fri Nov 20 08:43:19 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Fri Nov 20 08:43:19 2015 +0300
----------------------------------------------------------------------
modules/camel/README.txt | 34 +
modules/camel/licenses/apache-2.0.txt | 202 ++
.../ignite/stream/camel/CamelStreamer.java | 2 +-
.../java/org/apache/ignite/IgniteCache.java | 3 +-
.../java/org/apache/ignite/IgniteCompute.java | 3 +-
.../org/apache/ignite/compute/ComputeJob.java | 2 +-
.../internal/GridEventConsumeHandler.java | 22 +-
.../internal/GridMessageListenHandler.java | 18 +
.../ignite/internal/GridUpdateNotifier.java | 2 +-
.../communication/GridIoMessageFactory.java | 20 +-
.../processors/cache/GridCacheAdapter.java | 103 +-
.../processors/cache/GridCacheAtomicFuture.java | 6 +
.../processors/cache/GridCacheEntryEx.java | 12 +-
.../processors/cache/GridCacheFuture.java | 13 -
.../processors/cache/GridCacheIoManager.java | 50 +-
.../processors/cache/GridCacheMapEntry.java | 147 +-
.../processors/cache/GridCacheMessage.java | 20 +-
.../processors/cache/GridCacheMvccFuture.java | 7 +
.../processors/cache/GridCacheMvccManager.java | 108 +-
.../GridCachePartitionExchangeManager.java | 4 +-
.../cache/GridCacheUpdateAtomicResult.java | 15 +-
.../cache/GridCacheUpdateTxResult.java | 24 +-
.../processors/cache/IgniteCacheProxy.java | 3 +
.../distributed/GridCacheTxRecoveryFuture.java | 13 +-
.../GridDistributedTxRemoteAdapter.java | 22 +-
.../dht/CacheDistributedGetFutureAdapter.java | 27 +-
.../cache/distributed/dht/CacheGetFuture.java | 32 +
.../dht/GridClientPartitionTopology.java | 38 +-
.../distributed/dht/GridDhtCacheAdapter.java | 141 ++
.../distributed/dht/GridDhtLocalPartition.java | 35 +
.../distributed/dht/GridDhtLockFuture.java | 16 +-
.../dht/GridDhtPartitionTopology.java | 26 +-
.../dht/GridDhtPartitionTopologyImpl.java | 112 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 9 +-
.../distributed/dht/GridDhtTxFinishFuture.java | 38 +-
.../distributed/dht/GridDhtTxFinishRequest.java | 112 +-
.../cache/distributed/dht/GridDhtTxLocal.java | 4 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 17 +-
.../dht/GridPartitionedGetFuture.java | 69 +-
.../dht/GridPartitionedSingleGetFuture.java | 697 ++++++
.../dht/atomic/GridDhtAtomicCache.java | 206 +-
.../dht/atomic/GridDhtAtomicUpdateFuture.java | 159 +-
.../dht/atomic/GridDhtAtomicUpdateRequest.java | 151 +-
.../dht/atomic/GridNearAtomicUpdateFuture.java | 5 -
.../dht/colocated/GridDhtColocatedCache.java | 160 +-
.../colocated/GridDhtColocatedLockFuture.java | 26 +-
.../GridDhtPartitionsExchangeFuture.java | 35 +-
.../preloader/GridDhtPartitionsFullMessage.java | 64 +-
.../GridDhtPartitionsSingleMessage.java | 56 +-
.../distributed/near/CacheVersionedValue.java | 2 +-
.../distributed/near/GridNearAtomicCache.java | 10 +-
.../distributed/near/GridNearCacheAdapter.java | 4 +-
.../distributed/near/GridNearGetFuture.java | 57 +-
.../distributed/near/GridNearGetRequest.java | 1 -
.../distributed/near/GridNearGetResponse.java | 2 -
.../distributed/near/GridNearLockFuture.java | 16 +-
...arOptimisticSerializableTxPrepareFuture.java | 17 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 19 +-
.../GridNearPessimisticTxPrepareFuture.java | 19 +-
.../near/GridNearSingleGetRequest.java | 396 ++++
.../near/GridNearSingleGetResponse.java | 321 +++
.../near/GridNearTransactionalCache.java | 2 +-
.../near/GridNearTxFinishFuture.java | 24 +-
.../cache/distributed/near/GridNearTxLocal.java | 149 +-
.../near/GridNearTxPrepareFutureAdapter.java | 6 +-
.../distributed/near/GridNearTxRemote.java | 7 +
.../processors/cache/local/GridLocalCache.java | 4 +-
.../cache/local/GridLocalLockFuture.java | 5 -
.../CacheContinuousQueryBatchAck.java | 163 ++
.../continuous/CacheContinuousQueryEntry.java | 196 +-
.../continuous/CacheContinuousQueryEvent.java | 3 +-
.../continuous/CacheContinuousQueryHandler.java | 811 ++++++-
.../CacheContinuousQueryListener.java | 35 +
.../continuous/CacheContinuousQueryManager.java | 151 +-
.../cache/transactions/IgniteTxEntry.java | 20 +
.../cache/transactions/IgniteTxHandler.java | 22 +-
.../transactions/IgniteTxLocalAdapter.java | 20 +-
.../cache/transactions/IgniteTxManager.java | 2 +-
.../cache/transactions/IgniteTxRemoteEx.java | 7 +-
.../continuous/GridContinuousBatch.java | 44 +
.../continuous/GridContinuousBatchAdapter.java | 46 +
.../continuous/GridContinuousHandler.java | 22 +
.../continuous/GridContinuousProcessor.java | 221 +-
.../StartRoutineAckDiscoveryMessage.java | 14 +-
.../StartRoutineDiscoveryMessage.java | 21 +-
.../ignite/marshaller/MarshallerExclusions.java | 4 +-
.../IgniteClientReconnectCacheTest.java | 11 +-
.../cache/GridCacheAbstractFullApiSelfTest.java | 75 +
.../GridCacheConcurrentTxMultiNodeTest.java | 15 -
.../cache/GridCachePartitionedGetSelfTest.java | 3 +-
.../processors/cache/GridCacheTestEntryEx.java | 10 +-
.../IgniteCacheAbstractStopBusySelfTest.java | 27 +-
.../IgniteCacheP2pUnmarshallingErrorTest.java | 184 +-
.../CacheGetFutureHangsSelfTest.java | 6 +
.../GridCacheAbstractNodeRestartSelfTest.java | 2 +
.../IgniteCacheSingleGetMessageTest.java | 357 +++
.../GridCacheReplicatedMetricsSelfTest.java | 9 -
...ContinuousQueryFailoverAbstractSelfTest.java | 2235 ++++++++++++++++++
...ryFailoverAtomicNearEnabledSelfSelfTest.java | 46 +
...FailoverAtomicPrimaryWriteOrderSelfTest.java | 44 +
...usQueryFailoverAtomicReplicatedSelfTest.java | 40 +
...inuousQueryFailoverTxReplicatedSelfTest.java | 32 +
.../CacheContinuousQueryFailoverTxSelfTest.java | 39 +
...ridCacheContinuousQueryAbstractSelfTest.java | 153 +-
.../GridCacheContinuousQueryTxSelfTest.java | 49 +
...CacheContinuousQueryClientReconnectTest.java | 187 ++
.../IgniteCacheContinuousQueryClientTest.java | 157 +-
...cheContinuousQueryClientTxReconnectTest.java | 32 +
.../p2p/GridP2PSameClassLoaderSelfTest.java | 16 +-
.../testframework/junits/GridAbstractTest.java | 2 +-
.../junits/common/GridCommonAbstractTest.java | 3 +
.../testsuites/IgniteCacheTestSuite4.java | 3 +
modules/flume/README.md | 40 -
modules/flume/README.txt | 72 +
modules/flume/licenses/apache-2.0.txt | 202 ++
.../IgniteCacheQuerySelfTestSuite.java | 16 +-
modules/twitter/README.txt | 32 +
modules/twitter/licenses/apache-2.0.txt | 202 ++
modules/twitter/pom.xml | 122 +
.../ignite/stream/twitter/OAuthSettings.java | 86 +
.../ignite/stream/twitter/TwitterStreamer.java | 295 +++
.../twitter/IgniteTwitterStreamerTest.java | 234 ++
.../twitter/IgniteTwitterStreamerTestSuite.java | 32 +
.../stream/twitter/TwitterStreamerImpl.java | 79 +
.../config/benchmark-multicast.properties | 6 +-
.../benchmark-query-put-separated.properties | 87 +
.../yardstick/cache/CacheEntryEventProbe.java | 156 ++
.../IgniteSqlQueryPutSeparatedBenchmark.java | 84 +
pom.xml | 1 +
129 files changed, 10440 insertions(+), 996 deletions(-)
----------------------------------------------------------------------
[02/23] ignite git commit: IGNITE-529 License fix
Posted by sb...@apache.org.
IGNITE-529 License fix
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/fee7f86e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/fee7f86e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/fee7f86e
Branch: refs/heads/ignite-sql-opt
Commit: fee7f86e2a27c5958ac873bdaece3ef2d97de947
Parents: 33ec73f
Author: Anton Vinogradov <av...@apache.org>
Authored: Thu Nov 19 14:29:40 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Thu Nov 19 14:29:40 2015 +0300
----------------------------------------------------------------------
modules/flume/licenses/apache-2.0.txt | 202 +++++++++++++++++++++++++++++
1 file changed, 202 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/fee7f86e/modules/flume/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/flume/licenses/apache-2.0.txt b/modules/flume/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/flume/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
[20/23] ignite git commit: IGNITE-426 Implemented failover for
Continuous query.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
index 1219f2f..72a60d2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
@@ -78,6 +78,11 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
@GridDirectCollection(CacheObject.class)
private List<CacheObject> vals;
+ /** Previous values. */
+ @GridToStringInclude
+ @GridDirectCollection(CacheObject.class)
+ private List<CacheObject> prevVals;
+
/** Conflict versions. */
@GridDirectCollection(GridCacheVersion.class)
private List<GridCacheVersion> conflictVers;
@@ -139,10 +144,19 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
/** Task name hash. */
private int taskNameHash;
+ /** Partition. */
+ private GridLongList updateCntrs;
+
/** On response flag. Access should be synced on future. */
@GridDirectTransient
private boolean onRes;
+ @GridDirectTransient
+ private List<Integer> partIds;
+
+ @GridDirectTransient
+ private List<CacheObject> localPrevVals;
+
/**
* Empty constructor required by {@link Externalizable}.
*/
@@ -193,6 +207,8 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
this.addDepInfo = addDepInfo;
keys = new ArrayList<>();
+ partIds = new ArrayList<>();
+ localPrevVals = new ArrayList<>();
if (forceTransformBackups) {
entryProcessors = new ArrayList<>();
@@ -216,15 +232,25 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
* @param ttl TTL (optional).
* @param conflictExpireTime Conflict expire time (optional).
* @param conflictVer Conflict version (optional).
+ * @param addPrevVal If {@code true} adds previous value.
+ * @param prevVal Previous value.
*/
public void addWriteValue(KeyCacheObject key,
@Nullable CacheObject val,
EntryProcessor<Object, Object, Object> entryProcessor,
long ttl,
long conflictExpireTime,
- @Nullable GridCacheVersion conflictVer) {
+ @Nullable GridCacheVersion conflictVer,
+ boolean addPrevVal,
+ int partId,
+ @Nullable CacheObject prevVal,
+ @Nullable Long updateIdx) {
keys.add(key);
+ partIds.add(partId);
+
+ localPrevVals.add(prevVal);
+
if (forceTransformBackups) {
assert entryProcessor != null;
@@ -233,6 +259,20 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
else
vals.add(val);
+ if (addPrevVal) {
+ if (prevVals == null)
+ prevVals = new ArrayList<>();
+
+ prevVals.add(prevVal);
+ }
+
+ if (updateIdx != null) {
+ if (updateCntrs == null)
+ updateCntrs = new GridLongList();
+
+ updateCntrs.add(updateIdx);
+ }
+
// In case there is no conflict, do not create the list.
if (conflictVer != null) {
if (conflictVers == null) {
@@ -283,8 +323,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
@Nullable CacheObject val,
EntryProcessor<Object, Object, Object> entryProcessor,
long ttl,
- long expireTime)
- {
+ long expireTime) {
if (nearKeys == null) {
nearKeys = new ArrayList<>();
@@ -415,6 +454,25 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
}
/**
+ * @param idx Partition index.
+ * @return Partition id.
+ */
+ public int partitionId(int idx) {
+ return partIds.get(idx);
+ }
+
+ /**
+ * @param updCntr Update counter.
+ * @return Update counter.
+ */
+ public Long updateCounter(int updCntr) {
+ if (updateCntrs != null && updCntr < updateCntrs.size())
+ return updateCntrs.get(updCntr);
+
+ return null;
+ }
+
+ /**
* @param idx Near key index.
* @return Key.
*/
@@ -435,6 +493,25 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
/**
* @param idx Key index.
+ * @return Value.
+ */
+ @Nullable public CacheObject previousValue(int idx) {
+ if (prevVals != null)
+ return prevVals.get(idx);
+
+ return null;
+ }
+
+ /**
+ * @param idx Key index.
+ * @return Value.
+ */
+ @Nullable public CacheObject localPreviousValue(int idx) {
+ return localPrevVals.get(idx);
+ }
+
+ /**
+ * @param idx Key index.
* @return Entry processor.
*/
@Nullable public EntryProcessor<Object, Object, Object> entryProcessor(int idx) {
@@ -544,8 +621,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
return invokeArgs;
}
- /** {@inheritDoc}
- * @param ctx*/
+ /** {@inheritDoc} */
@Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
super.prepareMarshal(ctx);
@@ -695,42 +771,54 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
writer.incrementState();
case 16:
- if (!writer.writeUuid("subjId", subjId))
+ if (!writer.writeCollection("prevVals", prevVals, MessageCollectionItemType.MSG))
return false;
writer.incrementState();
case 17:
- if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1))
+ if (!writer.writeUuid("subjId", subjId))
return false;
writer.incrementState();
case 18:
- if (!writer.writeInt("taskNameHash", taskNameHash))
+ if (!writer.writeByte("syncMode", syncMode != null ? (byte)syncMode.ordinal() : -1))
return false;
writer.incrementState();
case 19:
- if (!writer.writeMessage("topVer", topVer))
+ if (!writer.writeInt("taskNameHash", taskNameHash))
return false;
writer.incrementState();
case 20:
- if (!writer.writeMessage("ttls", ttls))
+ if (!writer.writeMessage("topVer", topVer))
return false;
writer.incrementState();
case 21:
- if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG))
+ if (!writer.writeMessage("ttls", ttls))
return false;
writer.incrementState();
case 22:
+ if (!writer.writeMessage("updateCntrs", updateCntrs))
+ return false;
+
+ writer.incrementState();
+
+ case 23:
+ if (!writer.writeCollection("vals", vals, MessageCollectionItemType.MSG))
+ return false;
+
+ writer.incrementState();
+
+ case 24:
if (!writer.writeMessage("writeVer", writeVer))
return false;
@@ -857,7 +945,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
reader.incrementState();
case 16:
- subjId = reader.readUuid("subjId");
+ prevVals = reader.readCollection("prevVals", MessageCollectionItemType.MSG);
if (!reader.isLastRead())
return false;
@@ -865,6 +953,14 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
reader.incrementState();
case 17:
+ subjId = reader.readUuid("subjId");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 18:
byte syncModeOrd;
syncModeOrd = reader.readByte("syncMode");
@@ -876,7 +972,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
reader.incrementState();
- case 18:
+ case 19:
taskNameHash = reader.readInt("taskNameHash");
if (!reader.isLastRead())
@@ -884,7 +980,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
reader.incrementState();
- case 19:
+ case 20:
topVer = reader.readMessage("topVer");
if (!reader.isLastRead())
@@ -892,7 +988,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
reader.incrementState();
- case 20:
+ case 21:
ttls = reader.readMessage("ttls");
if (!reader.isLastRead())
@@ -900,7 +996,15 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
reader.incrementState();
- case 21:
+ case 22:
+ updateCntrs = reader.readMessage("updateCntrs");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 23:
vals = reader.readCollection("vals", MessageCollectionItemType.MSG);
if (!reader.isLastRead())
@@ -908,7 +1012,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
reader.incrementState();
- case 22:
+ case 24:
writeVer = reader.readMessage("writeVer");
if (!reader.isLastRead())
@@ -928,7 +1032,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 23;
+ return 25;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 2f2944d..43f34c9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -613,7 +613,9 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
if (updateTop) {
for (GridClientPartitionTopology top : cctx.exchange().clientTopologies()) {
if (top.cacheId() == cacheCtx.cacheId()) {
- cacheCtx.topology().update(exchId, top.partitionMap(true));
+ cacheCtx.topology().update(exchId,
+ top.partitionMap(true),
+ top.updateCounters());
break;
}
@@ -813,6 +815,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
}
}
+ boolean topChanged = discoEvt.type() != EVT_DISCOVERY_CUSTOM_EVT;
+
for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
if (cacheCtx.isLocal())
continue;
@@ -823,6 +827,9 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
if (drCacheCtx.isDrEnabled())
drCacheCtx.dr().beforeExchange(topVer, exchId.isLeft());
+ if (topChanged)
+ cacheCtx.continuousQueries().beforeExchange(exchId.topologyVersion());
+
// Partition release future is done so we can flush the write-behind store.
cacheCtx.store().forceFlush();
@@ -956,14 +963,18 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
* @param id ID.
* @throws IgniteCheckedException If failed.
*/
- private void sendLocalPartitions(ClusterNode node, @Nullable GridDhtPartitionExchangeId id) throws IgniteCheckedException {
+ private void sendLocalPartitions(ClusterNode node, @Nullable GridDhtPartitionExchangeId id)
+ throws IgniteCheckedException {
GridDhtPartitionsSingleMessage m = new GridDhtPartitionsSingleMessage(id,
clientOnlyExchange,
cctx.versions().last());
for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
- if (!cacheCtx.isLocal())
+ if (!cacheCtx.isLocal()) {
m.addLocalPartitionMap(cacheCtx.cacheId(), cacheCtx.topology().localPartitionMap());
+
+ m.partitionUpdateCounters(cacheCtx.cacheId(), cacheCtx.topology().updateCounters());
+ }
}
if (log.isDebugEnabled())
@@ -989,15 +1000,21 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
boolean ready = startTopVer == null || startTopVer.compareTo(id.topologyVersion()) <= 0;
- if (ready)
+ if (ready) {
m.addFullPartitionsMap(cacheCtx.cacheId(), cacheCtx.topology().partitionMap(true));
+
+ m.addPartitionUpdateCounters(cacheCtx.cacheId(), cacheCtx.topology().updateCounters());
+ }
}
}
// It is important that client topologies be added after contexts.
- for (GridClientPartitionTopology top : cctx.exchange().clientTopologies())
+ for (GridClientPartitionTopology top : cctx.exchange().clientTopologies()) {
m.addFullPartitionsMap(top.cacheId(), top.partitionMap(true));
+ m.addPartitionUpdateCounters(top.cacheId(), top.updateCounters());
+ }
+
if (log.isDebugEnabled())
log.debug("Sending full partition map [nodeIds=" + F.viewReadOnly(nodes, F.node2id()) +
", exchId=" + exchId + ", msg=" + m + ']');
@@ -1334,15 +1351,17 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
for (Map.Entry<Integer, GridDhtPartitionFullMap> entry : msg.partitions().entrySet()) {
Integer cacheId = entry.getKey();
+ Map<Integer, Long> cntrMap = msg.partitionUpdateCounters(cacheId);
+
GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
if (cacheCtx != null)
- cacheCtx.topology().update(exchId, entry.getValue());
+ cacheCtx.topology().update(exchId, entry.getValue(), cntrMap);
else {
ClusterNode oldest = CU.oldestAliveCacheServerNode(cctx, AffinityTopologyVersion.NONE);
if (oldest != null && oldest.isLocal())
- cctx.exchange().clientTopology(cacheId, this).update(exchId, entry.getValue());
+ cctx.exchange().clientTopology(cacheId, this).update(exchId, entry.getValue(), cntrMap);
}
}
}
@@ -1360,7 +1379,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
GridDhtPartitionTopology top = cacheCtx != null ? cacheCtx.topology() :
cctx.exchange().clientTopology(cacheId, this);
- top.update(exchId, entry.getValue());
+ top.update(exchId, entry.getValue(), msg.partitionUpdateCounters(cacheId));
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
index c06d773..3f4f9bc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.preloader;
import java.io.Externalizable;
import java.nio.ByteBuffer;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.ignite.IgniteCheckedException;
@@ -48,6 +49,14 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
/** */
private byte[] partsBytes;
+ /** Partitions update counters. */
+ @GridToStringInclude
+ @GridDirectTransient
+ private Map<Integer, Map<Integer, Long>> partCntrs;
+
+ /** Serialized partitions counters. */
+ private byte[] partCntrsBytes;
+
/** Topology version. */
private AffinityTopologyVersion topVer;
@@ -92,13 +101,41 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
parts.put(cacheId, fullMap);
}
- /** {@inheritDoc}
- * @param ctx*/
+ /**
+ * @param cacheId Cache ID.
+ * @param cntrMap Partition update counters.
+ */
+ public void addPartitionUpdateCounters(int cacheId, Map<Integer, Long> cntrMap) {
+ if (partCntrs == null)
+ partCntrs = new HashMap<>();
+
+ if (!partCntrs.containsKey(cacheId))
+ partCntrs.put(cacheId, cntrMap);
+ }
+
+ /**
+ * @param cacheId Cache ID.
+ * @return Partition update counters.
+ */
+ public Map<Integer, Long> partitionUpdateCounters(int cacheId) {
+ if (partCntrs != null) {
+ Map<Integer, Long> res = partCntrs.get(cacheId);
+
+ return res != null ? res : Collections.<Integer, Long>emptyMap();
+ }
+
+ return Collections.emptyMap();
+ }
+
+ /** {@inheritDoc} */
@Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
super.prepareMarshal(ctx);
if (parts != null && partsBytes == null)
partsBytes = ctx.marshaller().marshal(parts);
+
+ if (partCntrs != null)
+ partCntrsBytes = ctx.marshaller().marshal(partCntrs);
}
/**
@@ -121,6 +158,9 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
if (partsBytes != null && parts == null)
parts = ctx.marshaller().unmarshal(partsBytes, ldr);
+
+ if (partCntrsBytes != null)
+ partCntrs = ctx.marshaller().unmarshal(partCntrsBytes, ldr);
}
/** {@inheritDoc} */
@@ -139,12 +179,18 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
switch (writer.state()) {
case 5:
- if (!writer.writeByteArray("partsBytes", partsBytes))
+ if (!writer.writeByteArray("partCntrsBytes", partCntrsBytes))
return false;
writer.incrementState();
case 6:
+ if (!writer.writeByteArray("partsBytes", partsBytes))
+ return false;
+
+ writer.incrementState();
+
+ case 7:
if (!writer.writeMessage("topVer", topVer))
return false;
@@ -167,7 +213,7 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
switch (reader.state()) {
case 5:
- partsBytes = reader.readByteArray("partsBytes");
+ partCntrsBytes = reader.readByteArray("partCntrsBytes");
if (!reader.isLastRead())
return false;
@@ -175,6 +221,14 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
reader.incrementState();
case 6:
+ partsBytes = reader.readByteArray("partsBytes");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 7:
topVer = reader.readMessage("topVer");
if (!reader.isLastRead())
@@ -194,7 +248,7 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 7;
+ return 8;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
index 83fbb1a..a2366bf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.distributed.dht.preloader;
import java.io.Externalizable;
import java.nio.ByteBuffer;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.ignite.IgniteCheckedException;
@@ -46,6 +47,14 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
/** Serialized partitions. */
private byte[] partsBytes;
+ /** Partitions update counters. */
+ @GridToStringInclude
+ @GridDirectTransient
+ private Map<Integer, Map<Integer, Long>> partCntrs;
+
+ /** Serialized partitions counters. */
+ private byte[] partCntrsBytes;
+
/** */
private boolean client;
@@ -90,6 +99,31 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
}
/**
+ * @param cacheId Cache ID.
+ * @param cntrMap Partition update counters.
+ */
+ public void partitionUpdateCounters(int cacheId, Map<Integer, Long> cntrMap) {
+ if (partCntrs == null)
+ partCntrs = new HashMap<>();
+
+ partCntrs.put(cacheId, cntrMap);
+ }
+
+ /**
+ * @param cacheId Cache ID.
+ * @return Partition update counters.
+ */
+ public Map<Integer, Long> partitionUpdateCounters(int cacheId) {
+ if (partCntrs != null) {
+ Map<Integer, Long> res = partCntrs.get(cacheId);
+
+ return res != null ? res : Collections.<Integer, Long>emptyMap();
+ }
+
+ return Collections.emptyMap();
+ }
+
+ /**
* @return Local partitions.
*/
public Map<Integer, GridDhtPartitionMap> partitions() {
@@ -103,6 +137,9 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
if (partsBytes == null && parts != null)
partsBytes = ctx.marshaller().marshal(parts);
+
+ if (partCntrs != null)
+ partCntrsBytes = ctx.marshaller().marshal(partCntrs);
}
/** {@inheritDoc} */
@@ -111,6 +148,9 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
if (partsBytes != null && parts == null)
parts = ctx.marshaller().unmarshal(partsBytes, ldr);
+
+ if (partCntrsBytes != null)
+ partCntrs = ctx.marshaller().unmarshal(partCntrsBytes, ldr);
}
/** {@inheritDoc} */
@@ -135,6 +175,12 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
writer.incrementState();
case 6:
+ if (!writer.writeByteArray("partCntrsBytes", partCntrsBytes))
+ return false;
+
+ writer.incrementState();
+
+ case 7:
if (!writer.writeByteArray("partsBytes", partsBytes))
return false;
@@ -165,6 +211,14 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
reader.incrementState();
case 6:
+ partCntrsBytes = reader.readByteArray("partCntrsBytes");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 7:
partsBytes = reader.readByteArray("partsBytes");
if (!reader.isLastRead())
@@ -184,7 +238,7 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 7;
+ return 8;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 1bf03a9..706655b 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
@@ -249,7 +249,7 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> {
/*write-through*/false,
/*read-through*/false,
/*retval*/false,
- /**expiry policy*/null,
+ /*expiry policy*/null,
/*event*/true,
/*metrics*/true,
/*primary*/false,
@@ -263,7 +263,9 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> {
false,
false,
subjId,
- taskName);
+ taskName,
+ null,
+ null);
if (updRes.removeVersion() != null)
ctx.onDeferredDelete(entry, updRes.removeVersion());
@@ -361,7 +363,9 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> {
false,
intercept,
req.subjectId(),
- taskName);
+ taskName,
+ null,
+ null);
if (updRes.removeVersion() != null)
ctx.onDeferredDelete(entry, updRes.removeVersion());
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
index d078df4..ba58f57 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
@@ -226,6 +226,13 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
}
/**
+ * @param cntrs Partition indexes.
+ */
+ @Override public void setPartitionUpdateCounters(long[] cntrs) {
+ // No-op.
+ }
+
+ /**
* Adds owned versions to map.
*
* @param vers Map of owned versions.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryBatchAck.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryBatchAck.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryBatchAck.java
new file mode 100644
index 0000000..7db9026
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryBatchAck.java
@@ -0,0 +1,163 @@
+/*
+ * 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.query.continuous;
+
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.internal.GridDirectMap;
+import org.apache.ignite.internal.processors.cache.GridCacheMessage;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+
+/**
+ * Batch acknowledgement.
+ */
+public class CacheContinuousQueryBatchAck extends GridCacheMessage {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Routine ID. */
+ private UUID routineId;
+
+ /** Update counters. */
+ @GridToStringInclude
+ @GridDirectMap(keyType = Integer.class, valueType = Long.class)
+ private Map<Integer, Long> updateCntrs;
+
+ /**
+ * Default constructor.
+ */
+ public CacheContinuousQueryBatchAck() {
+ // No-op.
+ }
+
+ /**
+ * @param cacheId Cache ID.
+ * @param routineId Routine ID.
+ * @param updateCntrs Update counters.
+ */
+ CacheContinuousQueryBatchAck(int cacheId, UUID routineId, Map<Integer, Long> updateCntrs) {
+ this.cacheId = cacheId;
+ this.routineId = routineId;
+ this.updateCntrs = updateCntrs;
+ }
+
+ /**
+ * @return Routine ID.
+ */
+ UUID routineId() {
+ return routineId;
+ }
+
+ /**
+ * @return Update counters.
+ */
+ Map<Integer, Long> updateCntrs() {
+ return updateCntrs;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
+ writer.setBuffer(buf);
+
+ if (!super.writeTo(buf, writer))
+ return false;
+
+ if (!writer.isHeaderWritten()) {
+ if (!writer.writeHeader(directType(), fieldsCount()))
+ return false;
+
+ writer.onHeaderWritten();
+ }
+
+ switch (writer.state()) {
+ case 3:
+ if (!writer.writeUuid("routineId", routineId))
+ return false;
+
+ writer.incrementState();
+
+ case 4:
+ if (!writer.writeMap("updateCntrs", updateCntrs, MessageCollectionItemType.INT,
+ MessageCollectionItemType.LONG))
+ return false;
+
+ writer.incrementState();
+
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
+ reader.setBuffer(buf);
+
+ if (!reader.beforeMessageRead())
+ return false;
+
+ if (!super.readFrom(buf, reader))
+ return false;
+
+ switch (reader.state()) {
+ case 3:
+ routineId = reader.readUuid("routineId");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 4:
+ updateCntrs = reader.readMap("updateCntrs", MessageCollectionItemType.INT,
+ MessageCollectionItemType.LONG, false);
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ }
+
+ return reader.afterMessageRead(CacheContinuousQueryBatchAck.class);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean addDeploymentInfo() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte directType() {
+ return 118;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte fieldsCount() {
+ return 5;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(CacheContinuousQueryBatchAck.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java
index a4b35eb..0495e6d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEntry.java
@@ -22,10 +22,12 @@ import javax.cache.event.EventType;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridDirectTransient;
import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -42,6 +44,12 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
private static final long serialVersionUID = 0L;
/** */
+ private static final byte BACKUP_ENTRY = 0b0001;
+
+ /** */
+ private static final byte FILTERED_ENTRY = 0b0010;
+
+ /** */
private static final EventType[] EVT_TYPE_VALS = EventType.values();
/**
@@ -75,8 +83,24 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
@GridDirectTransient
private GridDeploymentInfo depInfo;
+ /** Partition. */
+ private int part;
+
+ /** Update counter. */
+ private long updateCntr;
+
+ /** Flags. */
+ private byte flags;
+
+ /** */
+ @GridToStringInclude
+ private AffinityTopologyVersion topVer;
+
+ /** Filtered events. */
+ private GridLongList filteredEvts;
+
/**
- * Required by {@link org.apache.ignite.plugin.extensions.communication.Message}.
+ * Required by {@link Message}.
*/
public CacheContinuousQueryEntry() {
// No-op.
@@ -88,18 +112,34 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
* @param key Key.
* @param newVal New value.
* @param oldVal Old value.
+ * @param part Partition.
+ * @param updateCntr Update partition counter.
+ * @param topVer Topology version if applicable.
*/
CacheContinuousQueryEntry(
int cacheId,
EventType evtType,
KeyCacheObject key,
@Nullable CacheObject newVal,
- @Nullable CacheObject oldVal) {
+ @Nullable CacheObject oldVal,
+ int part,
+ long updateCntr,
+ @Nullable AffinityTopologyVersion topVer) {
this.cacheId = cacheId;
this.evtType = evtType;
this.key = key;
this.newVal = newVal;
this.oldVal = oldVal;
+ this.part = part;
+ this.updateCntr = updateCntr;
+ this.topVer = topVer;
+ }
+
+ /**
+ * @return Topology version if applicable.
+ */
+ @Nullable AffinityTopologyVersion topologyVersion() {
+ return topVer;
}
/**
@@ -117,6 +157,66 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
}
/**
+ * @return Partition.
+ */
+ int partition() {
+ return part;
+ }
+
+ /**
+ * @return Update counter.
+ */
+ long updateCounter() {
+ return updateCntr;
+ }
+
+ /**
+ * Mark that entry create on backup.
+ */
+ void markBackup() {
+ flags |= BACKUP_ENTRY;
+ }
+
+ /**
+ * Mark that entry filtered.
+ */
+ void markFiltered() {
+ flags |= FILTERED_ENTRY;
+ newVal = null;
+ oldVal = null;
+ key = null;
+ depInfo = null;
+ }
+
+ /**
+ * @return {@code True} if entry sent by backup node.
+ */
+ boolean isBackup() {
+ return (flags & BACKUP_ENTRY) != 0;
+ }
+
+ /**
+ * @return {@code True} if entry was filtered.
+ */
+ boolean isFiltered() {
+ return (flags & FILTERED_ENTRY) != 0;
+ }
+
+ /**
+ * @param cntrs Filtered events.
+ */
+ void filteredEvents(GridLongList cntrs) {
+ filteredEvts = cntrs;
+ }
+
+ /**
+ * @return previous filtered events.
+ */
+ long[] filteredEvents() {
+ return filteredEvts == null ? null : filteredEvts.array();
+ }
+
+ /**
* @param cctx Cache context.
* @throws IgniteCheckedException In case of error.
*/
@@ -138,13 +238,15 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
* @throws IgniteCheckedException In case of error.
*/
void unmarshal(GridCacheContext cctx, @Nullable ClassLoader ldr) throws IgniteCheckedException {
- key.finishUnmarshal(cctx.cacheObjectContext(), ldr);
+ if (!isFiltered()) {
+ key.finishUnmarshal(cctx.cacheObjectContext(), ldr);
- if (newVal != null)
- newVal.finishUnmarshal(cctx.cacheObjectContext(), ldr);
+ if (newVal != null)
+ newVal.finishUnmarshal(cctx.cacheObjectContext(), ldr);
- if (oldVal != null)
- oldVal.finishUnmarshal(cctx.cacheObjectContext(), ldr);
+ if (oldVal != null)
+ oldVal.finishUnmarshal(cctx.cacheObjectContext(), ldr);
+ }
}
/**
@@ -208,23 +310,53 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
writer.incrementState();
case 2:
- if (!writer.writeMessage("key", key))
+ if (!writer.writeMessage("filteredEvts", filteredEvts))
return false;
writer.incrementState();
case 3:
- if (!writer.writeMessage("newVal", newVal))
+ if (!writer.writeByte("flags", flags))
return false;
writer.incrementState();
case 4:
+ if (!writer.writeMessage("key", key))
+ return false;
+
+ writer.incrementState();
+
+ case 5:
+ if (!writer.writeMessage("newVal", newVal))
+ return false;
+
+ writer.incrementState();
+
+ case 6:
if (!writer.writeMessage("oldVal", oldVal))
return false;
writer.incrementState();
+ case 7:
+ if (!writer.writeInt("part", part))
+ return false;
+
+ writer.incrementState();
+
+ case 8:
+ if (!writer.writeMessage("topVer", topVer))
+ return false;
+
+ writer.incrementState();
+
+ case 9:
+ if (!writer.writeLong("updateCntr", updateCntr))
+ return false;
+
+ writer.incrementState();
+
}
return true;
@@ -259,7 +391,7 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
reader.incrementState();
case 2:
- key = reader.readMessage("key");
+ filteredEvts = reader.readMessage("filteredEvts");
if (!reader.isLastRead())
return false;
@@ -267,7 +399,7 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
reader.incrementState();
case 3:
- newVal = reader.readMessage("newVal");
+ flags = reader.readByte("flags");
if (!reader.isLastRead())
return false;
@@ -275,6 +407,22 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
reader.incrementState();
case 4:
+ key = reader.readMessage("key");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 5:
+ newVal = reader.readMessage("newVal");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 6:
oldVal = reader.readMessage("oldVal");
if (!reader.isLastRead())
@@ -282,6 +430,30 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
reader.incrementState();
+ case 7:
+ part = reader.readInt("part");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 8:
+ topVer = reader.readMessage("topVer");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 9:
+ updateCntr = reader.readLong("updateCntr");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
}
return reader.afterMessageRead(CacheContinuousQueryEntry.class);
@@ -289,7 +461,7 @@ public class CacheContinuousQueryEntry implements GridCacheDeployable, Message {
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 5;
+ return 10;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEvent.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEvent.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEvent.java
index 7417138..a1ebe39 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEvent.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEvent.java
@@ -58,8 +58,7 @@ class CacheContinuousQueryEvent<K, V> extends CacheEntryEvent<K, V> {
}
/** {@inheritDoc} */
- @Override
- public K getKey() {
+ @Override public K getKey() {
return e.key().value(cctx.cacheObjectContext(), false);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
index e517c70..b69d4cd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
@@ -21,8 +21,21 @@ import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.TreeMap;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
import javax.cache.event.CacheEntryEvent;
import javax.cache.event.CacheEntryUpdatedListener;
import javax.cache.event.EventType;
@@ -30,26 +43,37 @@ import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cache.CacheEntryEventSerializableFilter;
+import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.events.CacheQueryExecutedEvent;
import org.apache.ignite.events.CacheQueryReadEvent;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteDeploymentCheckedException;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.managers.communication.GridIoPolicy;
import org.apache.ignite.internal.managers.deployment.GridDeployment;
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.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheDeploymentManager;
import org.apache.ignite.internal.processors.cache.query.CacheQueryType;
+import org.apache.ignite.internal.processors.continuous.GridContinuousBatch;
+import org.apache.ignite.internal.processors.continuous.GridContinuousBatchAdapter;
import org.apache.ignite.internal.processors.continuous.GridContinuousHandler;
import org.apache.ignite.internal.processors.platform.cache.query.PlatformContinuousQueryFilter;
+import org.apache.ignite.internal.util.GridConcurrentSkipListSet;
+import org.apache.ignite.internal.util.GridLongList;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.F;
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.IgnitePredicate;
import org.jetbrains.annotations.Nullable;
+import org.jsr166.ConcurrentLinkedDeque8;
import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_EXECUTED;
import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_OBJECT_READ;
@@ -61,6 +85,9 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
/** */
private static final long serialVersionUID = 0L;
+ /** */
+ private static final int BACKUP_ACK_THRESHOLD = 100;
+
/** Cache name. */
private String cacheName;
@@ -97,9 +124,27 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
/** Whether to skip primary check for REPLICATED cache. */
private transient boolean skipPrimaryCheck;
+ /** Backup queue. */
+ private transient Collection<CacheContinuousQueryEntry> backupQueue;
+
+ /** */
+ private boolean localCache;
+
+ /** */
+ private transient ConcurrentMap<Integer, PartitionRecovery> rcvs;
+
+ /** */
+ private transient ConcurrentMap<Integer, EntryBuffer> entryBufs;
+
+ /** */
+ private transient AcknowledgeBuffer ackBuf;
+
/** */
private transient int cacheId;
+ /** */
+ private Map<Integer, Long> initUpdCntrs;
+
/**
* Required by {@link Externalizable}.
*/
@@ -121,6 +166,7 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
* @param ignoreExpired Ignore expired events flag.
* @param skipPrimaryCheck Whether to skip primary check for REPLICATED cache.
* @param taskHash Task name hash code.
+ * @param locCache {@code True} if local cache.
*/
public CacheContinuousQueryHandler(
String cacheName,
@@ -133,7 +179,8 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
boolean sync,
boolean ignoreExpired,
int taskHash,
- boolean skipPrimaryCheck) {
+ boolean skipPrimaryCheck,
+ boolean locCache) {
assert topic != null;
assert locLsnr != null;
@@ -148,6 +195,7 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
this.ignoreExpired = ignoreExpired;
this.taskHash = taskHash;
this.skipPrimaryCheck = skipPrimaryCheck;
+ this.localCache = locCache;
cacheId = CU.cacheId(cacheName);
}
@@ -173,6 +221,11 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
}
/** {@inheritDoc} */
+ @Override public void updateCounters(Map<Integer, Long> cntrs) {
+ this.initUpdCntrs = cntrs;
+ }
+
+ /** {@inheritDoc} */
@Override public RegisterStatus register(final UUID nodeId, final UUID routineId, final GridKernalContext ctx)
throws IgniteCheckedException {
assert nodeId != null;
@@ -185,8 +238,32 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
if (rmtFilter != null)
ctx.resource().injectGeneric(rmtFilter);
+ entryBufs = new ConcurrentHashMap<>();
+
+ backupQueue = new ConcurrentLinkedDeque8<>();
+
+ ackBuf = new AcknowledgeBuffer();
+
+ rcvs = new ConcurrentHashMap<>();
+
final boolean loc = nodeId.equals(ctx.localNodeId());
+ assert !skipPrimaryCheck || loc;
+
+ final GridCacheContext<K, V> cctx = cacheContext(ctx);
+
+ if (!internal && cctx != null && initUpdCntrs != null) {
+ Map<Integer, Long> map = cctx.topology().updateCounters();
+
+ for (Map.Entry<Integer, Long> e : map.entrySet()) {
+ Long cntr0 = initUpdCntrs.get(e.getKey());
+ Long cntr1 = e.getValue();
+
+ if (cntr0 == null || cntr1 > cntr0)
+ initUpdCntrs.put(e.getKey(), cntr1);
+ }
+ }
+
CacheContinuousQueryListener<K, V> lsnr = new CacheContinuousQueryListener<K, V>() {
@Override public void onExecution() {
if (ctx.event().isRecordable(EVT_CACHE_QUERY_EXECUTED)) {
@@ -212,11 +289,15 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
if (ignoreExpired && evt.getEventType() == EventType.EXPIRED)
return;
- GridCacheContext<K, V> cctx = cacheContext(ctx);
+ final GridCacheContext<K, V> cctx = cacheContext(ctx);
- if (cctx.isReplicated() && !skipPrimaryCheck && !primary)
+ // Check that cache stopped.
+ if (cctx == null)
return;
+ // skipPrimaryCheck is set only when listen locally for replicated cache events.
+ assert !skipPrimaryCheck || (cctx.isReplicated() && ctx.localNodeId().equals(nodeId));
+
boolean notify = true;
if (rmtFilter != null) {
@@ -228,54 +309,94 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
}
}
- if (notify) {
- if (loc)
- locLsnr.onUpdated(F.<CacheEntryEvent<? extends K, ? extends V>>asList(evt));
- else {
- try {
- if (cctx.deploymentEnabled() && ctx.discovery().node(nodeId) != null) {
- evt.entry().prepareMarshal(cctx);
-
- cctx.deploy().prepare(evt.entry());
+ try {
+ final CacheContinuousQueryEntry entry = evt.entry();
+
+ if (!notify)
+ entry.markFiltered();
+
+ if (primary || skipPrimaryCheck) {
+ if (loc) {
+ if (!localCache) {
+ Collection<CacheContinuousQueryEntry> entries = handleEvent(ctx, entry);
+
+ if (!entries.isEmpty()) {
+ final IgniteCache cache = cctx.kernalContext().cache().jcache(cctx.name());
+
+ Iterable<CacheEntryEvent<? extends K, ? extends V>> evts = F.viewReadOnly(entries,
+ new C1<CacheContinuousQueryEntry, CacheEntryEvent<? extends K, ? extends V>>() {
+ @Override public CacheEntryEvent<? extends K, ? extends V> apply(
+ CacheContinuousQueryEntry e) {
+ return new CacheContinuousQueryEvent<>(cache, cctx, e);
+ }
+ },
+ new IgnitePredicate<CacheContinuousQueryEntry>() {
+ @Override public boolean apply(CacheContinuousQueryEntry entry) {
+ return !entry.isFiltered();
+ }
+ }
+ );
+
+ locLsnr.onUpdated(evts);
+
+ if (!internal && !skipPrimaryCheck)
+ sendBackupAcknowledge(ackBuf.onAcknowledged(entry), routineId, ctx);
+ }
+ }
+ else {
+ if (!entry.isFiltered())
+ locLsnr.onUpdated(F.<CacheEntryEvent<? extends K, ? extends V>>asList(evt));
}
- else
- evt.entry().prepareMarshal(cctx);
-
- ctx.continuous().addNotification(nodeId, routineId, evt.entry(), topic, sync, true);
}
- catch (ClusterTopologyCheckedException ex) {
- IgniteLogger log = ctx.log(getClass());
+ else {
+ if (!entry.isFiltered())
+ prepareEntry(cctx, nodeId, entry);
- if (log.isDebugEnabled())
- log.debug("Failed to send event notification to node, node left cluster " +
- "[node=" + nodeId + ", err=" + ex + ']');
- }
- catch (IgniteCheckedException ex) {
- U.error(ctx.log(getClass()), "Failed to send event notification to node: " + nodeId, ex);
+ CacheContinuousQueryEntry e = handleEntry(entry);
+
+ if (e != null)
+ ctx.continuous().addNotification(nodeId, routineId, entry, topic, sync, true);
}
}
+ else {
+ if (!internal) {
+ entry.markBackup();
- if (recordIgniteEvt) {
- ctx.event().record(new CacheQueryReadEvent<>(
- ctx.discovery().localNode(),
- "Continuous query executed.",
- EVT_CACHE_QUERY_OBJECT_READ,
- CacheQueryType.CONTINUOUS.name(),
- cacheName,
- null,
- null,
- null,
- rmtFilter,
- null,
- nodeId,
- taskName(),
- evt.getKey(),
- evt.getValue(),
- evt.getOldValue(),
- null
- ));
+ backupQueue.add(entry);
+ }
}
}
+ catch (ClusterTopologyCheckedException ex) {
+ IgniteLogger log = ctx.log(getClass());
+
+ if (log.isDebugEnabled())
+ log.debug("Failed to send event notification to node, node left cluster " +
+ "[node=" + nodeId + ", err=" + ex + ']');
+ }
+ catch (IgniteCheckedException ex) {
+ U.error(ctx.log(getClass()), "Failed to send event notification to node: " + nodeId, ex);
+ }
+
+ if (recordIgniteEvt && notify) {
+ ctx.event().record(new CacheQueryReadEvent<>(
+ ctx.discovery().localNode(),
+ "Continuous query executed.",
+ EVT_CACHE_QUERY_OBJECT_READ,
+ CacheQueryType.CONTINUOUS.name(),
+ cacheName,
+ null,
+ null,
+ null,
+ rmtFilter,
+ null,
+ nodeId,
+ taskName(),
+ evt.getKey(),
+ evt.getValue(),
+ evt.getOldValue(),
+ null
+ ));
+ }
}
@Override public void onUnregister() {
@@ -283,6 +404,85 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
((PlatformContinuousQueryFilter)rmtFilter).onQueryUnregister();
}
+ @Override public void cleanupBackupQueue(Map<Integer, Long> updateCntrs) {
+ Iterator<CacheContinuousQueryEntry> it = backupQueue.iterator();
+
+ while (it.hasNext()) {
+ CacheContinuousQueryEntry backupEntry = it.next();
+
+ Long updateCntr = updateCntrs.get(backupEntry.partition());
+
+ if (updateCntr != null && backupEntry.updateCounter() <= updateCntr)
+ it.remove();
+ }
+ }
+
+ @Override public void flushBackupQueue(GridKernalContext ctx, AffinityTopologyVersion topVer) {
+ if (backupQueue.isEmpty())
+ return;
+
+ try {
+ GridCacheContext<K, V> cctx = cacheContext(ctx);
+
+ for (CacheContinuousQueryEntry e : backupQueue) {
+ if (!e.isFiltered())
+ prepareEntry(cctx, nodeId, e);
+ }
+
+ ctx.continuous().addBackupNotification(nodeId, routineId, backupQueue, topic);
+
+ backupQueue.clear();
+ }
+ catch (IgniteCheckedException e) {
+ U.error(ctx.log(getClass()), "Failed to send backup event notification to node: " + nodeId, e);
+ }
+ }
+
+ @Override public void acknowledgeBackupOnTimeout(GridKernalContext ctx) {
+ sendBackupAcknowledge(ackBuf.acknowledgeOnTimeout(), routineId, ctx);
+ }
+
+ @Override public void skipUpdateEvent(CacheContinuousQueryEvent<K, V> evt, AffinityTopologyVersion topVer) {
+ try {
+ assert evt != null;
+
+ CacheContinuousQueryEntry e = evt.entry();
+
+ EntryBuffer buf = entryBufs.get(e.partition());
+
+ if (buf == null) {
+ buf = new EntryBuffer();
+
+ EntryBuffer oldRec = entryBufs.putIfAbsent(e.partition(), buf);
+
+ if (oldRec != null)
+ buf = oldRec;
+ }
+
+ e = buf.skipEntry(e);
+
+ if (e != null)
+ ctx.continuous().addNotification(nodeId, routineId, e, topic, sync, true);
+ }
+ catch (ClusterTopologyCheckedException ex) {
+ IgniteLogger log = ctx.log(getClass());
+
+ if (log.isDebugEnabled())
+ log.debug("Failed to send event notification to node, node left cluster " +
+ "[node=" + nodeId + ", err=" + ex + ']');
+ }
+ catch (IgniteCheckedException ex) {
+ U.error(ctx.log(getClass()), "Failed to send event notification to node: " + nodeId, ex);
+ }
+ }
+
+ @Override public void onPartitionEvicted(int part) {
+ for (Iterator<CacheContinuousQueryEntry> it = backupQueue.iterator(); it.hasNext();) {
+ if (it.next().partition() == part)
+ it.remove();
+ }
+ }
+
@Override public boolean oldValueRequired() {
return oldValRequired;
}
@@ -304,6 +504,23 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
return mgr.registerListener(routineId, lsnr, internal);
}
+ /**
+ * @param cctx Context.
+ * @param nodeId ID of the node that started routine.
+ * @param entry Entry.
+ * @throws IgniteCheckedException In case of error.
+ */
+ private void prepareEntry(GridCacheContext cctx, UUID nodeId, CacheContinuousQueryEntry entry)
+ throws IgniteCheckedException {
+ if (cctx.kernalContext().config().isPeerClassLoadingEnabled() && cctx.discovery().node(nodeId) != null) {
+ entry.prepareMarshal(cctx);
+
+ cctx.deploy().prepare(entry);
+ }
+ else
+ entry.prepareMarshal(cctx);
+ }
+
/** {@inheritDoc} */
@Override public void onListenerRegistered(UUID routineId, GridKernalContext ctx) {
// No-op.
@@ -366,17 +583,377 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
final IgniteCache cache = cctx.kernalContext().cache().jcache(cctx.name());
- Iterable<CacheEntryEvent<? extends K, ? extends V>> evts = F.viewReadOnly(entries,
+ Collection<CacheContinuousQueryEntry> entries0 = new ArrayList<>();
+
+ for (CacheContinuousQueryEntry e : entries)
+ entries0.addAll(handleEvent(ctx, e));
+
+ Iterable<CacheEntryEvent<? extends K, ? extends V>> evts = F.viewReadOnly(entries0,
new C1<CacheContinuousQueryEntry, CacheEntryEvent<? extends K, ? extends V>>() {
@Override public CacheEntryEvent<? extends K, ? extends V> apply(CacheContinuousQueryEntry e) {
return new CacheContinuousQueryEvent<>(cache, cctx, e);
}
+ },
+ new IgnitePredicate<CacheContinuousQueryEntry>() {
+ @Override public boolean apply(CacheContinuousQueryEntry entry) {
+ return !entry.isFiltered();
+ }
}
);
locLsnr.onUpdated(evts);
}
+ /**
+ * @param ctx Context.
+ * @param e entry.
+ * @return Entry collection.
+ */
+ private Collection<CacheContinuousQueryEntry> handleEvent(GridKernalContext ctx,
+ CacheContinuousQueryEntry e) {
+ assert e != null;
+
+ if (internal) {
+ if (e.isFiltered())
+ return Collections.emptyList();
+ else
+ return F.asList(e);
+ }
+
+ // Initial query entry or evicted entry.
+ // This events should be fired immediately.
+ if (e.updateCounter() == -1)
+ return F.asList(e);
+
+ PartitionRecovery rec = rcvs.get(e.partition());
+
+ if (rec == null) {
+ rec = new PartitionRecovery(ctx.log(getClass()), cacheContext(ctx).topology().topologyVersion(),
+ initUpdCntrs == null ? null : initUpdCntrs.get(e.partition()));
+
+ PartitionRecovery oldRec = rcvs.putIfAbsent(e.partition(), rec);
+
+ if (oldRec != null)
+ rec = oldRec;
+ }
+
+ return rec.collectEntries(e);
+ }
+
+ /**
+ * @param e Entry.
+ * @return Entry.
+ */
+ private CacheContinuousQueryEntry handleEntry(CacheContinuousQueryEntry e) {
+ assert e != null;
+ assert entryBufs != null;
+
+ if (internal) {
+ if (e.isFiltered())
+ return null;
+ else
+ return e;
+ }
+
+ // Initial query entry.
+ // This events should be fired immediately.
+ if (e.updateCounter() == -1)
+ return e;
+
+ EntryBuffer buf = entryBufs.get(e.partition());
+
+ if (buf == null) {
+ buf = new EntryBuffer();
+
+ EntryBuffer oldRec = entryBufs.putIfAbsent(e.partition(), buf);
+
+ if (oldRec != null)
+ buf = oldRec;
+ }
+
+ return buf.handle(e);
+ }
+
+ /**
+ *
+ */
+ private static class PartitionRecovery {
+ /** Event which means hole in sequence. */
+ private static final CacheContinuousQueryEntry HOLE = new CacheContinuousQueryEntry();
+
+ /** */
+ private final static int MAX_BUFF_SIZE = 100;
+
+ /** */
+ private IgniteLogger log;
+
+ /** */
+ private long lastFiredEvt;
+
+ /** */
+ private AffinityTopologyVersion curTop = AffinityTopologyVersion.NONE;
+
+ /** */
+ private final Map<Long, CacheContinuousQueryEntry> pendingEvts = new TreeMap<>();
+
+ /**
+ * @param log Logger.
+ * @param topVer Topology version.
+ * @param initCntr Update counters.
+ */
+ public PartitionRecovery(IgniteLogger log, AffinityTopologyVersion topVer, @Nullable Long initCntr) {
+ this.log = log;
+
+ if (initCntr != null) {
+ this.lastFiredEvt = initCntr;
+
+ curTop = topVer;
+ }
+ }
+
+ /**
+ * Add continuous entry.
+ *
+ * @param entry Cache continuous query entry.
+ * @return Collection entries which will be fired.
+ */
+ public Collection<CacheContinuousQueryEntry> collectEntries(CacheContinuousQueryEntry entry) {
+ assert entry != null;
+
+ List<CacheContinuousQueryEntry> entries;
+
+ synchronized (pendingEvts) {
+ // Received first event.
+ if (curTop == AffinityTopologyVersion.NONE) {
+ lastFiredEvt = entry.updateCounter();
+
+ curTop = entry.topologyVersion();
+
+ return F.asList(entry);
+ }
+
+ if (curTop.compareTo(entry.topologyVersion()) < 0) {
+ if (entry.updateCounter() == 1 && !entry.isBackup()) {
+ entries = new ArrayList<>(pendingEvts.size());
+
+ for (CacheContinuousQueryEntry evt : pendingEvts.values()) {
+ if (evt != HOLE && !evt.isFiltered())
+ entries.add(evt);
+ }
+
+ pendingEvts.clear();
+
+ curTop = entry.topologyVersion();
+
+ lastFiredEvt = entry.updateCounter();
+
+ entries.add(entry);
+
+ return entries;
+ }
+
+ curTop = entry.topologyVersion();
+ }
+
+ // Check duplicate.
+ if (entry.updateCounter() > lastFiredEvt) {
+ pendingEvts.put(entry.updateCounter(), entry);
+
+ // Put filtered events.
+ if (entry.filteredEvents() != null) {
+ for (long cnrt : entry.filteredEvents()) {
+ if (cnrt > lastFiredEvt)
+ pendingEvts.put(cnrt, HOLE);
+ }
+ }
+ }
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Skip duplicate continuous query message: " + entry);
+
+ return Collections.emptyList();
+ }
+
+ if (pendingEvts.isEmpty())
+ return Collections.emptyList();
+
+ Iterator<Map.Entry<Long, CacheContinuousQueryEntry>> iter = pendingEvts.entrySet().iterator();
+
+ entries = new ArrayList<>();
+
+ if (pendingEvts.size() >= MAX_BUFF_SIZE) {
+ for (int i = 0; i < MAX_BUFF_SIZE - (MAX_BUFF_SIZE / 10); i++) {
+ Map.Entry<Long, CacheContinuousQueryEntry> e = iter.next();
+
+ if (e.getValue() != HOLE && !e.getValue().isFiltered())
+ entries.add(e.getValue());
+
+ lastFiredEvt = e.getKey();
+
+ iter.remove();
+ }
+ }
+ else {
+ // Elements are consistently.
+ while (iter.hasNext()) {
+ Map.Entry<Long, CacheContinuousQueryEntry> e = iter.next();
+
+ if (e.getKey() == lastFiredEvt + 1) {
+ ++lastFiredEvt;
+
+ if (e.getValue() != HOLE && !e.getValue().isFiltered())
+ entries.add(e.getValue());
+
+ iter.remove();
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ return entries;
+ }
+ }
+
+ /**
+ *
+ */
+ private static class EntryBuffer {
+ /** */
+ private final static int MAX_BUFF_SIZE = 100;
+
+ /** */
+ private final GridConcurrentSkipListSet<Long> buf = new GridConcurrentSkipListSet<>();
+
+ /** */
+ private AtomicLong lastFiredCntr = new AtomicLong();
+
+ /**
+ * @param newVal New value.
+ * @return Old value if previous value less than new value otherwise {@code -1}.
+ */
+ private long updateFiredCounter(long newVal) {
+ long prevVal = lastFiredCntr.get();
+
+ while (prevVal < newVal) {
+ if (lastFiredCntr.compareAndSet(prevVal, newVal))
+ return prevVal;
+ else
+ prevVal = lastFiredCntr.get();
+ }
+
+ return prevVal >= newVal ? -1 : prevVal;
+ }
+
+ /**
+ * @param e Entry.
+ * @param topVer Topology version.
+ * @return Continuous query entry.
+ */
+ private CacheContinuousQueryEntry skipEntry(CacheContinuousQueryEntry e) {
+ if (lastFiredCntr.get() > e.updateCounter() || e.updateCounter() == 1) {
+
+ e.markFiltered();
+
+ return e;
+ }
+ else {
+ buf.add(e.updateCounter());
+
+ // Double check. If another thread sent a event with counter higher than this event.
+ if (lastFiredCntr.get() > e.updateCounter() && buf.contains(e.updateCounter())) {
+ buf.remove(e.updateCounter());
+
+ e.markFiltered();
+
+ return e;
+ }
+ else
+ return null;
+ }
+ }
+
+ /**
+ * Add continuous entry.
+ *
+ * @param e Cache continuous query entry.
+ * @return Collection entries which will be fired.
+ */
+ public CacheContinuousQueryEntry handle(CacheContinuousQueryEntry e) {
+ assert e != null;
+
+ if (e.isFiltered()) {
+ Long last = buf.lastx();
+ Long first = buf.firstx();
+
+ if (last != null && first != null && last - first >= MAX_BUFF_SIZE) {
+ NavigableSet<Long> prevHoles = buf.subSet(first, true, last, true);
+
+ GridLongList filteredEvts = new GridLongList((int)(last - first));
+
+ int size = 0;
+
+ Long cntr;
+
+ while ((cntr = prevHoles.pollFirst()) != null) {
+ filteredEvts.add(cntr);
+
+ ++size;
+ }
+
+ filteredEvts.truncate(size, true);
+
+ e.filteredEvents(filteredEvts);
+
+ return e;
+ }
+
+ if (lastFiredCntr.get() > e.updateCounter() || e.updateCounter() == 1)
+ return e;
+ else {
+ buf.add(e.updateCounter());
+
+ // Double check. If another thread sent a event with counter higher than this event.
+ if (lastFiredCntr.get() > e.updateCounter() && buf.contains(e.updateCounter())) {
+ buf.remove(e.updateCounter());
+
+ return e;
+ }
+ else
+ return null;
+ }
+ }
+ else {
+ long prevVal = updateFiredCounter(e.updateCounter());
+
+ if (prevVal == -1)
+ return e;
+ else {
+ NavigableSet<Long> prevHoles = buf.subSet(prevVal, true, e.updateCounter(), true);
+
+ GridLongList filteredEvts = new GridLongList((int)(e.updateCounter() - prevVal));
+
+ int size = 0;
+
+ Long cntr;
+
+ while ((cntr = prevHoles.pollFirst()) != null) {
+ filteredEvts.add(cntr);
+
+ ++size;
+ }
+
+ filteredEvts.truncate(size, true);
+
+ e.filteredEvents(filteredEvts);
+
+ return e;
+ }
+ }
+ }
+ }
+
/** {@inheritDoc} */
@Override public void p2pMarshal(GridKernalContext ctx) throws IgniteCheckedException {
assert ctx != null;
@@ -397,6 +974,65 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
}
/** {@inheritDoc} */
+ @Override public GridContinuousBatch createBatch() {
+ return new GridContinuousBatchAdapter();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onBatchAcknowledged(final UUID routineId,
+ GridContinuousBatch batch,
+ final GridKernalContext ctx) {
+ sendBackupAcknowledge(ackBuf.onAcknowledged(batch), routineId, ctx);
+ }
+
+ /**
+ * @param t Acknowledge information.
+ * @param routineId Routine ID.
+ * @param ctx Context.
+ */
+ private void sendBackupAcknowledge(final IgniteBiTuple<Map<Integer, Long>, Set<AffinityTopologyVersion>> t,
+ final UUID routineId,
+ final GridKernalContext ctx) {
+ if (t != null) {
+ ctx.closure().runLocalSafe(new Runnable() {
+ @Override public void run() {
+ GridCacheContext<K, V> cctx = cacheContext(ctx);
+
+ CacheContinuousQueryBatchAck msg = new CacheContinuousQueryBatchAck(cctx.cacheId(),
+ routineId,
+ t.get1());
+
+ Collection<ClusterNode> nodes = new HashSet<>();
+
+ for (AffinityTopologyVersion topVer : t.get2())
+ nodes.addAll(ctx.discovery().cacheNodes(topVer));
+
+ for (ClusterNode node : nodes) {
+ if (!node.id().equals(ctx.localNodeId())) {
+ try {
+ cctx.io().send(node, msg, GridIoPolicy.SYSTEM_POOL);
+ }
+ catch (ClusterTopologyCheckedException e) {
+ IgniteLogger log = ctx.log(getClass());
+
+ if (log.isDebugEnabled())
+ log.debug("Failed to send acknowledge message, node left " +
+ "[msg=" + msg + ", node=" + node + ']');
+ }
+ catch (IgniteCheckedException e) {
+ IgniteLogger log = ctx.log(getClass());
+
+ U.error(log, "Failed to send acknowledge message " +
+ "[msg=" + msg + ", node=" + node + ']', e);
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+
+ /** {@inheritDoc} */
@Nullable @Override public Object orderedTopic() {
return topic;
}
@@ -471,6 +1107,93 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
return ctx.cache().<K, V>context().cacheContext(cacheId);
}
+ /** */
+ private static class AcknowledgeBuffer {
+ /** */
+ private int size;
+
+ /** */
+ @GridToStringInclude
+ private Map<Integer, Long> updateCntrs = new HashMap<>();
+
+ /** */
+ @GridToStringInclude
+ private Set<AffinityTopologyVersion> topVers = U.newHashSet(1);
+
+ /**
+ * @param batch Batch.
+ * @return Non-null tuple if acknowledge should be sent to backups.
+ */
+ @SuppressWarnings("unchecked")
+ @Nullable synchronized IgniteBiTuple<Map<Integer, Long>, Set<AffinityTopologyVersion>>
+ onAcknowledged(GridContinuousBatch batch) {
+ size += batch.size();
+
+ Collection<CacheContinuousQueryEntry> entries = (Collection)batch.collect();
+
+ for (CacheContinuousQueryEntry e : entries)
+ addEntry(e);
+
+ return size >= BACKUP_ACK_THRESHOLD ? acknowledgeData() : null;
+ }
+
+ /**
+ * @param e Entry.
+ * @return Non-null tuple if acknowledge should be sent to backups.
+ */
+ @Nullable synchronized IgniteBiTuple<Map<Integer, Long>, Set<AffinityTopologyVersion>>
+ onAcknowledged(CacheContinuousQueryEntry e) {
+ size++;
+
+ addEntry(e);
+
+ return size >= BACKUP_ACK_THRESHOLD ? acknowledgeData() : null;
+ }
+
+ /**
+ * @param e Entry.
+ */
+ private void addEntry(CacheContinuousQueryEntry e) {
+ topVers.add(e.topologyVersion());
+
+ Long cntr0 = updateCntrs.get(e.partition());
+
+ if (cntr0 == null || e.updateCounter() > cntr0)
+ updateCntrs.put(e.partition(), e.updateCounter());
+ }
+
+ /**
+ * @return Non-null tuple if acknowledge should be sent to backups.
+ */
+ @Nullable synchronized IgniteBiTuple<Map<Integer, Long>, Set<AffinityTopologyVersion>>
+ acknowledgeOnTimeout() {
+ return size > 0 ? acknowledgeData() : null;
+ }
+
+ /**
+ * @return Tuple with acknowledge information.
+ */
+ private IgniteBiTuple<Map<Integer, Long>, Set<AffinityTopologyVersion>> acknowledgeData() {
+ assert size > 0;
+
+ Map<Integer, Long> cntrs = new HashMap<>(updateCntrs);
+
+ IgniteBiTuple<Map<Integer, Long>, Set<AffinityTopologyVersion>> res =
+ new IgniteBiTuple<>(cntrs, topVers);
+
+ topVers = U.newHashSet(1);
+
+ size = 0;
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(AcknowledgeBuffer.class, this);
+ }
+ }
+
/**
* Deployable object.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryListener.java
index a3c19a9..8342acf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryListener.java
@@ -17,6 +17,10 @@
package org.apache.ignite.internal.processors.cache.query.continuous;
+import java.util.Map;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+
/**
* Continuous query listener.
*/
@@ -41,6 +45,37 @@ interface CacheContinuousQueryListener<K, V> {
public void onUnregister();
/**
+ * Cleans backup queue.
+ *
+ * @param updateCntrs Update indexes map.
+ */
+ public void cleanupBackupQueue(Map<Integer, Long> updateCntrs);
+
+ /**
+ * Flushes backup queue.
+ *
+ * @param ctx Context.
+ * @param topVer Topology version.
+ */
+ public void flushBackupQueue(GridKernalContext ctx, AffinityTopologyVersion topVer);
+
+ /**
+ * @param ctx Context.
+ */
+ public void acknowledgeBackupOnTimeout(GridKernalContext ctx);
+
+ /**
+ * @param evt Event
+ * @param topVer Topology version.
+ */
+ public void skipUpdateEvent(CacheContinuousQueryEvent<K, V> evt, AffinityTopologyVersion topVer);
+
+ /**
+ * @param part Partition.
+ */
+ public void onPartitionEvicted(int part);
+
+ /**
* @return Whether old value is required.
*/
public boolean oldValueRequired();
[21/23] ignite git commit: IGNITE-426 Implemented failover for
Continuous query.
Posted by sb...@apache.org.
IGNITE-426 Implemented failover for Continuous query.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ce636372
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ce636372
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ce636372
Branch: refs/heads/ignite-sql-opt
Commit: ce6363729f3553c6854ed2e8cfc3b5c244678fcd
Parents: 8728a5b
Author: nikolay_tikhonov <nt...@gridgain.com>
Authored: Thu Nov 19 19:50:58 2015 +0300
Committer: nikolay_tikhonov <nt...@gridgain.com>
Committed: Thu Nov 19 19:50:58 2015 +0300
----------------------------------------------------------------------
.../internal/GridEventConsumeHandler.java | 22 +-
.../internal/GridMessageListenHandler.java | 18 +
.../communication/GridIoMessageFactory.java | 8 +-
.../processors/cache/GridCacheEntryEx.java | 12 +-
.../processors/cache/GridCacheMapEntry.java | 147 +-
.../GridCachePartitionExchangeManager.java | 4 +-
.../cache/GridCacheUpdateAtomicResult.java | 15 +-
.../cache/GridCacheUpdateTxResult.java | 24 +-
.../GridDistributedTxRemoteAdapter.java | 22 +-
.../dht/GridClientPartitionTopology.java | 38 +-
.../distributed/dht/GridDhtLocalPartition.java | 35 +
.../dht/GridDhtPartitionTopology.java | 26 +-
.../dht/GridDhtPartitionTopologyImpl.java | 112 +-
.../distributed/dht/GridDhtTxFinishFuture.java | 14 +-
.../distributed/dht/GridDhtTxFinishRequest.java | 112 +-
.../dht/atomic/GridDhtAtomicCache.java | 79 +-
.../dht/atomic/GridDhtAtomicUpdateFuture.java | 75 +-
.../dht/atomic/GridDhtAtomicUpdateRequest.java | 140 +-
.../GridDhtPartitionsExchangeFuture.java | 35 +-
.../preloader/GridDhtPartitionsFullMessage.java | 64 +-
.../GridDhtPartitionsSingleMessage.java | 56 +-
.../distributed/near/GridNearAtomicCache.java | 10 +-
.../distributed/near/GridNearTxRemote.java | 7 +
.../CacheContinuousQueryBatchAck.java | 163 ++
.../continuous/CacheContinuousQueryEntry.java | 196 +-
.../continuous/CacheContinuousQueryEvent.java | 3 +-
.../continuous/CacheContinuousQueryHandler.java | 811 ++++++-
.../CacheContinuousQueryListener.java | 35 +
.../continuous/CacheContinuousQueryManager.java | 151 +-
.../cache/transactions/IgniteTxEntry.java | 20 +
.../cache/transactions/IgniteTxHandler.java | 3 +
.../transactions/IgniteTxLocalAdapter.java | 18 +-
.../cache/transactions/IgniteTxRemoteEx.java | 7 +-
.../continuous/GridContinuousBatch.java | 44 +
.../continuous/GridContinuousBatchAdapter.java | 46 +
.../continuous/GridContinuousHandler.java | 22 +
.../continuous/GridContinuousProcessor.java | 221 +-
.../StartRoutineAckDiscoveryMessage.java | 14 +-
.../StartRoutineDiscoveryMessage.java | 21 +-
.../processors/cache/GridCacheTestEntryEx.java | 10 +-
...ContinuousQueryFailoverAbstractSelfTest.java | 2235 ++++++++++++++++++
...ryFailoverAtomicNearEnabledSelfSelfTest.java | 46 +
...FailoverAtomicPrimaryWriteOrderSelfTest.java | 44 +
...usQueryFailoverAtomicReplicatedSelfTest.java | 40 +
...inuousQueryFailoverTxReplicatedSelfTest.java | 32 +
.../CacheContinuousQueryFailoverTxSelfTest.java | 39 +
...ridCacheContinuousQueryAbstractSelfTest.java | 153 +-
.../GridCacheContinuousQueryTxSelfTest.java | 49 +
...CacheContinuousQueryClientReconnectTest.java | 187 ++
.../IgniteCacheContinuousQueryClientTest.java | 157 +-
...cheContinuousQueryClientTxReconnectTest.java | 32 +
.../p2p/GridP2PSameClassLoaderSelfTest.java | 16 +-
.../testframework/junits/GridAbstractTest.java | 2 +-
.../junits/common/GridCommonAbstractTest.java | 3 +
.../IgniteCacheQuerySelfTestSuite.java | 16 +-
.../yardstick/cache/CacheEntryEventProbe.java | 156 ++
56 files changed, 5753 insertions(+), 314 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
index b4ce4ab..3918976 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
@@ -23,6 +23,7 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.LinkedList;
+import java.util.Map;
import java.util.Queue;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
@@ -38,6 +39,8 @@ import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
import org.apache.ignite.internal.processors.cache.GridCacheDeploymentManager;
+import org.apache.ignite.internal.processors.continuous.GridContinuousBatch;
+import org.apache.ignite.internal.processors.continuous.GridContinuousBatchAdapter;
import org.apache.ignite.internal.processors.continuous.GridContinuousHandler;
import org.apache.ignite.internal.processors.platform.PlatformEventFilterListener;
import org.apache.ignite.internal.util.typedef.F;
@@ -127,6 +130,11 @@ class GridEventConsumeHandler implements GridContinuousHandler {
}
/** {@inheritDoc} */
+ @Override public void updateCounters(Map<Integer, Long> cntrs) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
@Override public RegisterStatus register(final UUID nodeId, final UUID routineId, final GridKernalContext ctx)
throws IgniteCheckedException {
assert nodeId != null;
@@ -213,8 +221,8 @@ class GridEventConsumeHandler implements GridContinuousHandler {
}
}
- ctx.continuous().addNotification(t3.get1(), t3.get2(), wrapper, null, false,
- false);
+ ctx.continuous().addNotification(t3.get1(), t3.get2(), wrapper, null,
+ false, false);
}
catch (ClusterTopologyCheckedException ignored) {
// No-op.
@@ -377,6 +385,16 @@ class GridEventConsumeHandler implements GridContinuousHandler {
}
/** {@inheritDoc} */
+ @Override public GridContinuousBatch createBatch() {
+ return new GridContinuousBatchAdapter();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onBatchAcknowledged(UUID routineId, GridContinuousBatch batch, GridKernalContext ctx) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
@Nullable @Override public Object orderedTopic() {
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
index ff38949..aa837b8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridMessageListenHandler.java
@@ -22,10 +22,13 @@ import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
+import java.util.Map;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.managers.deployment.GridDeployment;
import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean;
+import org.apache.ignite.internal.processors.continuous.GridContinuousBatch;
+import org.apache.ignite.internal.processors.continuous.GridContinuousBatchAdapter;
import org.apache.ignite.internal.processors.continuous.GridContinuousHandler;
import org.apache.ignite.internal.util.lang.GridPeerDeployAware;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -100,6 +103,11 @@ public class GridMessageListenHandler implements GridContinuousHandler {
}
/** {@inheritDoc} */
+ @Override public void updateCounters(Map<Integer, Long> cntrs) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
@Override public RegisterStatus register(UUID nodeId, UUID routineId, final GridKernalContext ctx) throws IgniteCheckedException {
ctx.io().addUserMessageListener(topic, pred);
@@ -167,6 +175,16 @@ public class GridMessageListenHandler implements GridContinuousHandler {
}
/** {@inheritDoc} */
+ @Override public GridContinuousBatch createBatch() {
+ return new GridContinuousBatchAdapter();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onBatchAcknowledged(UUID routineId, GridContinuousBatch batch, GridKernalContext ctx) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
@Nullable @Override public Object orderedTopic() {
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
index 3548aac..c671582 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
@@ -93,6 +93,7 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridNearUnlo
import org.apache.ignite.internal.processors.cache.query.GridCacheQueryRequest;
import org.apache.ignite.internal.processors.cache.query.GridCacheQueryResponse;
import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
+import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryBatchAck;
import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
@@ -708,7 +709,12 @@ public class GridIoMessageFactory implements MessageFactory {
break;
- // [-3..114] - this
+ case 118:
+ msg = new CacheContinuousQueryBatchAck();
+
+ break;
+
+ // [-3..118] - this
// [120..123] - DR
// [-4..-22] - SQL
default:
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 af62e39..8d50616 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
@@ -360,6 +360,7 @@ public interface GridCacheEntryEx {
* @param subjId Subject ID initiated this update.
* @param taskName Task name.
* @param dhtVer Dht version for near cache entry.
+ * @param updateCntr Update counter.
* @return Tuple containing success flag and old value. If success is {@code false},
* then value is {@code null}.
* @throws IgniteCheckedException If storing value failed.
@@ -382,7 +383,8 @@ public interface GridCacheEntryEx {
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
String taskName,
- @Nullable GridCacheVersion dhtVer
+ @Nullable GridCacheVersion dhtVer,
+ @Nullable Long updateCntr
) throws IgniteCheckedException, GridCacheEntryRemovedException;
/**
@@ -417,7 +419,8 @@ public interface GridCacheEntryEx {
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
String taskName,
- @Nullable GridCacheVersion dhtVer
+ @Nullable GridCacheVersion dhtVer,
+ @Nullable Long updateCntr
) throws IgniteCheckedException, GridCacheEntryRemovedException;
/**
@@ -446,6 +449,7 @@ public interface GridCacheEntryEx {
* @param intercept If {@code true} then calls cache interceptor.
* @param subjId Subject ID initiated this update.
* @param taskName Task name.
+ * @param updateCntr Update counter.
* @return Tuple where first value is flag showing whether operation succeeded,
* second value is old entry value if return value is requested, third is updated entry value,
* fourth is the version to enqueue for deferred delete the fifth is DR conflict context
@@ -478,7 +482,9 @@ public interface GridCacheEntryEx {
boolean conflictResolve,
boolean intercept,
@Nullable UUID subjId,
- String taskName
+ String taskName,
+ @Nullable CacheObject prevVal,
+ @Nullable Long updateCntr
) throws IgniteCheckedException, GridCacheEntryRemovedException;
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 0786a50..8d363ad 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,6 +37,7 @@ 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.dht.GridDhtLocalPartition;
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;
@@ -1060,7 +1061,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
String taskName,
- @Nullable GridCacheVersion dhtVer
+ @Nullable GridCacheVersion dhtVer,
+ @Nullable Long updateCntr
) throws IgniteCheckedException, GridCacheEntryRemovedException {
CacheObject old;
@@ -1077,6 +1079,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
Object key0 = null;
Object val0 = null;
+ long updateCntr0;
+
synchronized (this) {
checkObsolete();
@@ -1155,6 +1159,11 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
deletedUnlocked(false);
}
+ updateCntr0 = nextPartCounter(topVer);
+
+ if (updateCntr != null && updateCntr != 0)
+ updateCntr0 = updateCntr;
+
update(val, expireTime, ttl, newVer);
drReplicate(drType, val, newVer);
@@ -1180,8 +1189,10 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
subjId, null, taskName);
}
- if (cctx.isLocal() || cctx.isReplicated() || (tx != null && tx.local() && !isNear()))
- cctx.continuousQueries().onEntryUpdated(this, key, val, old, false);
+ if (cctx.isLocal() || cctx.isReplicated() ||
+ (!isNear() && !(tx != null && tx.onePhaseCommit() && !tx.local())))
+ cctx.continuousQueries().onEntryUpdated(key, val, old, isInternal() || !context().userCache(),
+ partition(), tx.local(), false, updateCntr0, topVer);
cctx.dataStructures().onEntryUpdated(key, false);
}
@@ -1197,7 +1208,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (intercept)
cctx.config().getInterceptor().onAfterPut(new CacheLazyEntry(cctx, key, key0, val, val0));
- return valid ? new GridCacheUpdateTxResult(true, retval ? old : null) :
+ return valid ? new GridCacheUpdateTxResult(true, retval ? old : null, updateCntr0) :
new GridCacheUpdateTxResult(false, null);
}
@@ -1223,7 +1234,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
@Nullable GridCacheVersion explicitVer,
@Nullable UUID subjId,
String taskName,
- @Nullable GridCacheVersion dhtVer
+ @Nullable GridCacheVersion dhtVer,
+ @Nullable Long updateCntr
) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert cctx.transactional();
@@ -1245,6 +1257,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
Cache.Entry entry0 = null;
+ Long updateCntr0;
+
boolean deferred;
boolean marked = false;
@@ -1261,7 +1275,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
assert tx == null || (!tx.local() && tx.onePhaseCommit()) || tx.ownsLock(this) :
- "Transaction does not own lock for remove[entry=" + this + ", tx=" + tx + ']';
+ "Transaction does not own lock for remove[entry=" + this + ", tx=" + tx + ']';
boolean startVer = isStartVersion();
@@ -1318,6 +1332,11 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
}
+ updateCntr0 = nextPartCounter(topVer);
+
+ if (updateCntr != null && updateCntr != 0)
+ updateCntr0 = updateCntr;
+
drReplicate(drType, null, newVer);
if (metrics && cctx.cache().configuration().isStatisticsEnabled())
@@ -1350,8 +1369,10 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
taskName);
}
- if (cctx.isLocal() || cctx.isReplicated() || (tx != null && tx.local() && !isNear()))
- cctx.continuousQueries().onEntryUpdated(this, key, null, old, false);
+ if (cctx.isLocal() || cctx.isReplicated() ||
+ (!isNear() && !(tx != null && tx.onePhaseCommit() && !tx.local())))
+ cctx.continuousQueries().onEntryUpdated(key, null, old, isInternal()
+ || !context().userCache(),partition(), tx.local(), false, updateCntr0, topVer);
cctx.dataStructures().onEntryUpdated(key, true);
@@ -1394,7 +1415,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
else
ret = old;
- return new GridCacheUpdateTxResult(true, ret);
+ return new GridCacheUpdateTxResult(true, ret, updateCntr0);
}
else
return new GridCacheUpdateTxResult(false, null);
@@ -1686,7 +1707,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (res)
updateMetrics(op, metrics);
- cctx.continuousQueries().onEntryUpdated(this, key, val, old, false);
+ if (!isNear()) {
+ long updateCntr = nextPartCounter(AffinityTopologyVersion.NONE);
+
+ cctx.continuousQueries().onEntryUpdated(key, val, old, isInternal() || !context().userCache(),
+ partition(), true, false, updateCntr, AffinityTopologyVersion.NONE);
+ }
cctx.dataStructures().onEntryUpdated(key, op == GridCacheOperation.DELETE);
@@ -1729,7 +1755,9 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
boolean conflictResolve,
boolean intercept,
@Nullable UUID subjId,
- String taskName
+ String taskName,
+ @Nullable CacheObject prevVal,
+ @Nullable Long updateCntr
) throws IgniteCheckedException, GridCacheEntryRemovedException, GridClosureException {
assert cctx.atomic();
@@ -1755,6 +1783,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
Object key0 = null;
Object updated0 = null;
+ Long updateCntr0 = null;
+
synchronized (this) {
boolean needVal = intercept || retval || op == GridCacheOperation.TRANSFORM || !F.isEmptyOrNulls(filter);
@@ -1862,7 +1892,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CU.EXPIRE_TIME_ETERNAL,
null,
null,
- false);
+ false,
+ updateCntr0 == null ? 0 : updateCntr0);
}
// Will update something.
else {
@@ -1911,6 +1942,38 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
"[entry=" + this + ", newVer=" + newVer + ']');
}
+ if (!cctx.isNear()) {
+ CacheObject evtVal;
+
+ if (op == GridCacheOperation.TRANSFORM) {
+ EntryProcessor<Object, Object, ?> entryProcessor =
+ (EntryProcessor<Object, Object, ?>)writeObj;
+
+ CacheInvokeEntry<Object, Object> entry =
+ new CacheInvokeEntry<>(cctx, key, prevVal, version());
+
+ try {
+ entryProcessor.process(entry, invokeArgs);
+
+ evtVal = entry.modified() ?
+ cctx.toCacheObject(cctx.unwrapTemporary(entry.getValue())) : prevVal;
+ }
+ catch (Exception e) {
+ evtVal = prevVal;
+ }
+ }
+ else
+ evtVal = (CacheObject)writeObj;
+
+ updateCntr0 = nextPartCounter(topVer);
+
+ if (updateCntr != null)
+ updateCntr0 = updateCntr;
+
+ cctx.continuousQueries().onEntryUpdated(key, evtVal, prevVal, isInternal()
+ || !context().userCache(), partition(), primary, false, updateCntr0, topVer);
+ }
+
return new GridCacheUpdateAtomicResult(false,
retval ? rawGetOrUnmarshalUnlocked(false) : null,
null,
@@ -1919,7 +1982,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CU.EXPIRE_TIME_ETERNAL,
null,
null,
- false);
+ false,
+ updateCntr0 == null ? 0 : updateCntr0);
}
}
else
@@ -1995,7 +2059,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CU.EXPIRE_TIME_ETERNAL,
null,
null,
- false);
+ false,
+ updateCntr0 == null ? 0 : updateCntr0);
}
}
@@ -2042,7 +2107,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CU.EXPIRE_TIME_ETERNAL,
null,
null,
- false);
+ false,
+ updateCntr0 == null ? 0 : updateCntr);
}
}
else
@@ -2142,7 +2208,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CU.EXPIRE_TIME_ETERNAL,
null,
null,
- false);
+ false,
+ updateCntr0 == null ? 0 : updateCntr0);
else if (interceptorVal != updated0) {
updated0 = cctx.unwrapTemporary(interceptorVal);
@@ -2179,6 +2246,11 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
update(updated, newExpireTime, newTtl, newVer);
+ updateCntr0 = nextPartCounter(topVer);
+
+ if (updateCntr != null)
+ updateCntr0 = updateCntr;
+
drReplicate(drType, updated, newVer);
recordNodeId(affNodeId, topVer);
@@ -2218,7 +2290,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CU.EXPIRE_TIME_ETERNAL,
null,
null,
- false);
+ false,
+ updateCntr0 == null ? 0 : updateCntr0);
}
if (writeThrough)
@@ -2270,6 +2343,11 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
recordNodeId(affNodeId, topVer);
+ updateCntr0 = nextPartCounter(topVer);
+
+ if (updateCntr != null)
+ updateCntr0 = updateCntr;
+
drReplicate(drType, null, newVer);
if (evt) {
@@ -2299,9 +2377,6 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (res)
updateMetrics(op, metrics);
- if (cctx.isReplicated() || primary)
- cctx.continuousQueries().onEntryUpdated(this, key, val, oldVal, false);
-
cctx.dataStructures().onEntryUpdated(key, op == GridCacheOperation.DELETE);
if (intercept) {
@@ -2326,7 +2401,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
newSysExpireTime,
enqueueVer,
conflictCtx,
- true);
+ true,
+ updateCntr0);
}
/**
@@ -3146,11 +3222,16 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
else if (deletedUnlocked())
deletedUnlocked(false);
+ long updateCntr = 0;
+
+ if (!preload)
+ updateCntr = nextPartCounter(topVer);
+
drReplicate(drType, val, ver);
if (!skipQryNtf) {
- if (cctx.isLocal() || cctx.isReplicated() || cctx.affinity().primary(cctx.localNode(), key, topVer))
- cctx.continuousQueries().onEntryUpdated(this, key, val, null, preload);
+ cctx.continuousQueries().onEntryUpdated(key, val, null, this.isInternal()
+ || !this.context().userCache(), this.partition(), true, preload, updateCntr, topVer);
cctx.dataStructures().onEntryUpdated(key, false);
}
@@ -3167,6 +3248,26 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
}
+ /**
+ * @param topVer Topology version.
+ * @return Update counter.
+ */
+ private long nextPartCounter(AffinityTopologyVersion topVer) {
+ long updateCntr;
+
+ if (!cctx.isLocal() && !isNear()) {
+ GridDhtLocalPartition locPart = cctx.topology().localPartition(partition(), topVer, false);
+
+ assert locPart != null;
+
+ updateCntr = locPart.nextUpdateCounter();
+ }
+ else
+ updateCntr = 0;
+
+ return updateCntr;
+ }
+
/** {@inheritDoc} */
@Override public synchronized boolean initialValue(KeyCacheObject key, GridCacheSwapEntry unswapped) throws
IgniteCheckedException,
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index e19b310..cd89416 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -989,7 +989,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
top = cacheCtx.topology();
if (top != null)
- updated |= top.update(null, entry.getValue()) != null;
+ updated |= top.update(null, entry.getValue(), null) != null;
}
if (!cctx.kernalContext().clientNode() && updated)
@@ -1032,7 +1032,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
top = cacheCtx.topology();
if (top != null)
- updated |= top.update(null, entry.getValue()) != null;
+ updated |= top.update(null, entry.getValue(), null) != null;
}
if (updated)
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateAtomicResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateAtomicResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateAtomicResult.java
index 3674284..9df476e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateAtomicResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateAtomicResult.java
@@ -57,6 +57,9 @@ public class GridCacheUpdateAtomicResult {
/** Whether update should be propagated to DHT node. */
private final boolean sndToDht;
+ /** */
+ private final Long updateCntr;
+
/** Value computed by entry processor. */
private IgniteBiTuple<Object, Exception> res;
@@ -72,6 +75,7 @@ public class GridCacheUpdateAtomicResult {
* @param rmvVer Version for deferred delete.
* @param conflictRes DR resolution result.
* @param sndToDht Whether update should be propagated to DHT node.
+ * @param updateCntr Partition update counter.
*/
public GridCacheUpdateAtomicResult(boolean success,
@Nullable CacheObject oldVal,
@@ -81,7 +85,8 @@ public class GridCacheUpdateAtomicResult {
long conflictExpireTime,
@Nullable GridCacheVersion rmvVer,
@Nullable GridCacheVersionConflictContext<?, ?> conflictRes,
- boolean sndToDht) {
+ boolean sndToDht,
+ long updateCntr) {
this.success = success;
this.oldVal = oldVal;
this.newVal = newVal;
@@ -91,6 +96,7 @@ public class GridCacheUpdateAtomicResult {
this.rmvVer = rmvVer;
this.conflictRes = conflictRes;
this.sndToDht = sndToDht;
+ this.updateCntr = updateCntr;
}
/**
@@ -129,6 +135,13 @@ public class GridCacheUpdateAtomicResult {
}
/**
+ * @return Partition update index.
+ */
+ public Long updateCounter() {
+ return updateCntr;
+ }
+
+ /**
* @return Explicit conflict expire time (if any). Set only if it is necessary to propagate concrete expire time
* value to DHT node. Otherwise set to {@link GridCacheUtils#EXPIRE_TIME_CALCULATE}.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateTxResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateTxResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateTxResult.java
index ffda7a2..461baa7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateTxResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUpdateTxResult.java
@@ -32,6 +32,9 @@ public class GridCacheUpdateTxResult {
@GridToStringInclude
private final CacheObject oldVal;
+ /** Partition idx. */
+ private long updateCntr;
+
/**
* Constructor.
*
@@ -44,6 +47,25 @@ public class GridCacheUpdateTxResult {
}
/**
+ * Constructor.
+ *
+ * @param success Success flag.
+ * @param oldVal Old value (if any),
+ */
+ GridCacheUpdateTxResult(boolean success, @Nullable CacheObject oldVal, long updateCntr) {
+ this.success = success;
+ this.oldVal = oldVal;
+ this.updateCntr = updateCntr;
+ }
+
+ /**
+ * @return Partition idx.
+ */
+ public long updatePartitionCounter() {
+ return updateCntr;
+ }
+
+ /**
* @return Success flag.
*/
public boolean success() {
@@ -61,4 +83,4 @@ public class GridCacheUpdateTxResult {
@Override public String toString() {
return S.toString(GridCacheUpdateTxResult.class, this);
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 0d49584..f9ac2df 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
@@ -265,6 +265,19 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
}
}
+ /** {@inheritDoc} */
+ @Override public void setPartitionUpdateCounters(long[] cntrs) {
+ if (writeMap() != null && !writeMap().isEmpty() && cntrs != null && cntrs.length > 0) {
+ int i = 0;
+
+ for (IgniteTxEntry txEntry : writeMap().values()) {
+ txEntry.updateCounter(cntrs[i]);
+
+ ++i;
+ }
+ }
+ }
+
/**
* Adds completed versions to an entry.
*
@@ -529,7 +542,8 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
near() ? null : explicitVer,
CU.subjectId(this, cctx),
resolveTaskName(),
- dhtVer);
+ dhtVer,
+ txEntry.updateCounter());
else {
cached.innerSet(this,
eventNodeId(),
@@ -547,7 +561,8 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
near() ? null : explicitVer,
CU.subjectId(this, cctx),
resolveTaskName(),
- dhtVer);
+ dhtVer,
+ txEntry.updateCounter());
// Keep near entry up to date.
if (nearCached != null) {
@@ -575,7 +590,8 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
near() ? null : explicitVer,
CU.subjectId(this, cctx),
resolveTaskName(),
- dhtVer);
+ dhtVer,
+ txEntry.updateCounter());
// Keep near entry up to date.
if (nearCached != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
index 162c116..b7169bf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
@@ -94,6 +94,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
/** Lock. */
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+ /** Partition update counters. */
+ private Map<Integer, Long> cntrMap = new HashMap<>();
+
/**
* @param cctx Context.
* @param cacheId Cache ID.
@@ -527,7 +530,8 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
/** {@inheritDoc} */
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
@Nullable @Override public GridDhtPartitionMap update(@Nullable GridDhtPartitionExchangeId exchId,
- GridDhtPartitionFullMap partMap) {
+ GridDhtPartitionFullMap partMap,
+ Map<Integer, Long> cntrMap) {
if (log.isDebugEnabled())
log.debug("Updating full partition map [exchId=" + exchId + ", parts=" + fullMapString() + ']');
@@ -602,6 +606,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
part2node = p2n;
+ if (cntrMap != null)
+ this.cntrMap = new HashMap<>(cntrMap);
+
consistencyCheck();
if (log.isDebugEnabled())
@@ -617,7 +624,8 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
/** {@inheritDoc} */
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
@Nullable @Override public GridDhtPartitionMap update(@Nullable GridDhtPartitionExchangeId exchId,
- GridDhtPartitionMap parts) {
+ GridDhtPartitionMap parts,
+ Map<Integer, Long> cntrMap) {
if (log.isDebugEnabled())
log.debug("Updating single partition map [exchId=" + exchId + ", parts=" + mapString(parts) + ']');
@@ -698,6 +706,15 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
}
}
+ if (cntrMap != null) {
+ for (Map.Entry<Integer, Long> e : cntrMap.entrySet()) {
+ Long cntr = this.cntrMap.get(e.getKey());
+
+ if (cntr == null || cntr < e.getValue())
+ this.cntrMap.put(e.getKey(), e.getValue());
+ }
+ }
+
consistencyCheck();
if (log.isDebugEnabled())
@@ -852,6 +869,23 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
}
/** {@inheritDoc} */
+ @Override public Map<Integer, Long> updateCounters() {
+ lock.readLock().lock();
+
+ try {
+ return new HashMap<>(cntrMap);
+ }
+ finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean rebalanceFinished(AffinityTopologyVersion topVer) {
+ return false;
+ }
+
+ /** {@inheritDoc} */
@Override public void printMemoryStats(int threshold) {
X.println(">>> Cache partition topology stats [grid=" + cctx.gridName() + ", cacheId=" + cacheId + ']');
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
index 1516ee4..63e2899 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.locks.ReentrantLock;
@@ -114,6 +115,9 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
/** Group reservations. */
private final CopyOnWriteArrayList<GridDhtPartitionsReservation> reservations = new CopyOnWriteArrayList<>();
+ /** Update counter. */
+ private final AtomicLong cntr = new AtomicLong();
+
/**
* @param cctx Context.
* @param id Partition ID.
@@ -532,6 +536,8 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
if (cctx.isDrEnabled())
cctx.dr().partitionEvicted(id);
+ cctx.continuousQueries().onPartitionEvicted(id);
+
cctx.dataStructures().onPartitionEvicted(id);
rent.onDone();
@@ -599,6 +605,35 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
}
/**
+ * @return Next update index.
+ */
+ public long nextUpdateCounter() {
+ return cntr.incrementAndGet();
+ }
+
+ /**
+ * @return Current update index.
+ */
+ public long updateCounter() {
+ return cntr.get();
+ }
+
+ /**
+ * @param val Update index value.
+ */
+ public void updateCounter(long val) {
+ while (true) {
+ long val0 = cntr.get();
+
+ if (val0 >= val)
+ break;
+
+ if (cntr.compareAndSet(val0, val))
+ break;
+ }
+ }
+
+ /**
* Clears values for this partition.
*/
private void clearAll() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
index d642314..3ac2b85 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.distributed.dht;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
@@ -51,6 +52,8 @@ public interface GridDhtPartitionTopology {
*
* @param exchId Exchange ID.
* @param exchFut Exchange future.
+ * @param updateSeq Update sequence.
+ * @param stopping Stopping flag.
* @throws IgniteInterruptedCheckedException If interrupted.
*/
public void updateTopologyVersion(
@@ -193,17 +196,27 @@ public interface GridDhtPartitionTopology {
/**
* @param exchId Exchange ID.
* @param partMap Update partition map.
+ * @param cntrMap Partition update counters.
* @return Local partition map if there were evictions or {@code null} otherwise.
*/
- public GridDhtPartitionMap update(@Nullable GridDhtPartitionExchangeId exchId, GridDhtPartitionFullMap partMap);
+ public GridDhtPartitionMap update(@Nullable GridDhtPartitionExchangeId exchId,
+ GridDhtPartitionFullMap partMap,
+ @Nullable Map<Integer, Long> cntrMap);
/**
* @param exchId Exchange ID.
* @param parts Partitions.
+ * @param cntrMap Partition update counters.
* @return Local partition map if there were evictions or {@code null} otherwise.
*/
@Nullable public GridDhtPartitionMap update(@Nullable GridDhtPartitionExchangeId exchId,
- GridDhtPartitionMap parts);
+ GridDhtPartitionMap parts,
+ @Nullable Map<Integer, Long> cntrMap);
+
+ /**
+ * @return Partition update counters.
+ */
+ public Map<Integer, Long> updateCounters();
/**
* @param part Partition to own.
@@ -213,6 +226,7 @@ public interface GridDhtPartitionTopology {
/**
* @param part Evicted partition.
+ * @param updateSeq Update sequence increment flag.
*/
public void onEvicted(GridDhtLocalPartition part, boolean updateSeq);
@@ -228,4 +242,10 @@ public interface GridDhtPartitionTopology {
* @param threshold Threshold for number of entries.
*/
public void printMemoryStats(int threshold);
-}
\ No newline at end of file
+
+ /**
+ * @param topVer Topology version.
+ * @return {@code True} if rebalance process finished.
+ */
+ public boolean rebalanceFinished(AffinityTopologyVersion topVer);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
index 6bd283a..39c55db 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
@@ -102,6 +102,12 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
/** Lock. */
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+ /** Partition update counter. */
+ private Map<Integer, Long> cntrMap = new HashMap<>();
+
+ /** */
+ private volatile AffinityTopologyVersion rebalancedTopVer = AffinityTopologyVersion.NONE;
+
/**
* @param cctx Context.
*/
@@ -131,6 +137,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
topReadyFut = null;
topVer = AffinityTopologyVersion.NONE;
+
+ rebalancedTopVer = AffinityTopologyVersion.NONE;
}
finally {
lock.writeLock().unlock();
@@ -220,6 +228,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
updateSeq.setIfGreater(updSeq);
topReadyFut = exchFut;
+
+ rebalancedTopVer = AffinityTopologyVersion.NONE;
}
finally {
lock.writeLock().unlock();
@@ -292,6 +302,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
long updateSeq = this.updateSeq.incrementAndGet();
+ cntrMap.clear();
+
// If this is the oldest node.
if (oldest.id().equals(loc.id()) || exchFut.isCacheAdded(cctx.cacheId(), exchId.topologyVersion())) {
if (node2part == null) {
@@ -525,6 +537,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
}
}
+ updateRebalanceVersion();
+
consistencyCheck();
}
finally {
@@ -732,7 +746,10 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
* @param states Additional partition states.
* @return List of nodes for the partition.
*/
- private List<ClusterNode> nodes(int p, AffinityTopologyVersion topVer, GridDhtPartitionState state, GridDhtPartitionState... states) {
+ private List<ClusterNode> nodes(int p,
+ AffinityTopologyVersion topVer,
+ GridDhtPartitionState state,
+ GridDhtPartitionState... states) {
Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(CU.affinityNodes(cctx, topVer)) : null;
lock.readLock().lock();
@@ -831,7 +848,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
/** {@inheritDoc} */
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
@Nullable @Override public GridDhtPartitionMap update(@Nullable GridDhtPartitionExchangeId exchId,
- GridDhtPartitionFullMap partMap) {
+ GridDhtPartitionFullMap partMap,
+ @Nullable Map<Integer, Long> cntrMap) {
if (log.isDebugEnabled())
log.debug("Updating full partition map [exchId=" + exchId + ", parts=" + fullMapString() + ']');
@@ -843,6 +861,22 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (stopping)
return null;
+ if (cntrMap != null) {
+ for (Map.Entry<Integer, Long> e : cntrMap.entrySet()) {
+ Long cntr = this.cntrMap.get(e.getKey());
+
+ if (cntr == null || cntr < e.getValue())
+ this.cntrMap.put(e.getKey(), e.getValue());
+ }
+
+ for (GridDhtLocalPartition part : locParts.values()) {
+ Long cntr = cntrMap.get(part.id());
+
+ if (cntr != null)
+ part.updateCounter(cntr);
+ }
+ }
+
if (exchId != null && lastExchangeId != null && lastExchangeId.compareTo(exchId) >= 0) {
if (log.isDebugEnabled())
log.debug("Stale exchange id for full partition map update (will ignore) [lastExchId=" +
@@ -913,6 +947,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
boolean changed = checkEvictions(updateSeq);
+ updateRebalanceVersion();
+
consistencyCheck();
if (log.isDebugEnabled())
@@ -928,7 +964,7 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
/** {@inheritDoc} */
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
@Nullable @Override public GridDhtPartitionMap update(@Nullable GridDhtPartitionExchangeId exchId,
- GridDhtPartitionMap parts) {
+ GridDhtPartitionMap parts, @Nullable Map<Integer, Long> cntrMap) {
if (log.isDebugEnabled())
log.debug("Updating single partition map [exchId=" + exchId + ", parts=" + mapString(parts) + ']');
@@ -946,6 +982,22 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (stopping)
return null;
+ if (cntrMap != null) {
+ for (Map.Entry<Integer, Long> e : cntrMap.entrySet()) {
+ Long cntr = this.cntrMap.get(e.getKey());
+
+ if (cntr == null || cntr < e.getValue())
+ this.cntrMap.put(e.getKey(), e.getValue());
+ }
+
+ for (GridDhtLocalPartition part : locParts.values()) {
+ Long cntr = cntrMap.get(part.id());
+
+ if (cntr != null)
+ part.updateCounter(cntr);
+ }
+ }
+
if (lastExchangeId != null && exchId != null && lastExchangeId.compareTo(exchId) > 0) {
if (log.isDebugEnabled())
log.debug("Stale exchange id for single partition map update (will ignore) [lastExchId=" +
@@ -1008,6 +1060,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
changed |= checkEvictions(updateSeq);
+ updateRebalanceVersion();
+
consistencyCheck();
if (log.isDebugEnabled())
@@ -1254,6 +1308,33 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
}
/** {@inheritDoc} */
+ @Override public Map<Integer, Long> updateCounters() {
+ lock.readLock().lock();
+
+ try {
+ Map<Integer, Long> res = new HashMap<>(cntrMap);
+
+ for (GridDhtLocalPartition part : locParts.values()) {
+ Long cntr0 = res.get(part.id());
+ Long cntr1 = part.updateCounter();
+
+ if (cntr0 == null || cntr1 > cntr0)
+ res.put(part.id(), cntr1);
+ }
+
+ return res;
+ }
+ finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean rebalanceFinished(AffinityTopologyVersion topVer) {
+ return topVer.equals(rebalancedTopVer);
+ }
+
+ /** {@inheritDoc} */
@Override public void printMemoryStats(int threshold) {
X.println(">>> Cache partition topology stats [grid=" + cctx.gridName() + ", cache=" + cctx.name() + ']');
@@ -1266,6 +1347,31 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
}
/**
+ *
+ */
+ private void updateRebalanceVersion() {
+ if (!rebalancedTopVer.equals(topVer)) {
+ for (int i = 0; i < cctx.affinity().partitions(); i++) {
+ List<ClusterNode> affNodes = cctx.affinity().nodes(i, topVer);
+
+ // Topology doesn't contain server nodes (just clients).
+ if (affNodes.isEmpty() || (node2part != null && !node2part.valid()))
+ continue;
+
+ List<ClusterNode> owners = owners(i);
+
+ if (affNodes.size() != owners.size() || !owners.containsAll(affNodes))
+ return;
+ }
+
+ rebalancedTopVer = topVer;
+
+ if (log.isDebugEnabled())
+ log.debug("Updated rebalanced version [cache=" + cctx.name() + ", ver=" + rebalancedTopVer + ']');
+ }
+ }
+
+ /**
* @param p Partition.
* @param nodeId Node ID.
* @param match State to match.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
index bb370a5..e8ef5d4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
@@ -17,9 +17,9 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.IgniteCheckedException;
@@ -31,7 +31,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheFuture;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
-import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
@@ -42,9 +42,7 @@ import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.F;
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.jetbrains.annotations.Nullable;
import static org.apache.ignite.transactions.TransactionState.COMMITTING;
@@ -356,6 +354,11 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
add(fut); // Append new future.
+ Collection<Long> updCntrs = new ArrayList<>(dhtMapping.entries().size());
+
+ for (IgniteTxEntry e : dhtMapping.entries())
+ updCntrs.add(e.updateCounter());
+
GridDhtTxFinishRequest req = new GridDhtTxFinishRequest(
tx.nearNodeId(),
futId,
@@ -379,7 +382,8 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
tx.size(),
tx.subjectId(),
tx.taskNameHash(),
- tx.activeCachesDeploymentEnabled());
+ tx.activeCachesDeploymentEnabled(),
+ updCntrs);
req.writeVersion(tx.writeVersion() != null ? tx.writeVersion() : tx.xidVersion());
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
index caa0aa5..65f1cb4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
@@ -26,6 +26,7 @@ import org.apache.ignite.internal.GridDirectCollection;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxFinishRequest;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteUuid;
@@ -66,6 +67,11 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
/** Check comitted flag. */
private boolean checkCommitted;
+ /** Partition update counter. */
+ @GridToStringInclude
+ @GridDirectCollection(Long.class)
+ private GridLongList partUpdateCnt;
+
/** One phase commit write version. */
private GridCacheVersion writeVer;
@@ -163,6 +169,76 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
}
/**
+ * @param nearNodeId Near node ID.
+ * @param futId Future ID.
+ * @param miniId Mini future ID.
+ * @param topVer Topology version.
+ * @param xidVer Transaction ID.
+ * @param threadId Thread ID.
+ * @param commitVer Commit version.
+ * @param isolation Transaction isolation.
+ * @param commit Commit flag.
+ * @param invalidate Invalidate flag.
+ * @param sys System flag.
+ * @param sysInvalidate System invalidation flag.
+ * @param syncCommit Synchronous commit flag.
+ * @param syncRollback Synchronous rollback flag.
+ * @param baseVer Base version.
+ * @param committedVers Committed versions.
+ * @param rolledbackVers Rolled back versions.
+ * @param pendingVers Pending versions.
+ * @param txSize Expected transaction size.
+ * @param subjId Subject ID.
+ * @param taskNameHash Task name hash.
+ * @param updateIdxs Partition update idxs.
+ * @param addDepInfo Deployment info flag.
+ */
+ public GridDhtTxFinishRequest(
+ UUID nearNodeId,
+ IgniteUuid futId,
+ IgniteUuid miniId,
+ @NotNull AffinityTopologyVersion topVer,
+ GridCacheVersion xidVer,
+ GridCacheVersion commitVer,
+ long threadId,
+ TransactionIsolation isolation,
+ boolean commit,
+ boolean invalidate,
+ boolean sys,
+ byte plc,
+ boolean sysInvalidate,
+ boolean syncCommit,
+ boolean syncRollback,
+ GridCacheVersion baseVer,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers,
+ Collection<GridCacheVersion> pendingVers,
+ int txSize,
+ @Nullable UUID subjId,
+ int taskNameHash,
+ boolean addDepInfo,
+ Collection<Long> updateIdxs
+ ) {
+ this(nearNodeId, futId, miniId, topVer, xidVer, commitVer, threadId, isolation, commit, invalidate, sys, plc,
+ sysInvalidate, syncCommit, syncRollback, baseVer, committedVers, rolledbackVers, pendingVers, txSize,
+ subjId, taskNameHash, addDepInfo);
+
+ if (updateIdxs != null && !updateIdxs.isEmpty()) {
+ partUpdateCnt = new GridLongList(updateIdxs.size());
+
+ for (Long idx : updateIdxs)
+ partUpdateCnt.add(idx);
+ }
+ }
+
+ /**
+ * @return Partition update counters.
+ */
+ public GridLongList partUpdateCounters(){
+ return partUpdateCnt;
+ }
+
+ /**
* @return Mini ID.
*/
public IgniteUuid miniId() {
@@ -294,36 +370,42 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
writer.incrementState();
case 22:
- if (!writer.writeCollection("pendingVers", pendingVers, MessageCollectionItemType.MSG))
+ if (!writer.writeMessage("partUpdateCnt", partUpdateCnt))
return false;
writer.incrementState();
case 23:
- if (!writer.writeUuid("subjId", subjId))
+ if (!writer.writeCollection("pendingVers", pendingVers, MessageCollectionItemType.MSG))
return false;
writer.incrementState();
case 24:
- if (!writer.writeBoolean("sysInvalidate", sysInvalidate))
+ if (!writer.writeUuid("subjId", subjId))
return false;
writer.incrementState();
case 25:
- if (!writer.writeInt("taskNameHash", taskNameHash))
+ if (!writer.writeBoolean("sysInvalidate", sysInvalidate))
return false;
writer.incrementState();
case 26:
- if (!writer.writeMessage("topVer", topVer))
+ if (!writer.writeInt("taskNameHash", taskNameHash))
return false;
writer.incrementState();
case 27:
+ if (!writer.writeMessage("topVer", topVer))
+ return false;
+
+ writer.incrementState();
+
+ case 28:
if (!writer.writeMessage("writeVer", writeVer))
return false;
@@ -382,7 +464,7 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
reader.incrementState();
case 22:
- pendingVers = reader.readCollection("pendingVers", MessageCollectionItemType.MSG);
+ partUpdateCnt = reader.readMessage("partUpdateCnt");
if (!reader.isLastRead())
return false;
@@ -390,7 +472,7 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
reader.incrementState();
case 23:
- subjId = reader.readUuid("subjId");
+ pendingVers = reader.readCollection("pendingVers", MessageCollectionItemType.MSG);
if (!reader.isLastRead())
return false;
@@ -398,7 +480,7 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
reader.incrementState();
case 24:
- sysInvalidate = reader.readBoolean("sysInvalidate");
+ subjId = reader.readUuid("subjId");
if (!reader.isLastRead())
return false;
@@ -406,7 +488,7 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
reader.incrementState();
case 25:
- taskNameHash = reader.readInt("taskNameHash");
+ sysInvalidate = reader.readBoolean("sysInvalidate");
if (!reader.isLastRead())
return false;
@@ -414,7 +496,7 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
reader.incrementState();
case 26:
- topVer = reader.readMessage("topVer");
+ taskNameHash = reader.readInt("taskNameHash");
if (!reader.isLastRead())
return false;
@@ -422,6 +504,14 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
reader.incrementState();
case 27:
+ topVer = reader.readMessage("topVer");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 28:
writeVer = reader.readMessage("writeVer");
if (!reader.isLastRead())
@@ -441,6 +531,6 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 28;
+ return 29;
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/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 75f8c2f..3ee1048 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
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheA
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
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.distributed.dht.GridDhtPartitionTopology;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader;
@@ -1204,7 +1205,9 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
Collection<IgniteBiTuple<GridDhtCacheEntry, GridCacheVersion>> deleted = null;
try {
- topology().readLock();
+ GridDhtPartitionTopology top = topology();
+
+ top.readLock();
try {
if (topology().stopping()) {
@@ -1221,7 +1224,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
// Also do not check topology version if topology was locked on near node by
// external transaction or explicit lock.
if ((req.fastMap() && !req.clientRequest()) || req.topologyLocked() ||
- !needRemap(req.topologyVersion(), topology().topologyVersion())) {
+ !needRemap(req.topologyVersion(), top.topologyVersion())) {
ClusterNode node = ctx.discovery().node(nodeId);
if (node == null) {
@@ -1236,7 +1239,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
if (ver == null) {
// Assign next version for update inside entries lock.
- ver = ctx.versions().next(topology().topologyVersion());
+ ver = ctx.versions().next(top.topologyVersion());
if (hasNear)
res.nearVersion(ver);
@@ -1248,6 +1251,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
log.debug("Using cache version for update request on primary node [ver=" + ver +
", req=" + req + ']');
+ boolean sndPrevVal = !top.rebalanceFinished(req.topologyVersion());
+
dhtFut = createDhtFuture(ver, req, res, completionCb, false);
expiry = expiryPolicy(req.expiry());
@@ -1270,7 +1275,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
completionCb,
ctx.isDrEnabled(),
taskName,
- expiry);
+ expiry,
+ sndPrevVal);
deleted = updRes.deleted();
dhtFut = updRes.dhtFuture();
@@ -1289,7 +1295,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
completionCb,
ctx.isDrEnabled(),
taskName,
- expiry);
+ expiry,
+ sndPrevVal);
retVal = updRes.returnValue();
deleted = updRes.deleted();
@@ -1309,7 +1316,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
remap = true;
}
finally {
- topology().readUnlock();
+ top.readUnlock();
}
}
catch (GridCacheEntryRemovedException e) {
@@ -1384,6 +1391,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
* @param replicate Whether replication is enabled.
* @param taskName Task name.
* @param expiry Expiry policy.
+ * @param sndPrevVal If {@code true} sends previous value to backups.
* @return Deleted entries.
* @throws GridCacheEntryRemovedException Should not be thrown.
*/
@@ -1399,7 +1407,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
CI2<GridNearAtomicUpdateRequest, GridNearAtomicUpdateResponse> completionCb,
boolean replicate,
String taskName,
- @Nullable IgniteCacheExpiryPolicy expiry
+ @Nullable IgniteCacheExpiryPolicy expiry,
+ boolean sndPrevVal
) throws GridCacheEntryRemovedException {
assert !ctx.dr().receiveEnabled(); // Cannot update in batches during DR due to possible conflicts.
assert !req.returnValue() || req.operation() == TRANSFORM; // Should not request return values for putAll.
@@ -1546,7 +1555,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
replicate,
updRes,
taskName,
- expiry);
+ expiry,
+ sndPrevVal);
firstEntryIdx = i;
@@ -1594,7 +1604,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
replicate,
updRes,
taskName,
- expiry);
+ expiry,
+ sndPrevVal);
firstEntryIdx = i;
@@ -1713,7 +1724,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
replicate,
updRes,
taskName,
- expiry);
+ expiry,
+ sndPrevVal);
}
else
assert filtered.isEmpty();
@@ -1790,6 +1802,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
* @param replicate Whether DR is enabled for that cache.
* @param taskName Task name.
* @param expiry Expiry policy.
+ * @param sndPrevVal If {@code true} sends previous value to backups.
* @return Return value.
* @throws GridCacheEntryRemovedException Should be never thrown.
*/
@@ -1804,7 +1817,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
CI2<GridNearAtomicUpdateRequest, GridNearAtomicUpdateResponse> completionCb,
boolean replicate,
String taskName,
- @Nullable IgniteCacheExpiryPolicy expiry
+ @Nullable IgniteCacheExpiryPolicy expiry,
+ boolean sndPrevVal
) throws GridCacheEntryRemovedException {
GridCacheReturn retVal = null;
Collection<IgniteBiTuple<GridDhtCacheEntry, GridCacheVersion>> deleted = null;
@@ -1861,7 +1875,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
req.invokeArguments(),
primary && writeThrough() && !req.skipStore(),
!req.skipStore(),
- req.returnValue(),
+ sndPrevVal || req.returnValue(),
expiry,
true,
true,
@@ -1876,7 +1890,9 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
true,
intercept,
req.subjectId(),
- taskName);
+ taskName,
+ null,
+ null);
if (dhtFut == null && !F.isEmpty(filteredReaders)) {
dhtFut = createDhtFuture(ver, req, res, completionCb, true);
@@ -1901,7 +1917,10 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
entryProcessor,
updRes.newTtl(),
updRes.conflictExpireTime(),
- newConflictVer);
+ newConflictVer,
+ sndPrevVal,
+ updRes.oldValue(),
+ updRes.updateCounter());
}
if (!F.isEmpty(filteredReaders))
@@ -1918,6 +1937,11 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
"[entry=" + entry + ", filter=" + Arrays.toString(req.filter()) + ']');
}
}
+ else if (!entry.isNear() && updRes.success()) {
+ ctx.continuousQueries().onEntryUpdated(entry.key(), updRes.newValue(), updRes.oldValue(),
+ entry.isInternal() || !context().userCache(), entry.partition(), primary, false,
+ updRes.updateCounter(), topVer);
+ }
if (hasNear) {
if (primary && updRes.sendToDht()) {
@@ -2008,6 +2032,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
* @param batchRes Batch update result.
* @param taskName Task name.
* @param expiry Expiry policy.
+ * @param sndPrevVal If {@code true} sends previous value to backups.
* @return Deleted entries.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
@@ -2028,7 +2053,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
boolean replicate,
UpdateBatchResult batchRes,
String taskName,
- @Nullable IgniteCacheExpiryPolicy expiry
+ @Nullable IgniteCacheExpiryPolicy expiry,
+ boolean sndPrevVal
) {
assert putMap == null ^ rmvKeys == null;
@@ -2130,7 +2156,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
null,
/*write-through*/false,
/*read-through*/false,
- /*retval*/false,
+ /*retval*/sndPrevVal,
expiry,
/*event*/true,
/*metrics*/true,
@@ -2145,7 +2171,9 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
/*conflict resolve*/false,
/*intercept*/false,
req.subjectId(),
- taskName);
+ taskName,
+ null,
+ null);
assert !updRes.success() || updRes.newTtl() == CU.TTL_NOT_CHANGED || expiry != null :
"success=" + updRes.success() + ", newTtl=" + updRes.newTtl() + ", expiry=" + expiry;
@@ -2184,7 +2212,10 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
entryProcessor,
updRes.newTtl(),
CU.EXPIRE_TIME_CALCULATE,
- null);
+ null,
+ sndPrevVal,
+ updRes.oldValue(),
+ updRes.updateCounter());
if (!F.isEmpty(filteredReaders))
dhtFut.addNearWriteEntries(filteredReaders,
@@ -2573,7 +2604,10 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
entry = entryExx(key);
CacheObject val = req.value(i);
+ CacheObject prevVal = req.previousValue(i);
+
EntryProcessor<Object, Object, Object> entryProcessor = req.entryProcessor(i);
+ Long updateIdx = req.updateCounter(i);
GridCacheOperation op = entryProcessor != null ? TRANSFORM :
(val != null) ? UPDATE : DELETE;
@@ -2605,11 +2639,18 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
false,
intercept,
req.subjectId(),
- taskName);
+ taskName,
+ prevVal,
+ updateIdx);
if (updRes.removeVersion() != null)
ctx.onDeferredDelete(entry, updRes.removeVersion());
+ if (updRes.success() && !entry.isNear())
+ ctx.continuousQueries().onEntryUpdated(entry.key(), updRes.newValue(),
+ updRes.oldValue(), entry.isInternal() || !context().userCache(), entry.partition(),
+ false, false, updRes.updateCounter(), req.topologyVersion());
+
entry.onUnlock();
break; // While.
http://git-wip-us.apache.org/repos/asf/ignite/blob/ce636372/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
index c34dcfd..c73b3b7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
@@ -215,13 +215,17 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
* @param ttl TTL (optional).
* @param conflictExpireTime Conflict expire time (optional).
* @param conflictVer Conflict version (optional).
+ * @param updateCntr Partition update counter.
*/
public void addWriteEntry(GridDhtCacheEntry entry,
@Nullable CacheObject val,
EntryProcessor<Object, Object, Object> entryProcessor,
long ttl,
long conflictExpireTime,
- @Nullable GridCacheVersion conflictVer) {
+ @Nullable GridCacheVersion conflictVer,
+ boolean addPrevVal,
+ @Nullable CacheObject prevVal,
+ @Nullable Long updateCntr) {
AffinityTopologyVersion topVer = updateReq.topologyVersion();
Collection<ClusterNode> dhtNodes = cctx.dht().topology().nodes(entry.partition(), topVer);
@@ -261,7 +265,22 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
entryProcessor,
ttl,
conflictExpireTime,
- conflictVer);
+ conflictVer,
+ addPrevVal,
+ entry.partition(),
+ prevVal,
+ updateCntr);
+ }
+ else if (dhtNodes.size() == 1) {
+ try {
+ cctx.continuousQueries().onEntryUpdated(entry.key(), val, prevVal,
+ entry.key().internal() || !cctx.userCache(), entry.partition(), true, false,
+ updateCntr, updateReq.topologyVersion());
+ }
+ catch (IgniteCheckedException e) {
+ U.warn(log, "Failed to send continuous query message. [key=" + entry.key() + ", newVal="
+ + val + ", err=" + e + "]");
+ }
}
}
}
@@ -331,8 +350,56 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
cctx.mvcc().removeAtomicFuture(version());
if (err != null) {
- for (KeyCacheObject key : keys)
- updateRes.addFailedKey(key, err);
+ if (!mappings.isEmpty()) {
+ Collection<KeyCacheObject> hndKeys = new ArrayList<>(keys.size());
+
+ exit: for (GridDhtAtomicUpdateRequest req : mappings.values()) {
+ for (int i = 0; i < req.size(); i++) {
+ KeyCacheObject key = req.key(i);
+
+ if (!hndKeys.contains(key)) {
+ updateRes.addFailedKey(key, err);
+
+ cctx.continuousQueries().skipUpdateEvent(key, req.partitionId(i), req.updateCounter(i),
+ updateReq.topologyVersion());
+
+ hndKeys.add(key);
+
+ if (hndKeys.size() == keys.size())
+ break exit;
+ }
+ }
+ }
+ }
+ else
+ for (KeyCacheObject key : keys)
+ updateRes.addFailedKey(key, err);
+ }
+ else {
+ Collection<KeyCacheObject> hndKeys = new ArrayList<>(keys.size());
+
+ exit: for (GridDhtAtomicUpdateRequest req : mappings.values()) {
+ for (int i = 0; i < req.size(); i++) {
+ KeyCacheObject key = req.key(i);
+
+ if (!hndKeys.contains(key)) {
+ try {
+ cctx.continuousQueries().onEntryUpdated(key, req.value(i), req.localPreviousValue(i),
+ key.internal() || !cctx.userCache(), req.partitionId(i), true, false,
+ req.updateCounter(i), updateReq.topologyVersion());
+ }
+ catch (IgniteCheckedException e) {
+ U.warn(log, "Failed to send continuous query message. [key=" + key + ", newVal="
+ + req.value(i) + ", err=" + e + "]");
+ }
+
+ hndKeys.add(key);
+
+ if (hndKeys.size() == keys.size())
+ break exit;
+ }
+ }
+ }
}
if (updateReq.writeSynchronizationMode() == FULL_SYNC)