[asterisk-scf-commits] asterisk-scf/integration/sip.git branch "retry_deux" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Fri Jan 20 13:59:41 CST 2012
branch "retry_deux" has been updated
via f7de9e3e3c9e447f89543e57e35a98857ff95e70 (commit)
from 0d7330f79f2e697442a5b9498f71d84b39a2bacf (commit)
Summary of changes:
src/PJSIPSessionModule.cpp | 59 +++++++++++++++++++++++++++-----
src/SIPTransfer.cpp | 81 +++++++++++++++++++++++++++++++++++++++----
src/SIPTransfer.h | 26 ++++++++++++++
3 files changed, 149 insertions(+), 17 deletions(-)
- Log -----------------------------------------------------------------
commit f7de9e3e3c9e447f89543e57e35a98857ff95e70
Author: Ken Hunt <ken.hunt at digium.com>
Date: Fri Jan 20 13:59:48 2012 -0600
Adding additional retry logic for the other session router operations.
diff --git a/src/PJSIPSessionModule.cpp b/src/PJSIPSessionModule.cpp
index 754502e..1cd5ead 100644
--- a/src/PJSIPSessionModule.cpp
+++ b/src/PJSIPSessionModule.cpp
@@ -2028,7 +2028,12 @@ public:
const std::string& contact,
const AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx>& router,
const SIPSessionPtr& session)
- : mInv(inv), mContact(contact), mRouter(router), mSession(session) { }
+ : mInv(inv),
+ mContact(contact),
+ mRouter(router),
+ mSession(session),
+ mRetryPolicy(5, 500),
+ mOperationId(::IceUtil::generateUUID()) { }
protected:
SuspendableWorkResult initial(const SuspendableWorkListenerPtr&)
@@ -2037,14 +2042,8 @@ protected:
{
SuspendableWorkListenerPtr listener = 0;
SIPAMICallbackPtr cb(new SIPAMICallback(listener, mSession, this, false, true));
- Ice::CallbackPtr d = Ice::newCallback(cb, &SIPAMICallback::callback);
- mRouter->begin_connectBridgedSessionsWithDestination(
- IceUtil::generateUUID(),
- mSession->getSessionProxy(),
- mContact,
- true,
- 0,
- d);
+ SIPAMICallbackCookiePtr cookie = new SIPAMICallbackCookie(cb);
+ invokeOperation(cookie);
}
catch (const Ice::CommunicatorDestroyedException&)
{
@@ -2053,6 +2052,24 @@ protected:
return Complete;
}
+ /**
+ * Invoke the operation.
+ * @param cookie The cookie contains the SIPAMICallback object. Passed into the AMI operation so
+ * that retry operations have access to the callback object.
+ */
+ void invokeOperation(const SIPAMICallbackCookiePtr& cookie)
+ {
+ Ice::CallbackPtr d = Ice::newCallback(cookie->getSIPAMICallback(), &SIPAMICallback::callback);
+ mRouter->begin_connectBridgedSessionsWithDestination(
+ mOperationId,
+ mSession->getSessionProxy(),
+ mContact,
+ true,
+ 0,
+ d,
+ cookie);
+ }
+
SuspendableWorkResult calledBack(const Ice::AsyncResultPtr& asyncResult)
{
SessionRouterPrx router =
@@ -2066,6 +2083,28 @@ protected:
{
router->end_connectBridgedSessionsWithDestination(asyncResult);
}
+ catch (const Ice::ConnectionLostException &cle)
+ {
+ // Assume a failover is occurring for the routing service.
+ // This will block the WorkQueue's thread, but it's highly likely
+ // that the failover effects most of the other enqueued operations
+ // anyway.
+ if(mRetryPolicy.retry())
+ {
+ lg(Warning) << "HandleRedirection: Retrying connectBridgedSessionsWithDestination operation.";
+
+ // Retry the operation.
+ invokeOperation(SIPAMICallbackCookiePtr::dynamicCast(asyncResult->getCookie()));
+ }
+ else
+ {
+ lg(Error) << "HandleRedirection: connectBridgedSessionsWithDestination failed " << mRetryPolicy.getMaxRetries() << " retries." ;
+
+ op = PJSIP_REDIRECT_REJECT;
+ pjsip_inv_process_redirect(mInv, op, NULL);
+ }
+ return Complete;
+ }
catch (const std::exception&)
{
op = PJSIP_REDIRECT_REJECT;
@@ -2080,6 +2119,8 @@ private:
const std::string mContact;
AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx> mRouter;
SIPSessionPtr mSession;
+ RetryPolicy mRetryPolicy;
+ std::string mOperationId;
};
pjsip_redirect_op PJSIPSessionModule::invOnRedirected(pjsip_inv_session* inv, const pjsip_uri* uri,
diff --git a/src/SIPTransfer.cpp b/src/SIPTransfer.cpp
index 2620727..0f0b06b 100644
--- a/src/SIPTransfer.cpp
+++ b/src/SIPTransfer.cpp
@@ -417,7 +417,9 @@ HandleReferOperation::HandleReferOperation(
mReplicationContext(replicationContext),
mModuleId(moduleId),
mReferCSeq(tsx->cseq),
- mBlindTransfer(false) {}
+ mBlindTransfer(false),
+ mOperationId(::IceUtil::generateUUID()),
+ mRetryPolicy(5, 500) {}
HandleReferOperation::~HandleReferOperation()
{
@@ -484,20 +486,20 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
}
PJSIPSessionModInfo *other_session_mod_info = (PJSIPSessionModInfo*)other_inv->mod_data[mModuleId];
- SIPSessionPtr other_session = other_session_mod_info->getSessionPtr();
+ mOtherSession = other_session_mod_info->getSessionPtr();
//Go ahead and send a 202 for the REFER. We can send a NOTIFY later to indicate if something
//on the outbound leg went awry.
pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
try
{
- std::string operationId = ::IceUtil::generateUUID();
SIPAMICallbackPtr cb(new SIPAMICallback(workListener, mSession, this, false, true));
- Ice::CallbackPtr d = Ice::newCallback(cb, &SIPAMICallback::callback);
+ SIPAMICallbackCookiePtr cookie = new SIPAMICallbackCookie(cb);
lg(Debug) << "handleRefer() calling router connectBridgedSessions(). ";
- mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), true, d);
+ invokeTransfer(cookie);
+
pjsip_dlg_dec_lock(other_dlg);
return Complete;
}
@@ -518,11 +520,10 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
// Now that we have the target user we can pass this into routing and go on our marry way
try
{
- std::string operationId = ::IceUtil::generateUUID();
PJSIPSessionModInfo *session_mod_info = (PJSIPSessionModInfo*)mInv->mod_data[mModuleId];
SIPSessionPtr session = session_mod_info->getSessionPtr();
SIPAMICallbackPtr cb(new SIPAMICallback(workListener, mSession, this, false, true));
- Ice::CallbackPtr d = Ice::newCallback(cb, &SIPAMICallback::callback);
+ SIPAMICallbackCookiePtr cookie = new SIPAMICallbackCookie(cb);
lg(Debug) << "handleRefer() calling router connectBridgedSessionsWithDestination(). ";
lg(Debug) << "Session to replace is with endpoint " << session->getEndpoint()->getName();
@@ -539,7 +540,8 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
}
- mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, true, mHook->getProxy(), d);
+ invokeBlindTransfer(cookie);
+
return Complete;
}
catch (const Ice::CommunicatorDestroyedException &)
@@ -552,6 +554,32 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
}
};
+/**
+ * Invoke a blind transfer operation.
+ * @param cookie The cookie contains the SIPAMICallback object. Passed into the AMI operation so
+ * that retry operations have access to the callback object.
+ */
+void HandleReferOperation::invokeBlindTransfer(const SIPAMICallbackCookiePtr& cookie)
+{
+ Ice::CallbackPtr d = Ice::newCallback(cookie->getSIPAMICallback(), &SIPAMICallback::callback);
+
+ PJSIPSessionModInfo *session_mod_info = (PJSIPSessionModInfo*)mInv->mod_data[mModuleId];
+ SIPSessionPtr session = session_mod_info->getSessionPtr();
+
+ mSessionRouter->begin_connectBridgedSessionsWithDestination(mOperationId, session->getSessionProxy(), mTarget, true, mHook->getProxy(), d);
+}
+
+/**
+ * Invoke a transfer operation.
+ * @param cookie The cookie contains the SIPAMICallback object. Passed into the AMI operation so
+ * that retry operations have access to the callback object.
+ */
+void HandleReferOperation::invokeTransfer(const SIPAMICallbackCookiePtr& cookie)
+{
+ Ice::CallbackPtr d = Ice::newCallback(cookie->getSIPAMICallback(), &SIPAMICallback::callback);
+ mSessionRouter->begin_connectBridgedSessions(mOperationId, mSession->getSessionProxy(), mOtherSession->getSessionProxy(), true, d);
+}
+
SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr& asyncResult)
{
SessionRouterPrx router = SessionRouterPrx::uncheckedCast(asyncResult->getProxy());
@@ -567,6 +595,43 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
router->end_connectBridgedSessions(asyncResult);
}
}
+ catch (const Ice::ConnectionLostException &cle)
+ {
+ // Assume a failover is occurring for the routing service.
+ // This will block the WorkQueue's thread, but it's highly likely
+ // that the failover effects most of the other enqueued operations
+ // anyway.
+ if(mRetryPolicy.retry())
+ {
+ lg(Warning) << "HandleReferOperation: Retrying transfer operation.";
+
+ // Retry the operation.
+ if (mBlindTransfer)
+ {
+ invokeBlindTransfer(SIPAMICallbackCookiePtr::dynamicCast(asyncResult->getCookie()));
+ }
+ else
+ {
+ invokeTransfer(SIPAMICallbackCookiePtr::dynamicCast(asyncResult->getCookie()));
+ }
+ }
+ else
+ {
+ lg(Error) << "ConnectBridgedSessionsCallback sending 400 due to retry failing " << mRetryPolicy.getMaxRetries() << " retries." ;
+ pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
+ if (tdata)
+ {
+ addNotifyBody(tdata, "SIP/2.0 400 Bad Request");
+ pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+ }
+ //Only blind transfers have the session creation hook to get rid of
+ if (mBlindTransfer)
+ {
+ mHook->shutdown();
+ }
+ }
+ return Complete;
+ }
catch (const AsteriskSCF::Core::Routing::V1::DestinationNotFoundException&)
{
lg(Debug) << "ConnectBridgedSessionsWithDestination sending 404 due to destination not found.";
diff --git a/src/SIPTransfer.h b/src/SIPTransfer.h
index aebc65c..db8927c 100644
--- a/src/SIPTransfer.h
+++ b/src/SIPTransfer.h
@@ -19,6 +19,7 @@
#include <AsteriskSCF/Discovery/SmartProxy.h>
#include <AsteriskSCF/Replication/SIPSessionManager/SIPStateReplicationIf.h>
#include <AsteriskSCF/System/Hook/HookIf.h>
+#include <AsteriskSCF/Helpers/Retry.h>
#include "PJSIPSessionModule.h"
@@ -280,6 +281,17 @@ protected:
const Ice::AsyncResultPtr& asyncResult);
private:
+
+ /**
+ * Invoke a blind transfer using session routing service.
+ */
+ void invokeBlindTransfer(const SIPAMICallbackCookiePtr& cookie);
+
+ /**
+ * Invoke a transfer using session routing service.
+ */
+ void invokeTransfer(const SIPAMICallbackCookiePtr& cookie);
+
/**
* Find matching dialog from the replaces header.
* This mostly exists just so there isn't a huge
@@ -329,6 +341,10 @@ private:
*/
SIPSessionPtr mSession;
/**
+ * The SIPSession that is bridged with the sessions that are being moved in a transfer.
+ */
+ SIPSessionPtr mOtherSession;
+ /**
* Session router...nothing more to say really
*/
AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::SessionCommunications::V1::SessionRouterPrx> mSessionRouter;
@@ -359,6 +375,16 @@ private:
* session fails.
*/
TransferSessionCreationHookPtr mHook;
+
+ /**
+ * Unique id used for the routing service operation.
+ */
+ std::string mOperationId;
+
+ /**
+ * Retry helper.
+ */
+ RetryPolicy mRetryPolicy;
};
}; //end namespace SIPSessionManager
-----------------------------------------------------------------------
--
asterisk-scf/integration/sip.git
More information about the asterisk-scf-commits
mailing list