Hi Jarl,
we stumbled over the ClientStub method setAutoReconnect and were questioning ourselves whether this method may of any use for our connection problem. I tried to decrypt the code in Marshal.cpp but I must admit that some explanation from your side would help me ...
Regards and sorry for bothering you so frequently,
Volker
RCF::ClientStub::setAutoReconnect ?
Re: RCF::ClientStub::setAutoReconnect ?
No problem Volker. The autoReconnect setting is set to true by default, and it means that if a client detects a network disconnection, right before making a call, it will silently reconnect and then issue the call as normal.
If you set it to false, you will get an immediate exception in those cases where the client can detect that the connection is down. However this still leaves open the situation of undetectable disconnections, for example if a network cable is pulled out of the server.
If you set it to false, you will get an immediate exception in those cases where the client can detect that the connection is down. However this still leaves open the situation of undetectable disconnections, for example if a network cable is pulled out of the server.
Re: RCF::ClientStub::setAutoReconnect ?
I slighly modified the client of your Hello World example :
And I expected that now I have to add an explicit call to connect somewhere. Auto reconnection seems to work regardless of the state of the ClientStub member _mAutoReconnect_. I tried this with client and server on a single host where I periodically stopped and started the server.
Code: Select all
#include <RCF/RCF.hpp>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/exception/all.hpp>
#include <iostream>
RCF_BEGIN(I_HelloWorld, "I_HelloWorld")
RCF_METHOD_V1(void, Print, const std::string &)
RCF_END(I_HelloWorld)
int main()
{
RCF::RcfInitDeinit rcfInit;
RcfClient<I_HelloWorld> client( RCF::TcpEndpoint(50001) );
client.getClientStub().setAutoReconnect(false);
for(;;)
{
try {
std::cout << "Calling the I_HelloWorld Print() method." << std::endl;
client.Print("Hello World");
}
catch( std::exception const &exc )
{
std::cerr << boost::diagnostic_information(exc) << std::endl ;
}
boost::this_thread::sleep_for( boost::chrono::seconds(1) ) ;
}
return 0;
}
Re: RCF::ClientStub::setAutoReconnect ?
setAutoReconnect() only affects what the client does, if it detects an unexpected disconnection. When you first create the client object, it is in a known disconnected state and therefore knows that it has to connect.
However, if at a subsequent point, you make a call on the client, and before sending the request the client detects that the network connection is no longer up, that's where the autoReconnect setting comes into play. Should the client do a transparent reconnect and then issue the call, or should it just throw an error.
However, if at a subsequent point, you make a call on the client, and before sending the request the client detects that the network connection is no longer up, that's where the autoReconnect setting comes into play. Should the client do a transparent reconnect and then issue the call, or should it just throw an error.
Re: RCF::ClientStub::setAutoReconnect ?
Thats what I tried to achieve with the simple modification of the example.
I would expect that when I start client and server (I which order doesn't matter), the client will establish the connection. That is what I see, everythings fine.
But after that when I stop and restart the server, I would expect that the client would not reconnect without my interaction (calling connect explicitly).
Scratching my head ...
I would expect that when I start client and server (I which order doesn't matter), the client will establish the connection. That is what I see, everythings fine.
But after that when I stop and restart the server, I would expect that the client would not reconnect without my interaction (calling connect explicitly).
Scratching my head ...
Re: RCF::ClientStub::setAutoReconnect ?
Are you by any chance testing it with one-way calls?
The relevant code is in ClientStub::connect(), in Marshal.cpp:
If you step through this code in a debugger, after restarting your server, you should be able to see which code it is going through, and why.
I've put together a simple sample to show how it works. If you run the following code you should get an exception after the server restarts:
The relevant code is in ClientStub::connect(), in Marshal.cpp:
Code: Select all
if (!mConnected)
{
// Not connected.
shouldReconnect = true;
}
else if ( mConnected
&& mAutoReconnect
&& mRcs == Twoway
&& !mTransport->isConnected())
{
// Auto reconnect.
shouldReconnect = true;
}
I've put together a simple sample to show how it works. If you run the following code you should get an exception after the server restarts:
Code: Select all
#include <iostream>
#include <RCF/RCF.hpp>
RCF_BEGIN(I_Echo, "I_Echo")
RCF_METHOD_R1(std::string, echo, const std::string &)
RCF_END(I_Echo)
class Echo
{
public:
std::string echo(const std::string &s)
{
return s;
}
};
int main()
{
RCF::RcfInitDeinit rcfInit;
try
{
Echo echo;
RCF::RcfServer server( RCF::TcpEndpoint(50001) );
server.bind<I_Echo>(echo);
server.start();
std::string s0 = "AAABBBCCC";
std::string s1;
RcfClient<I_Echo> client( RCF::TcpEndpoint(50001) );
client.getClientStub().setAutoReconnect(false);
s1 = client.echo(s0);
server.stop();
server.start();
// This will throw, as the original network connection has been closed by the server.
s1 = client.echo(s0);
}
catch(const RCF::Exception & e)
{
std::cout << "Error: " << e.getErrorString() << std::endl;
return 1;
}
return 0;
}
Re: RCF::ClientStub::setAutoReconnect ?
I found the misunderstanding in our conversation :
In case the flag mAutoReconnect has been set to false, the caller will get an exception of type RCF::Exception(_RcfError_PeerDisconnect()) in response to the first call he makes after the server has been restarted. The second call via RCF to the server will do a transparent reconnect because after the first unsuccesful attempt the flag mConnected has been set to false.
So knowing this we could handle the situation appropriate but IMHO the naming of the method may lead to misunderstanding.
In case the flag mAutoReconnect has been set to false, the caller will get an exception of type RCF::Exception(_RcfError_PeerDisconnect()) in response to the first call he makes after the server has been restarted. The second call via RCF to the server will do a transparent reconnect because after the first unsuccesful attempt the flag mConnected has been set to false.
So knowing this we could handle the situation appropriate but IMHO the naming of the method may lead to misunderstanding.
Re: RCF::ClientStub::setAutoReconnect ?
Yes, I see what you're saying... A more descriptive name might end up being uncomfortably long though.