use of org.apache.geode.distributed.internal.ReplyException in project geode by apache.
the class DistributedRegionFunctionStreamingMessage method process.
@Override
protected void process(final DistributionManager dm) {
Throwable thr = null;
boolean sendReply = true;
DistributedRegion dr = null;
TXStateProxy tx = null;
try {
if (checkCacheClosing(dm) || checkDSClosing(dm)) {
thr = new CacheClosedException(LocalizedStrings.PartitionMessage_REMOTE_CACHE_IS_CLOSED_0.toLocalizedString(dm.getId()));
return;
}
dr = (DistributedRegion) GemFireCacheImpl.getInstance().getRegion(this.regionPath);
if (dr == null) {
// if the distributed system is disconnecting, don't send a reply saying
// the partitioned region can't be found (bug 36585)
thr = new ForceReattemptException(dm.getDistributionManagerId().toString() + ": could not find Distributed region " + regionPath);
// reply sent in finally block below
return;
}
thr = UNHANDLED_EXCEPTION;
tx = prepForTransaction();
// need to take care of
sendReply = operateOnDistributedRegion(dm, dr);
// it...
thr = null;
} catch (CancelException se) {
// bug 37026: this is too noisy...
// throw new CacheClosedException("remote system shutting down");
// thr = se; cache is closed, no point trying to send a reply
thr = null;
sendReply = false;
if (logger.isDebugEnabled()) {
logger.debug("shutdown caught, abandoning message: {}", se.getMessage(), se);
}
} catch (RegionDestroyedException rde) {
// region is also destroyed, who cares if we send it an exception
if (dr != null && dr.isClosed()) {
thr = new ForceReattemptException("Region is destroyed in " + dm.getDistributionManagerId(), rde);
}
} catch (VirtualMachineError err) {
SystemFailure.initiateFailure(err);
// now, so don't let this thread continue.
throw err;
} catch (Throwable t) {
logger.debug("{} exception occurred while processing message: {}", this, t.getMessage(), t);
// Whenever you catch Error or Throwable, you must also
// catch VirtualMachineError (see above). However, there is
// _still_ a possibility that you are dealing with a cascading
// error condition, so you also need to check to see if the JVM
// is still usable:
SystemFailure.checkFailure();
// log the exception at fine level if there is no reply to the message
thr = null;
if (sendReply && this.processorId != 0) {
if (!checkDSClosing(dm)) {
thr = t;
} else {
// don't pass arbitrary runtime exceptions and errors back if this
// cache/vm is closing
thr = new ForceReattemptException("Distributed system is disconnecting");
}
}
if (this.processorId == 0) {
logger.debug("{} exception while processing message: {}", this, t.getMessage(), t);
} else if (logger.isTraceEnabled(LogMarker.DM) && (t instanceof RuntimeException)) {
logger.trace(LogMarker.DM, "Exception caught while processing message", t);
}
} finally {
cleanupTransaction(tx);
if (sendReply && this.processorId != 0) {
ReplyException rex = null;
if (thr != null) {
// don't transmit the exception if this message was to a listener
// and this listener is shutting down
boolean excludeException = false;
if (!this.functionObject.isHA()) {
excludeException = (thr instanceof CacheClosedException || (thr instanceof ForceReattemptException));
} else {
excludeException = thr instanceof ForceReattemptException;
}
if (!excludeException) {
rex = new ReplyException(thr);
}
}
// Send the reply if the operateOnPartitionedRegion returned true
sendReply(getSender(), this.processorId, dm, rex, null, 0, true, false);
}
}
}
use of org.apache.geode.distributed.internal.ReplyException in project geode by apache.
the class RemoteRemoveAllMessage method operateOnRegion.
@Override
protected boolean operateOnRegion(DistributionManager dm, LocalRegion r, long startTime) throws RemoteOperationException {
final boolean sendReply;
InternalDistributedMember eventSender = getSender();
try {
sendReply = doLocalRemoveAll(r, eventSender);
} catch (RemoteOperationException e) {
sendReply(getSender(), getProcessorId(), dm, new ReplyException(e), r, startTime);
return false;
}
if (sendReply) {
sendReply(getSender(), getProcessorId(), dm, null, r, startTime);
}
return false;
}
use of org.apache.geode.distributed.internal.ReplyException in project geode by apache.
the class TXMessage method process.
@Override
protected void process(final DistributionManager dm) {
Throwable thr = null;
boolean sendReply = true;
try {
if (logger.isDebugEnabled()) {
logger.debug("processing {}", this);
}
InternalCache cache = GemFireCacheImpl.getInstance();
if (checkCacheClosing(cache) || checkDSClosing(cache.getInternalDistributedSystem())) {
thr = new CacheClosedException(LocalizedStrings.PartitionMessage_REMOTE_CACHE_IS_CLOSED_0.toLocalizedString(dm.getId()));
return;
}
TXManagerImpl txMgr = cache.getTXMgr();
TXStateProxy tx = null;
try {
assert this.txUniqId != TXManagerImpl.NOTX;
TXId txId = new TXId(getMemberToMasqueradeAs(), this.txUniqId);
tx = txMgr.masqueradeAs(this);
sendReply = operateOnTx(txId, dm);
} finally {
txMgr.unmasquerade(tx);
}
} catch (CommitConflictException cce) {
thr = cce;
} catch (DistributedSystemDisconnectedException se) {
sendReply = false;
if (logger.isDebugEnabled()) {
logger.debug("shutdown caught, abandoning message: " + se);
}
} catch (RegionDestroyedException rde) {
thr = new ForceReattemptException(LocalizedStrings.PartitionMessage_REGION_IS_DESTROYED_IN_0.toLocalizedString(dm.getDistributionManagerId()), rde);
} catch (VirtualMachineError err) {
SystemFailure.initiateFailure(err);
// now, so don't let this thread continue.
throw err;
} catch (Throwable t) {
// Whenever you catch Error or Throwable, you must also
// catch VirtualMachineError (see above). However, there is
// _still_ a possibility that you are dealing with a cascading
// error condition, so you also need to check to see if the JVM
// is still usable:
SystemFailure.checkFailure();
if (sendReply) {
thr = t;
}
} finally {
ReplySender rs = getReplySender(dm);
if (sendReply && (this.processorId != 0 || (rs != dm))) {
ReplyException rex = null;
if (thr != null) {
rex = new ReplyException(thr);
}
sendReply(getSender(), this.processorId, dm, rex);
}
}
}
use of org.apache.geode.distributed.internal.ReplyException in project geode by apache.
the class TXCommitMessage method memberDeparted.
public void memberDeparted(final InternalDistributedMember id, boolean crashed) {
if (!getSender().equals(id)) {
return;
}
this.dm.removeMembershipListener(this);
ThreadGroup group = LoggingThreadGroup.createThreadGroup("TXCommitMessage Threads", logger);
synchronized (this) {
if (isProcessing() || this.departureNoticed) {
if (logger.isDebugEnabled()) {
logger.debug("Member departed: Commit data is already being processed for lockid: {}", lockId);
}
return;
}
this.departureNoticed = true;
}
// determine if any one of them have received a CommitProcessMessage
if (this.farSiders != null && !this.farSiders.isEmpty()) {
if (logger.isDebugEnabled()) {
logger.debug("Member departed: {} sending query for CommitProcess message to other recipients.", id);
}
// Create a new thread, send the CommitProcessQuery, wait for a response and potentially
// process
Thread fellowFarSidersQuery = new Thread(group, "CommitProcessQuery Thread") {
// Should I use a thread pool?, Darrel suggests look in DM somewhere or introduce a zero
// sized thread pool
@Override
public void run() {
final TXCommitMessage mess = TXCommitMessage.this;
Object trackerKey = mess.getTrackerKey();
DistributedMember member = getMemberFromTrackerKey(trackerKey);
if (!mess.getSender().equals(member)) {
/*
* Do not send a CommitProcessQueryMessage when the sender of CommitMessage is not the
* member in the tracker key. (If this happens we are the redundant node for PR, and the
* primary just crashed).
*/
txTracker.removeMessage(mess);
return;
}
CommitProcessQueryReplyProcessor replProc = new CommitProcessQueryReplyProcessor(mess.dm, mess.farSiders);
CommitProcessQueryMessage query = new CommitProcessQueryMessage(mess.getTrackerKey(), replProc.getProcessorId());
query.setRecipients(mess.farSiders);
mess.dm.putOutgoing(query);
// Wait for any one positive response or all negative responses.
// (while() loop removed for bug 36983 - you can't loop on waitForReplies()
TXCommitMessage.this.dm.getCancelCriterion().checkCancelInProgress(null);
try {
replProc.waitForRepliesUninterruptibly();
} catch (ReplyException e) {
e.handleAsUnexpected();
}
if (replProc.receivedACommitProcessMessage()) {
if (logger.isDebugEnabled()) {
logger.debug("Transaction associated with lockID: {} from orign {} is processing due to a received \"commit process\" message", mess.lockId, id);
}
try {
// Set processor to zero to avoid the ack to the now departed origin
mess.processorId = 0;
mess.basicProcess();
} finally {
txTracker.processed(mess);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Transaction associated with lockID: {} from origin {} ignored. No other recipients received \"commit process\" message", mess.lockId, id);
}
txTracker.removeMessage(mess);
}
}
private DistributedMember getMemberFromTrackerKey(Object trackerKey) {
if (trackerKey instanceof TXId) {
TXId id1 = (TXId) trackerKey;
return id1.getMemberId();
} else if (trackerKey instanceof TXLockId) {
TXLockId id2 = (TXLockId) trackerKey;
return id2.getMemberId();
}
return null;
}
};
fellowFarSidersQuery.setDaemon(true);
fellowFarSidersQuery.start();
} else {
if (logger.isDebugEnabled()) {
logger.debug("Member departed: {}. Processing commit data.", getSender());
}
// Optimimal case where we are the only FarSider, assume we
// will never get the CommitProcess message, but it
// doesn't matter since we can commit anyway.
// Start a new thread to process the commit
Thread originDepartedCommit = new Thread(group, "Origin Departed Commit") {
@Override
public void run() {
final TXCommitMessage mess = TXCommitMessage.this;
try {
// Set processor to zero to avoid the ack to the now departed origin
mess.processorId = 0;
mess.basicProcess();
} finally {
txTracker.processed(mess);
}
}
};
originDepartedCommit.setDaemon(true);
originDepartedCommit.start();
}
}
use of org.apache.geode.distributed.internal.ReplyException in project geode by apache.
the class StateFlushOperation method flush.
/**
* flush state to the given target
*
* @param recipients The members who may be making state changes to the region. This is typically
* taken from a CacheDistributionAdvisor membership set
* @param target The member who should have all state flushed to it
* @param processorType The execution processor type for the marker message that is sent to all
* members using the given region
* @param flushNewOps normally only ops that were started before region profile exchange are
* flushed. Setting this to true causes the flush to wait for any started after the profile
* exchange as well.
* @throws InterruptedException If the operation is interrupted, usually for shutdown, an
* InterruptedException will be thrown
* @return true if the state was flushed, false if not
*/
public boolean flush(Set recipients, DistributedMember target, int processorType, boolean flushNewOps) throws InterruptedException {
// do not use recipients parameter past this point
Set recips = recipients;
if (Thread.interrupted()) {
throw new InterruptedException();
}
InternalDistributedMember myId = this.dm.getDistributionManagerId();
if (!recips.contains(target) && !myId.equals(target)) {
recips = new HashSet(recipients);
recips.add(target);
}
// partial fix for bug 38773 - ensures that this cache will get both
// a cache op and an adjunct message when creating a bucket region
// if (recips.size() < 2 && !myId.equals(target)) {
// return true; // no state to flush to a single holder of the region
// }
StateMarkerMessage smm = new StateMarkerMessage();
smm.relayRecipient = target;
smm.processorType = processorType;
smm.flushNewOps = flushNewOps;
if (region == null) {
smm.allRegions = true;
} else {
smm.regionPath = region.getFullPath();
}
smm.setRecipients(recips);
StateFlushReplyProcessor gfprocessor = new StateFlushReplyProcessor(dm, recips, target);
smm.processorId = gfprocessor.getProcessorId();
if (region != null && region.isUsedForPartitionedRegionBucket() && region.getDistributionConfig().getAckSevereAlertThreshold() > 0) {
smm.severeAlertEnabled = true;
gfprocessor.enableSevereAlertProcessing();
}
if (logger.isTraceEnabled(LogMarker.STATE_FLUSH_OP)) {
logger.trace(LogMarker.STATE_FLUSH_OP, "Sending {} with processor {}", smm, gfprocessor);
}
Set failures = this.dm.putOutgoing(smm);
if (failures != null) {
if (failures.contains(target)) {
if (logger.isTraceEnabled(LogMarker.STATE_FLUSH_OP)) {
logger.trace(LogMarker.STATE_FLUSH_OP, "failed to send StateMarkerMessage to target {}; returning from flush without waiting for replies", target);
}
return false;
}
gfprocessor.messageNotSentTo(failures);
}
try {
// try { Thread.sleep(100); } catch (InterruptedException e) {
// Thread.currentThread().interrupt(); } // DEBUGGING - stall before getting membership to
// increase odds that target has left
gfprocessor.waitForReplies();
if (logger.isTraceEnabled(LogMarker.STATE_FLUSH_OP)) {
logger.trace(LogMarker.STATE_FLUSH_OP, "Finished processing {}", smm);
}
} catch (ReplyException re) {
logger.warn(LocalizedMessage.create(LocalizedStrings.StateFlushOperation_STATE_FLUSH_TERMINATED_WITH_EXCEPTION), re);
return false;
}
return true;
}
Aggregations