What happens when a C++ thrift (NonBlocking) server loses a connection? - c++

I am failing to find any examples of thrift exception/error handling. How can I programatically catch the scenario where a server loses a connection to it's assigned port, and either log or restart the server, as desired by my application?

Related

Apache Thrift: Terminate Connection from the Server

I am using thrift to provide an interface between a device and a management console. It is possible for there to be up to 4 active connections to the device at one time, and I have this working using a TThreadPool server.
The issue arises around client disconnections; If a client disconnects correctly, there is no issue, however if one does not (i.e. the client crashes out or doesn't call client->close()) then the server seems to keep that clients thread alive. This means that when the next connection attempt is made, the client hangs, as the server has used up its allocated thread pool so cannot service the new request.
I haven't been able to find any standard, public mechanism by which the server can stop, and hence free up, a clients thread if that client has not used the interface for a set time period?
Is there a standard way to facilitate this in thrift?
Set the receive/send timeout on the server socket might help. Server will close the connection on timeout.
https://github.com/apache/thrift/blob/129f332d72facda5d06f87e2b4e5e08bea0b6b44/lib/cpp/src/thrift/transport/TServerSocket.h#L103
void setSendTimeout(int sendTimeout);
void setRecvTimeout(int recvTimeout);

boost asio notify server of disconnect

I was wondering if there is any way to notify a server if a client side application was closed. Normally, if I Ctrl+C my client side terminal an EOF-signal is sent to the server side. The server side async_read function has a handle which has boost::system::error_code ec argument fed into it. The handle is called when the server side receives EOF-signal which I can happily process and tell the server to start listening again.
However, if I try to cleanly close my client application using socket.shutdown() and socket.close() nothing happens and the server side socket remains open.
I was wondering, is there a way to somehow send an error signal to the server-side socket so I could then process it using the error code?
The approaches described in comments covers 99% of cases. It doesn't work when client machine was (not gracefully) turned off, or network problems.
To get reliable notification of disconnected client you need to implement "ping" feature: to send ping packets regularly and to check that you received pong packets.

Re-connecting to QDBus server after server has been restarted (Qt C++)

I'm testing out using DBus for inter process communication for an QT C++ project (Linux).
I'm not using the bus daemon and i'm using unix paths / sockets.
After navigating my way through the mysterious world that is QT DBUS all seemed to be going well, until i wanted to test the robustness of one of my interfaces.
After killing the server process en restarting it, the connection times out.. i cleanup the connection objects (client-side) and i try to re-connect to the server.
The client does not seem to be able to reconnect and i get the following errors:
errName: org.freedesktop.DBus.Error.NoServer
errMesage: Failed to connect to socket /tmp/abcd: Connection refused
Ive tried:
- QDBusConnection::disconnectFromPeer(addr);
- cleaning up all related object, so no references to the connection exist.
When i restart the client, it has no problems connecting to the (restarted) server.
Problem found!
Seems to be a bug in Qt 4.8.x:
https://bugreports.qt.io/browse/QTBUG-27973
https://codereview.qt-project.org/#/c/60709/
QDBusConnection::disconnectFromBus and QDBusConnection::disconnectFromPeer does not remove invalid connection

Check remote host state in a nework using Indy comps

I have client server application that works with Firebird server. Everytime when clients connect to the server they(client apps) don't check if there is a network connection to the server so at this time my application sometimes freezes when the server computer is switched off or service has stopped, so first of all I need to check connection if remote host is switched on or at some port anything listening....
Before establishing the connection I need to check it and make sure server and service is running using Indy components.
Any ideas? also I can use IcmpClient to ping remote host and then establish connection but which is the most optimal way ?
If you just want to check if the server computer can be reached, you could do a "ping" to check that. However, if you want to check if a specific TCP port is open, then the only way to find that out is to actually do a proper connect, which leads to the "freezing" program while the connection times out if there is no-one listening on that port.

Windows service running on Windows Server 2003 cannot call an xml web service on the same machine

I have an XML web service running on my Windows 2003 server. I have a windows service running on the same machine. I want to call the XML web service from the windows service.
This works fine on my development machine, which is running Windows XP. However, when I try to do this on my Windows Server 2003 box, it times out and throws an exception. My windows service catches the exception and writes it to the eventlog. This is how the error shows up in the event log :
The description for Event ID ( 0 ) in Source ( myWS ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event:
Exception in MyWS service : [System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond [MY IP ADDRESS HERE]
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetRequestStream()
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at TesterClient.Test() in C:\Projects\Odyl\OdylUtilities\MyWS\TesterClient.cs:line 30
at MyWS.MyWSWindowsService.DoMyWSService() in C:\Projects\Odyl\OdylUtilities\MyWS\MyWSWindowsService.cs:line 81
at MyWS.MyWSWindowsService.StartService() in C:\Projects\Odyl\OdylUtilities\MyWS\MyWSWindowsService.cs:line 45].
As you can see, it has some problem with writing to the eventlog (all that AUXSOURCE stuff), but the main problem is that it's getting a timeout error from the web service.
Here's the truly odd thing, though -- from my dev box (running XP), I can call the web service that's running on my Windows 2003 Server box. This is really perplexing -- obviously the web service is working fine, but for some reason, Windows Server 2003 will not let you call a web service from the same machine!
Can anybody please give me a hint as to what's going on?
This sounds like a networking issue related to your Win2K3 server. The network configuration is preventing it from accessing the service url at the given location.
Easiest way to troubleshoot this: RDP to the Win2K3 Server desktop and open up a web browser to connect to the web service. I expect you will get a timeout.
Easiest way to remedy this: if there is a URL to the service that works locally, i.e. localhost, try that from your service. Otherwise, be prepared to get your network administrator involved to understand the DNS settings necessary to support the URL path you want to use for your service.