use of org.apache.geode.internal.cache.tier.sockets.MessageTooLargeException in project geode by apache.
the class GatewaySenderEventRemoteDispatcher method _dispatchBatch.
private boolean _dispatchBatch(List events, boolean isRetry) {
Exception ex = null;
int currentBatchId = this.processor.getBatchId();
connection = getConnection(true);
int batchIdForThisConnection = this.processor.getBatchId();
GatewaySenderStats statistics = this.sender.getStatistics();
// i.e The connection has been reset. It also resets the batchId.
if (currentBatchId != batchIdForThisConnection || this.processor.isConnectionReset()) {
return false;
}
try {
if (this.processor.isConnectionReset()) {
isRetry = true;
}
SenderProxy sp = new SenderProxy(this.sender.getProxy());
this.connectionLifeCycleLock.readLock().lock();
try {
if (connection != null) {
sp.dispatchBatch_NewWAN(connection, events, currentBatchId, sender.isRemoveFromQueueOnException(), isRetry);
if (logger.isDebugEnabled()) {
logger.debug("{} : Dispatched batch (id={}) of {} events, queue size: {} on connection {}", this.processor.getSender(), currentBatchId, events.size(), this.processor.getQueue().size(), connection);
}
} else {
throw new ConnectionDestroyedException();
}
} finally {
this.connectionLifeCycleLock.readLock().unlock();
}
return true;
} catch (ServerOperationException e) {
Throwable t = e.getCause();
if (t instanceof BatchException70) {
// A BatchException has occurred.
// Do not process the connection as dead since it is not dead.
ex = (BatchException70) t;
} else {
ex = e;
// keep using the connection if we had a batch exception. Else, destroy it
destroyConnection();
}
throw new GatewaySenderException(LocalizedStrings.GatewayEventRemoteDispatcher_0_EXCEPTION_DURING_PROCESSING_BATCH_1_ON_CONNECTION_2.toLocalizedString(new Object[] { this, Integer.valueOf(currentBatchId), connection }), ex);
} catch (GemFireIOException e) {
Throwable t = e.getCause();
if (t instanceof MessageTooLargeException) {
// A MessageTooLargeException has occurred.
// Do not process the connection as dead since it is not dead.
ex = (MessageTooLargeException) t;
// Reduce the batch size by half of the configured batch size or number of events in the
// current batch (whichever is less)
int newBatchSize = Math.min(events.size(), this.processor.getBatchSize()) / 2;
logger.warn(LocalizedMessage.create(LocalizedStrings.GatewaySenderEventRemoteDispatcher_MESSAGE_TOO_LARGE_EXCEPTION, new Object[] { events.size(), newBatchSize }), e);
this.processor.setBatchSize(newBatchSize);
statistics.incBatchesResized();
} else {
ex = e;
// keep using the connection if we had a MessageTooLargeException. Else, destroy it
destroyConnection();
}
throw new GatewaySenderException(LocalizedStrings.GatewayEventRemoteDispatcher_0_EXCEPTION_DURING_PROCESSING_BATCH_1_ON_CONNECTION_2.toLocalizedString(new Object[] { this, Integer.valueOf(currentBatchId), connection }), ex);
} catch (IllegalStateException e) {
this.processor.setException(new GatewaySenderException(e));
throw new GatewaySenderException(LocalizedStrings.GatewayEventRemoteDispatcher_0_EXCEPTION_DURING_PROCESSING_BATCH_1_ON_CONNECTION_2.toLocalizedString(new Object[] { this, Integer.valueOf(currentBatchId), connection }), e);
} catch (Exception e) {
// An Exception has occurred. Get its cause.
Throwable t = e.getCause();
if (t instanceof IOException) {
// An IOException has occurred.
ex = (IOException) t;
} else {
ex = e;
}
// the cause is not going to be BatchException70. So, destroy the connection
destroyConnection();
throw new GatewaySenderException(LocalizedStrings.GatewayEventRemoteDispatcher_0_EXCEPTION_DURING_PROCESSING_BATCH_1_ON_CONNECTION_2.toLocalizedString(new Object[] { this, Integer.valueOf(currentBatchId), connection }), ex);
}
}
use of org.apache.geode.internal.cache.tier.sockets.MessageTooLargeException in project geode by apache.
the class OpExecutorImpl method execute.
public Object execute(Op op, int retries) {
if (this.serverAffinity.get()) {
ServerLocation loc = this.affinityServerLocation.get();
if (loc == null) {
loc = getNextOpServerLocation();
this.affinityServerLocation.set(loc);
if (logger.isDebugEnabled()) {
logger.debug("setting server affinity to {}", this.affinityServerLocation.get());
}
}
return executeWithServerAffinity(loc, op);
}
boolean success = false;
Set attemptedServers = new HashSet();
Connection conn = (Connection) (threadLocalConnections ? localConnection.get() : null);
if (conn == null || conn.isDestroyed()) {
conn = connectionManager.borrowConnection(serverTimeout);
} else if (threadLocalConnections) {
// Fix for 43718. Clear the thread local connection
// while we're performing the op. It will be reset
// if the op succeeds.
localConnection.set(null);
try {
this.connectionManager.activate(conn);
} catch (ConnectionDestroyedException ex) {
conn = connectionManager.borrowConnection(serverTimeout);
}
}
try {
for (int attempt = 0; true; attempt++) {
// attempt's version stamp
if (attempt == 1 && (op instanceof AbstractOp)) {
AbstractOp absOp = (AbstractOp) op;
absOp.getMessage().setIsRetry();
}
try {
authenticateIfRequired(conn, op);
Object result = executeWithPossibleReAuthentication(conn, op);
success = true;
return result;
} catch (MessageTooLargeException e) {
throw new GemFireIOException("unable to transmit message to server", e);
} catch (Exception e) {
// This method will throw an exception if we need to stop
// It also unsets the threadlocal connection and notifies
// the connection manager if there are failures.
handleException(e, conn, attempt, attempt >= retries && retries != -1);
attemptedServers.add(conn.getServer());
try {
conn = connectionManager.exchangeConnection(conn, attemptedServers, serverTimeout);
} catch (NoAvailableServersException nse) {
// if retries is -1, don't try again after the last server has failed
if (retries == -1 || TRY_SERVERS_ONCE) {
handleException(e, conn, attempt, true);
} else {
// try one of the failed servers again, until we exceed the retry attempts.
attemptedServers.clear();
try {
conn = connectionManager.exchangeConnection(conn, attemptedServers, serverTimeout);
} catch (NoAvailableServersException nse2) {
handleException(e, conn, attempt, true);
}
}
}
}
}
} finally {
if (threadLocalConnections) {
this.connectionManager.passivate(conn, success);
// Fix for 43718. If the thread local was set to a different
// connection deeper in the call stack, return that connection
// and set our connection on the thread local.
Connection existingConnection = localConnection.get();
if (existingConnection != null && existingConnection != conn) {
connectionManager.returnConnection(existingConnection);
}
if (!conn.isDestroyed()) {
localConnection.set(conn);
} else {
localConnection.set(null);
}
} else {
connectionManager.returnConnection(conn);
}
}
}
use of org.apache.geode.internal.cache.tier.sockets.MessageTooLargeException in project geode by apache.
the class TXSynchronizationCommand method cmdExecute.
/*
* (non-Javadoc)
*
* @see
* org.apache.geode.internal.cache.tier.sockets.BaseCommand#cmdExecute(org.apache.geode.internal.
* cache.tier.sockets.Message, org.apache.geode.internal.cache.tier.sockets.ServerConnection,
* long)
*/
@Override
public void cmdExecute(final Message clientMessage, final ServerConnection serverConnection, long start) throws IOException, ClassNotFoundException, InterruptedException {
serverConnection.setAsTrue(REQUIRES_RESPONSE);
CompletionType type = CompletionType.values()[clientMessage.getPart(0).getInt()];
/* int txIdInt = */
// [bruce] not sure if we need to
clientMessage.getPart(1).getInt();
// transmit this
final Part statusPart;
if (type == CompletionType.AFTER_COMPLETION) {
statusPart = clientMessage.getPart(2);
} else {
statusPart = null;
}
final TXManagerImpl txMgr = (TXManagerImpl) serverConnection.getCache().getCacheTransactionManager();
final InternalDistributedMember member = (InternalDistributedMember) serverConnection.getProxyID().getDistributedMember();
// get the tx state without associating it with this thread. That's done later
final TXStateProxy txProxy = txMgr.masqueradeAs(clientMessage, member, true);
// releases them
if (txProxy != null) {
final boolean isDebugEnabled = logger.isDebugEnabled();
try {
if (type == CompletionType.BEFORE_COMPLETION) {
Runnable beforeCompletion = new Runnable() {
@SuppressWarnings("synthetic-access")
public void run() {
TXStateProxy txState = null;
Throwable failureException = null;
try {
txState = txMgr.masqueradeAs(clientMessage, member, false);
if (isDebugEnabled) {
logger.debug("Executing beforeCompletion() notification for transaction {}", clientMessage.getTransactionId());
}
txState.setIsJTA(true);
txState.beforeCompletion();
try {
writeReply(clientMessage, serverConnection);
} catch (IOException e) {
if (isDebugEnabled) {
logger.debug("Problem writing reply to client", e);
}
}
serverConnection.setAsTrue(RESPONDED);
} catch (ReplyException e) {
failureException = e.getCause();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
failureException = e;
} finally {
txMgr.unmasquerade(txState);
}
if (failureException != null) {
try {
writeException(clientMessage, failureException, false, serverConnection);
} catch (IOException ioe) {
if (isDebugEnabled) {
logger.debug("Problem writing reply to client", ioe);
}
}
serverConnection.setAsTrue(RESPONDED);
}
}
};
TXSynchronizationRunnable sync = new TXSynchronizationRunnable(beforeCompletion);
txProxy.setSynchronizationRunnable(sync);
Executor exec = InternalDistributedSystem.getConnectedInstance().getDistributionManager().getWaitingThreadPool();
exec.execute(sync);
sync.waitForFirstExecution();
} else {
Runnable afterCompletion = new Runnable() {
@SuppressWarnings("synthetic-access")
public void run() {
TXStateProxy txState = null;
try {
txState = txMgr.masqueradeAs(clientMessage, member, false);
int status = statusPart.getInt();
if (isDebugEnabled) {
logger.debug("Executing afterCompletion({}) notification for transaction {}", status, clientMessage.getTransactionId());
}
txState.setIsJTA(true);
txState.afterCompletion(status);
// GemFire commits during afterCompletion - send the commit info back to the client
// where it can be applied to the local cache
TXCommitMessage cmsg = txState.getCommitMessage();
try {
CommitCommand.writeCommitResponse(cmsg, clientMessage, serverConnection);
txMgr.removeHostedTXState(txState.getTxId());
} catch (IOException e) {
// not much can be done here
if (isDebugEnabled || (e instanceof MessageTooLargeException)) {
logger.warn("Problem writing reply to client", e);
}
}
serverConnection.setAsTrue(RESPONDED);
} catch (RuntimeException e) {
try {
writeException(clientMessage, e, false, serverConnection);
} catch (IOException ioe) {
if (isDebugEnabled) {
logger.debug("Problem writing reply to client", ioe);
}
}
serverConnection.setAsTrue(RESPONDED);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
txMgr.unmasquerade(txState);
}
}
};
// if there was a beforeCompletion call then there will be a thread
// sitting in the waiting pool to execute afterCompletion. Otherwise
// we have failed-over and may need to do beforeCompletion & hope that it works
TXSynchronizationRunnable sync = txProxy.getSynchronizationRunnable();
if (sync != null) {
sync.runSecondRunnable(afterCompletion);
} else {
if (statusPart.getInt() == Status.STATUS_COMMITTED) {
TXStateProxy txState = txMgr.masqueradeAs(clientMessage, member, false);
try {
if (isDebugEnabled) {
logger.debug("Executing beforeCompletion() notification for transaction {} after failover", clientMessage.getTransactionId());
}
txState.setIsJTA(true);
txState.beforeCompletion();
} finally {
txMgr.unmasquerade(txState);
}
}
afterCompletion.run();
}
}
} catch (Exception e) {
writeException(clientMessage, MessageType.EXCEPTION, e, false, serverConnection);
serverConnection.setAsTrue(RESPONDED);
}
if (isDebugEnabled) {
logger.debug("Sent tx synchronization response");
}
}
}
Aggregations