|
@@ -48,6 +48,11 @@
|
|
|
|
|
|
//#define _TRACE
|
|
|
//#define _FULLTRACE
|
|
|
+
|
|
|
+#if 1 // #ifdef _FULLTRACE
|
|
|
+#define _TRACELINKCLOSED
|
|
|
+#endif
|
|
|
+#define _TRACEMPSERVERNOTIFYCLOSED
|
|
|
#define _TRACEORPHANS
|
|
|
|
|
|
|
|
@@ -475,6 +480,7 @@ protected:
|
|
|
unsigned short port;
|
|
|
public:
|
|
|
bool checkclosed;
|
|
|
+ bool tryReopenChannel = false;
|
|
|
|
|
|
// packet handlers
|
|
|
PingPacketHandler *pingpackethandler; // TAG_SYS_PING
|
|
@@ -548,6 +554,22 @@ public:
|
|
|
{
|
|
|
return myNode;
|
|
|
}
|
|
|
+ virtual void setOpt(MPServerOpts opt, const char *value)
|
|
|
+ {
|
|
|
+ switch (opt)
|
|
|
+ {
|
|
|
+ case mpsopt_channelreopen:
|
|
|
+ {
|
|
|
+ bool tf = (nullptr != value) ? strToBool(value) : false;
|
|
|
+ PROGLOG("Setting ChannelReopen = %s", tf ? "true" : "false");
|
|
|
+ tryReopenChannel = tf;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ // ignore
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
//===========================================================================
|
|
@@ -718,6 +740,17 @@ protected: friend class CMPPacketReader;
|
|
|
#endif
|
|
|
|
|
|
|
|
|
+ bool checkReconnect(CTimeMon &tm)
|
|
|
+ {
|
|
|
+ if (!parent->tryReopenChannel)
|
|
|
+ return false;
|
|
|
+ ::Release(channelsock);
|
|
|
+ channelsock = nullptr;
|
|
|
+ if (connect(tm))
|
|
|
+ return true;
|
|
|
+ WARNLOG("Failed to reconnect");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
bool connect(CTimeMon &tm)
|
|
|
{
|
|
|
// must be called from connectsect
|
|
@@ -979,12 +1012,12 @@ public:
|
|
|
{
|
|
|
CriticalBlock block(connectsect);
|
|
|
if (closed) {
|
|
|
-#ifdef _FULLTRACE
|
|
|
+#ifdef _TRACELINKCLOSED
|
|
|
LOG(MCdebugInfo(100), unknownJob, "WritePacket closed on entry");
|
|
|
PrintStackReport();
|
|
|
#endif
|
|
|
- IMP_Exception *e=new CMPException(MPERR_link_closed,remoteep);
|
|
|
- throw e;
|
|
|
+ if (!checkReconnect(tm))
|
|
|
+ throw new CMPException(MPERR_link_closed,remoteep);
|
|
|
}
|
|
|
if (!channelsock) {
|
|
|
if (!connect(tm)) {
|
|
@@ -1127,8 +1160,10 @@ public:
|
|
|
try {
|
|
|
s->shutdown();
|
|
|
}
|
|
|
- catch (IException *) {
|
|
|
+ catch (IException *e) {
|
|
|
socketfailed = true; // ignore if the socket has been closed
|
|
|
+ WARNLOG("closeSocket() : Ignoring shutdown error");
|
|
|
+ e->Release();
|
|
|
}
|
|
|
}
|
|
|
parent->querySelectHandler().remove(s);
|
|
@@ -1701,12 +1736,12 @@ bool CMPChannel::send(MemoryBuffer &mb, mptag_t tag, mptag_t replytag, CTimeMon
|
|
|
size32_t msgsize = mb.length();
|
|
|
PacketHeader hdr(msgsize+sizeof(PacketHeader),localep,remoteep,tag,replytag);
|
|
|
if (closed||(reply&&!isConnected())) { // flag error if has been disconnected
|
|
|
-#ifdef _FULLTRACE
|
|
|
+#ifdef _TRACELINKCLOSED
|
|
|
LOG(MCdebugInfo(100), unknownJob, "CMPChannel::send closed on entry %d",(int)closed);
|
|
|
PrintStackReport();
|
|
|
#endif
|
|
|
- IMP_Exception *e=new CMPException(MPERR_link_closed,remoteep);
|
|
|
- throw e;
|
|
|
+ if (!checkReconnect(tm))
|
|
|
+ throw new CMPException(MPERR_link_closed,remoteep);
|
|
|
}
|
|
|
|
|
|
bool ismulti = (msgsize>MAXDATAPERPACKET);
|
|
@@ -2236,7 +2271,7 @@ bool CMPServer::recv(CMessageBuffer &mbuf, const SocketEndpoint *ep, mptag_t tag
|
|
|
return true;
|
|
|
}
|
|
|
if (nfy.aborted) {
|
|
|
-#ifdef _FULLTRACE
|
|
|
+#ifdef _TRACELINKCLOSED
|
|
|
LOG(MCdebugInfo(100), unknownJob, "CMPserver::recv closed on notify");
|
|
|
PrintStackReport();
|
|
|
#endif
|
|
@@ -2322,7 +2357,7 @@ unsigned CMPServer::probe(const SocketEndpoint *ep, mptag_t tag,CTimeMon &tm,Soc
|
|
|
return nfy.cancel?0:nfy.count;
|
|
|
}
|
|
|
if (nfy.aborted) {
|
|
|
-#ifdef _FULLTRACE
|
|
|
+#ifdef _TRACELINKCLOSED
|
|
|
LOG(MCdebugInfo(100), unknownJob, "CMPserver::probe closed on notify");
|
|
|
PrintStackReport();
|
|
|
#endif
|
|
@@ -2407,9 +2442,10 @@ bool CMPServer::nextChannel(CMPChannel *&cur)
|
|
|
|
|
|
void CMPServer::notifyClosed(SocketEndpoint &ep)
|
|
|
{
|
|
|
-#ifdef _TRACE
|
|
|
+#ifdef _TRACEMPSERVERNOTIFYCLOSED
|
|
|
StringBuffer url;
|
|
|
LOG(MCdebugInfo(100), unknownJob, "MP: CMPServer::notifyClosed %s",ep.getUrlStr(url).str());
|
|
|
+ PrintStackReport();
|
|
|
#endif
|
|
|
notifyclosedthread->notify(ep);
|
|
|
}
|