}
/** {@inheritDoc} */
@Override
public void run(IRequest request, IResponse response, IResponderCallback responderCallback) throws Exception {
SCMPMessage reqMessage = request.getMessage();
String serviceName = reqMessage.getServiceName();
// check service is present
Service abstractService = this.getService(serviceName);
int oti = reqMessage.getHeaderInt(SCMPHeaderAttributeKey.OPERATION_TIMEOUT);
// service is cascaded - unsubscribe is made by a normal client
String subscriptionId = reqMessage.getSessionId();
// lookup session and checks properness
Subscription subscription = this.getSubscriptionById(subscriptionId);
// looks up publish message queue and stops publish mechanism
PublishMessageQueue<SCMPMessage> publishMessageQueue = this.getPublishMessageQueueById(subscription);
// first remove subscription than unsubscribe
this.subscriptionRegistry.removeSubscription(subscription);
publishMessageQueue.unsubscribe(subscriptionId);
switch (abstractService.getType()) {
case CASCADED_PUBLISH_SERVICE:
CascadedPublishService cascadedPublishService = (CascadedPublishService) abstractService;
// publish service is cascaded
CascadedSC cascadedSC = cascadedPublishService.getCascadedSC();
// free server from subscription
cascadedSC.removeSession(subscription);
ClnUnsubscribeCommandCallback callback = new ClnUnsubscribeCommandCallback(request, response, responderCallback,
subscription);
cascadedSC.cascadedSCUnsubscribe(cascadedPublishService.getCascClient(), reqMessage, callback, oti);
return;
default:
// code for other types of services is below
break;
}
StatefulServer server = (StatefulServer) subscription.getServer();
ClnUnsubscribeCommandCallback callback = null;
int otiOnSCMillis = (int) (oti * basicConf.getOperationTimeoutMultiplier());
int tries = (otiOnSCMillis / Constants.WAIT_FOR_FREE_CONNECTION_INTERVAL_MILLIS);
int i = 0;
// Following loop implements the wait mechanism in case of a busy connection pool
do {
// reset msgType, might have been modified in below unsubscribe try
reqMessage.setMessageType(this.getKey());
// set up callback for normal client unsubscribe operation
callback = new ClnUnsubscribeCommandCallback(request, response, responderCallback, subscription);
try {
server.unsubscribe(reqMessage, callback, otiOnSCMillis - (i * Constants.WAIT_FOR_FREE_CONNECTION_INTERVAL_MILLIS));
// delete unreferenced nodes in queue
publishMessageQueue.removeNonreferencedNodes();
// no exception has been thrown - get out of wait loop
break;
} catch (ConnectionPoolBusyException ex) {
LOGGER.debug("ConnectionPoolBusyException caught in wait mec of unsubscribe, tries left=" + tries);
if (i >= (tries - 1)) {
// only one loop outstanding - don't continue throw current exception
server.abortSession(subscription, "unsubscribe subscription failed, connection pool to server busy");
LOGGER.debug(SCMPError.NO_FREE_CONNECTION.getErrorText("service=" + reqMessage.getServiceName()));
SCMPCommandException scmpCommandException = new SCMPCommandException(SCMPError.NO_FREE_CONNECTION, "service="
+ reqMessage.getServiceName());
scmpCommandException.setMessageType(this.getKey());
throw scmpCommandException;
}
}
// sleep for a while and then try again