use of org.apache.geode.internal.cache.ClientServerObserver in project geode by apache.
the class CacheClientUpdater method processMessages.
/**
* Processes messages received from the server.
*
* Only certain types of messages are handled.
*
* TODO: Method 'processMessages' is too complex to analyze by data flow algorithm
*
* @see MessageType#CLIENT_MARKER
* @see MessageType#LOCAL_CREATE
* @see MessageType#LOCAL_UPDATE
* @see MessageType#LOCAL_INVALIDATE
* @see MessageType#LOCAL_DESTROY
* @see MessageType#LOCAL_DESTROY_REGION
* @see MessageType#CLEAR_REGION
* @see ClientUpdateMessage
*/
private void processMessages() {
final boolean isDebugEnabled = logger.isDebugEnabled();
try {
Message clientMessage = initializeMessage();
if (quitting()) {
if (isDebugEnabled) {
logger.debug("processMessages quitting early because we have stopped");
}
// our caller calls close which will notify all waiters for our init
return;
}
logger.info(LocalizedMessage.create(LocalizedStrings.CacheClientUpdater_0_READY_TO_PROCESS_MESSAGES, this));
while (this.continueProcessing.get()) {
if (quitting()) {
if (isDebugEnabled) {
logger.debug("termination detected");
}
// our caller calls close which will notify all waiters for our init
return;
}
// the endpoint died while this thread was sleeping.
if (this.endpoint.isClosed()) {
if (isDebugEnabled) {
logger.debug("endpoint died");
}
// = false;
this.continueProcessing.set(false);
break;
}
try {
// Read the message
clientMessage.recv();
// Wait for the previously failed cache client updater
// to finish. This will avoid out of order messages.
waitForFailedUpdater();
this.cache.waitForRegisterInterestsInProgress();
if (quitting()) {
if (isDebugEnabled) {
logger.debug("processMessages quitting before processing message");
}
break;
}
// If the message is a ping, ignore it
if (clientMessage.getMessageType() == MessageType.SERVER_TO_CLIENT_PING) {
if (isDebugEnabled) {
logger.debug("{}: Received ping", this);
}
continue;
}
boolean isDeltaSent = false;
boolean isCreateOrUpdate = clientMessage.getMessageType() == MessageType.LOCAL_CREATE || clientMessage.getMessageType() == MessageType.LOCAL_UPDATE;
if (isCreateOrUpdate) {
isDeltaSent = (Boolean) clientMessage.getPart(2).getObject();
}
// extract the eventId and verify if it is a duplicate event
// if it is a duplicate event, ignore
// @since GemFire 5.1
int numberOfParts = clientMessage.getNumberOfParts();
Part eid = clientMessage.getPart(numberOfParts - 1);
// TODO the message handling methods also deserialized the eventID - inefficient
EventID eventId = (EventID) eid.getObject();
// no need to verify if the instantiator msg is duplicate or not
if (clientMessage.getMessageType() != MessageType.REGISTER_INSTANTIATORS && clientMessage.getMessageType() != MessageType.REGISTER_DATASERIALIZERS) {
if (this.qManager.getState().verifyIfDuplicate(eventId, !(this.isDurableClient || isDeltaSent))) {
continue;
}
}
if (logger.isTraceEnabled(LogMarker.BRIDGE_SERVER)) {
logger.trace(LogMarker.BRIDGE_SERVER, "Processing event with id {}", eventId.expensiveToString());
}
this.isOpCompleted = true;
// Process the message
switch(clientMessage.getMessageType()) {
case MessageType.LOCAL_CREATE:
case MessageType.LOCAL_UPDATE:
handleUpdate(clientMessage);
break;
case MessageType.LOCAL_INVALIDATE:
handleInvalidate(clientMessage);
break;
case MessageType.LOCAL_DESTROY:
handleDestroy(clientMessage);
break;
case MessageType.LOCAL_DESTROY_REGION:
handleDestroyRegion(clientMessage);
break;
case MessageType.CLEAR_REGION:
handleClearRegion(clientMessage);
break;
case MessageType.REGISTER_INSTANTIATORS:
handleRegisterInstantiator(clientMessage, eventId);
break;
case MessageType.REGISTER_DATASERIALIZERS:
handleRegisterDataSerializer(clientMessage, eventId);
break;
case MessageType.CLIENT_MARKER:
handleMarker(clientMessage);
break;
case MessageType.INVALIDATE_REGION:
handleInvalidateRegion(clientMessage);
break;
case MessageType.CLIENT_REGISTER_INTEREST:
handleRegisterInterest(clientMessage);
break;
case MessageType.CLIENT_UNREGISTER_INTEREST:
handleUnregisterInterest(clientMessage);
break;
case MessageType.TOMBSTONE_OPERATION:
handleTombstoneOperation(clientMessage);
break;
default:
logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientUpdater_0_RECEIVED_AN_UNSUPPORTED_MESSAGE_TYPE_1, new Object[] { this, MessageType.getString(clientMessage.getMessageType()) }));
break;
}
if (this.isOpCompleted && (this.isDurableClient || isDeltaSent)) {
this.qManager.getState().verifyIfDuplicate(eventId, true);
}
// TODO we should maintain the client's "live" view of the server
// but we don't because the server health monitor needs traffic
// originating from the client
// and by updating the last update stat, the ServerMonitor is less
// likely to send pings...
// and the ClientHealthMonitor will cause a disconnect
} catch (InterruptedIOException ignore) {
// Per Sun's support web site, this exception seems to be peculiar
// to Solaris, and may eventually not even be generated there.
//
// When this exception is thrown, the thread has been interrupted, but
// isInterrupted() is false. (How very odd!)
//
// We regard it the same as an InterruptedException
this.continueProcessing.set(false);
if (isDebugEnabled) {
logger.debug("InterruptedIOException");
}
} catch (IOException e) {
// Either the server went away, or we caught a closing condition.
if (!quitting()) {
// Server departed; print a message.
ClientServerObserver clientServerObserver = ClientServerObserverHolder.getInstance();
clientServerObserver.beforeFailoverByCacheClientUpdater(this.location);
this.eManager.serverCrashed(this.endpoint);
if (isDebugEnabled) {
logger.debug("Caught the following exception and will exit", e);
}
}
// !quitting
// In any event, terminate this thread.
this.continueProcessing.set(false);
if (isDebugEnabled) {
logger.debug("terminated due to IOException");
}
} catch (Exception e) {
if (!quitting()) {
ClientServerObserver clientServerObserver = ClientServerObserverHolder.getInstance();
clientServerObserver.beforeFailoverByCacheClientUpdater(this.location);
this.eManager.serverCrashed(this.endpoint);
String message = ": Caught the following exception and will exit: ";
handleException(message, e);
}
// In any event, terminate this thread.
// = false; // force termination
this.continueProcessing.set(false);
if (isDebugEnabled) {
logger.debug("CCU terminated due to Exception");
}
} finally {
clientMessage.clear();
}
}
// while
} finally {
if (isDebugEnabled) {
logger.debug("has stopped and cleaning the helper ..");
}
// added to fix some race conditions associated with 38382
close();
// this will make sure that if this thread dies without starting QueueMgr then it will start..
// 1. above we ignore InterruptedIOException and this thread dies without informing QueueMgr
// 2. if there is some other race condition with continueProcessing flag
this.qManager.checkEndpoint(this, this.endpoint);
}
}
use of org.apache.geode.internal.cache.ClientServerObserver in project geode by apache.
the class CacheClientUpdater method handleRegisterDataSerializer.
private void handleRegisterDataSerializer(Message msg, EventID eventId) {
Class dataSerializerClass = null;
final boolean isDebugEnabled = logger.isDebugEnabled();
try {
int noOfParts = msg.getNumberOfParts();
if (isDebugEnabled) {
logger.debug("{}: Received register dataserializer message of parts {}", getName(), noOfParts);
}
for (int i = 0; i < noOfParts - 1; ) {
try {
String dataSerializerClassName = (String) CacheServerHelper.deserialize(msg.getPart(i).getSerializedForm());
int id = msg.getPart(i + 1).getInt();
InternalDataSerializer.register(dataSerializerClassName, false, eventId, null, id);
// distribute is false because we don't want to propagate this to servers recursively
int numOfClasses = msg.getPart(i + 2).getInt();
int j = 0;
for (; j < numOfClasses; j++) {
String className = (String) CacheServerHelper.deserialize(msg.getPart(i + 3 + j).getSerializedForm());
InternalDataSerializer.updateSupportedClassesMap(dataSerializerClassName, className);
}
i += 3 + j;
} catch (ClassNotFoundException e) {
if (isDebugEnabled) {
logger.debug("{}: Caught following exception while attempting to read DataSerializer : {}", this, dataSerializerClass, e);
}
}
}
// CALLBACK TESTING PURPOSE ONLY
if (PoolImpl.IS_INSTANTIATOR_CALLBACK) {
ClientServerObserver bo = ClientServerObserverHolder.getInstance();
bo.afterReceivingFromServer(eventId);
}
} catch (Exception e) {
if (isDebugEnabled) {
logger.debug("{}: Caught following exception while attempting to read DataSerializer : {}", this, dataSerializerClass, e);
}
}
}
use of org.apache.geode.internal.cache.ClientServerObserver in project geode by apache.
the class CacheClientUpdater method handleRegisterInstantiator.
/**
* Register instantiators locally
*
* @param clientMessage message describing the new instantiators
* @param eventId eventId of the instantiators
*/
private void handleRegisterInstantiator(Message clientMessage, EventID eventId) {
String instantiatorClassName = null;
final boolean isDebugEnabled = logger.isDebugEnabled();
try {
int noOfParts = clientMessage.getNumberOfParts();
if (isDebugEnabled) {
logger.debug("{}: Received register instantiators message of parts {}", getName(), noOfParts);
}
Assert.assertTrue((noOfParts - 1) % 3 == 0);
for (int i = 0; i < noOfParts - 1; i += 3) {
instantiatorClassName = (String) CacheServerHelper.deserialize(clientMessage.getPart(i).getSerializedForm());
String instantiatedClassName = (String) CacheServerHelper.deserialize(clientMessage.getPart(i + 1).getSerializedForm());
int id = clientMessage.getPart(i + 2).getInt();
InternalInstantiator.register(instantiatorClassName, instantiatedClassName, id, false, eventId, null);
// distribute is false because we don't want to propagate this to servers recursively
}
// CALLBACK TESTING PURPOSE ONLY
if (PoolImpl.IS_INSTANTIATOR_CALLBACK) {
ClientServerObserver clientServerObserver = ClientServerObserverHolder.getInstance();
clientServerObserver.afterReceivingFromServer(eventId);
}
} catch (Exception e) {
if (isDebugEnabled) {
logger.debug("{}: Caught following exception while attempting to read Instantiator : {}", this, instantiatorClassName, e);
}
}
}
use of org.apache.geode.internal.cache.ClientServerObserver in project geode by apache.
the class CacheClientNotifier method blackListSlowReciever.
private void blackListSlowReciever(CacheClientProxy clientProxy) {
final CacheClientProxy proxy = clientProxy;
if ((proxy.getHARegionQueue() != null && proxy.getHARegionQueue().isClientSlowReciever()) && !blackListedClients.contains(proxy.getProxyID())) {
// log alert with client info.
logger.warn(LocalizedMessage.create(LocalizedStrings.CacheClientNotifier_CLIENT_0_IS_A_SLOW_RECEIVER, new Object[] { proxy.getProxyID() }));
addToBlacklistedClient(proxy.getProxyID());
InternalDistributedSystem ids = (InternalDistributedSystem) this.getCache().getDistributedSystem();
final DM dm = ids.getDistributionManager();
dm.getWaitingThreadPool().execute(new Runnable() {
public void run() {
CacheDistributionAdvisor advisor = ((DistributedRegion) proxy.getHARegionQueue().getRegion()).getCacheDistributionAdvisor();
Set members = advisor.adviseCacheOp();
// Send client blacklist message
ClientBlacklistProcessor.sendBlacklistedClient(proxy.getProxyID(), dm, members);
// close the proxy for slow receiver.
proxy.close(false, false);
removeClientProxy(proxy);
if (PoolImpl.AFTER_QUEUE_DESTROY_MESSAGE_FLAG) {
ClientServerObserver bo = ClientServerObserverHolder.getInstance();
bo.afterQueueDestroyMessage();
}
// send remove from blacklist.
RemoveClientFromBlacklistMessage rcm = new RemoveClientFromBlacklistMessage();
rcm.setProxyID(proxy.getProxyID());
dm.putOutgoing(rcm);
blackListedClients.remove(proxy.getProxyID());
}
});
}
}
use of org.apache.geode.internal.cache.ClientServerObserver in project geode by apache.
the class ServerRegionProxy method registerInterest.
/**
* Does a region registerInterest on a server
*
* @param key describes what we are interested in
* @param interestType the {@link InterestType} for this registration
* @param policy the interest result policy for this registration
* @param isDurable true if this registration is durable
* @param receiveUpdatesAsInvalidates whether to act like notify-by-subscription is false.
* @param regionDataPolicy the data policy ordinal of the region
* @return list of keys
*/
public List registerInterest(final Object key, final int interestType, final InterestResultPolicy policy, final boolean isDurable, final boolean receiveUpdatesAsInvalidates, final byte regionDataPolicy) {
if (interestType == InterestType.KEY && key instanceof List) {
return registerInterestList((List) key, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
} else {
final RegisterInterestTracker rit = this.pool.getRITracker();
List result = null;
boolean finished = false;
try {
// register with the tracker early
rit.addSingleInterest(this.region, key, interestType, policy, isDurable, receiveUpdatesAsInvalidates);
result = RegisterInterestOp.execute(this.pool, this.regionName, key, interestType, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
//////// TEST PURPOSE ONLY ///////////
if (PoolImpl.AFTER_REGISTER_CALLBACK_FLAG) {
ClientServerObserver bo = ClientServerObserverHolder.getInstance();
bo.afterInterestRegistration();
}
/////////////////////////////////////////
finished = true;
return result;
} finally {
if (!finished) {
rit.removeSingleInterest(this.region, key, interestType, isDurable, receiveUpdatesAsInvalidates);
}
}
}
}
Aggregations