blob: 30efc103ab4bc173df3374c12ad46d454b43c75c [file] [log] [blame]
/*
* 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.IgniteCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxQueryEnlistResponse;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxQueryResultsEnlistResponse;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.lang.GridClosureException;
import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteUuid;
import org.jetbrains.annotations.NotNull;
/**
*
*/
public final class NearTxQueryEnlistResultHandler implements CI1<IgniteInternalFuture<Long>> {
/** */
private static final long serialVersionUID = 5189735824793607906L;
/** */
private static final NearTxQueryEnlistResultHandler INSTANCE = new NearTxQueryEnlistResultHandler();
/** */
private NearTxQueryEnlistResultHandler() {}
/**
* @return Handler instance.
*/
public static NearTxQueryEnlistResultHandler instance() {
return INSTANCE;
}
/**
* @param future Enlist future.
* @return Enlist response.
*/
public static <T extends GridNearTxQueryEnlistResponse> T createResponse(IgniteInternalFuture<?> future) {
assert future != null;
Class<?> clazz = future.getClass();
if (clazz == GridDhtTxQueryResultsEnlistFuture.class)
return (T)createResponse((GridDhtTxQueryResultsEnlistFuture)future);
else if (clazz == GridDhtTxQueryEnlistFuture.class)
return (T)createResponse((GridDhtTxQueryEnlistFuture)future);
else
throw new IllegalStateException();
}
/**
* @param future Enlist future.
* @return Enlist response.
*/
@NotNull private static GridNearTxQueryEnlistResponse createResponse(GridDhtTxQueryEnlistFuture future) {
try {
future.get();
assert future.tx.queryEnlisted() || future.cnt == 0;
return new GridNearTxQueryEnlistResponse(future.cctx.cacheId(), future.nearFutId, future.nearMiniId,
future.nearLockVer, future.cnt, future.tx.empty() && !future.tx.queryEnlisted(), future.newDhtNodes);
}
catch (IgniteCheckedException e) {
return new GridNearTxQueryEnlistResponse(future.cctx.cacheId(), future.nearFutId, future.nearMiniId, future.nearLockVer, e);
}
}
/**
* @param fut Enlist future.
* @return Enlist response.
*/
@NotNull private static GridNearTxQueryResultsEnlistResponse createResponse(GridDhtTxQueryResultsEnlistFuture fut) {
try {
fut.get();
GridCacheVersion ver = null;
IgniteUuid id = null;
if (fut.hasNearNodeUpdates) {
ver = fut.cctx.tm().mappedVersion(fut.nearLockVer);
id = fut.futId;
}
return new GridNearTxQueryResultsEnlistResponse(fut.cctx.cacheId(), fut.nearFutId, fut.nearMiniId,
fut.nearLockVer, fut.cnt, ver, id, fut.newDhtNodes);
}
catch (IgniteCheckedException e) {
return new GridNearTxQueryResultsEnlistResponse(fut.cctx.cacheId(), fut.nearFutId, fut.nearMiniId,
fut.nearLockVer, e);
}
}
/** {@inheritDoc} */
@Override public void apply(IgniteInternalFuture<Long> fut0) {
GridDhtTxAbstractEnlistFuture fut = (GridDhtTxAbstractEnlistFuture)fut0;
GridCacheContext<?, ?> cctx = fut.cctx;
GridDhtTxLocal tx = (GridDhtTxLocal)fut.tx;
UUID nearNodeId = fut.nearNodeId;
GridNearTxQueryEnlistResponse res = createResponse(fut);
if (res.removeMapping()) {
cctx.tm().forgetTx(tx);
try {
cctx.io().send(nearNodeId, res, cctx.ioPolicy());
}
catch (IgniteCheckedException e) {
U.error(fut.log, "Failed to send near enlist response [" +
"tx=" + CU.txString(tx) +
", node=" + nearNodeId +
", res=" + res + ']', e);
throw new GridClosureException(e);
}
return;
}
try {
cctx.io().send(nearNodeId, res, cctx.ioPolicy());
}
catch (IgniteCheckedException e) {
U.error(fut.log, "Failed to send near enlist response (will rollback transaction) [" +
"tx=" + CU.txString(tx) +
", node=" + nearNodeId +
", res=" + res + ']', e);
try {
tx.rollbackDhtLocalAsync();
}
catch (Throwable e1) {
e.addSuppressed(e1);
}
throw new GridClosureException(e);
}
}
}