Managing Exceptions in Indy TIdTCPServer and TIdTCPClient
I have read in other post of this forum and in other places that in Indy components the exceptions (descendant from EIdException) are internally managed.
For this reason, in the TCPServer Execute method there is no need to use a try - catch block.
But what happens if in the TCPServer Execute method another kind of exception occurs?
In my server application, I have put a TIdTCPServer component on the main form, if something bad happens inside its Execute method and I don't manage it, the server stops.
Obviously I need the server running so I use a try - catch block and if there is an exception (any kind of exception), I restart the server.
I don't know if this is the best thing to do.
Sometimes, with the server application running in the IDE, I got the error
Project CallMonitor.exe raised exception class EIdSocketError with message 'Socket Error # 10054 - Connection reset by peer.'.
probably caused by the client running on the same computer (not in the IDE).
The application execution is blocked and If I break, code is stopped in IdStack file where there is the big READ ME!!! about exception 10038.
I press F9 and the application continues running.
For me it is not very clear what happens. My try - catch block is effective in this situation? Or is it useless or harmful?
I have to filter Indy exceptions and other exceptions?
On the client side, in my application there is a TIdTCPClient object in the main form and the connection to the server is managed in the main thread. Then there is another thread to manage communication with the server. In the communication thread Execute method I have a try - catch block and a loop in which I send a request to the server every 2 seconds or when the user asks for data and I decode the server answer.
If there is a EIdReadTimeout exception, i terminate the thread and I restart it. For other exception, I terminate the thread, I disconnect/connect the TIdTCPClient and I restart the thread.
I think this is a different situation because in the server the exception was managed inside the TIdTCPServer thread while in the client the exception is managed in a thread that just uses the TCPClient->Socket to communicate with the server, is it right?
Any answer/comment/suggestion is appreciated.
in the TCPServer Execute method there is no need to use a try - catch block. But what happens if in the TCPServer Execute method another kind of exception occurs?
ANY uncaught exception that is allowed to escape from the OnConnect or OnExecute event back into TIdTCPServer will cause the calling TIdContext thread to stop running. It will close its associated client Connection during its cleanup, firing the OnDisconnect event. And then the OnException event will be fired afterwards.
In my server application, I have put a TIdTCPServer component on the main form, if something bad happens inside its Execute method and I don't manage it, the server stops.
The server as a whole does not stop. Only the calling TIdContext thread is stopped.
Obviously I need the server running so I use a try - catch block and if there is an exception (any kind of exception), I restart the server.
It is not necessary to restart the whole server on any exception. Only on exceptions that invalidate/corrupt something that your app needs to function properly.
Sometimes, with the server application running in the IDE, I got the error
Project CallMonitor.exe raised exception class EIdSocketError with message 'Socket Error # 10054 - Connection reset by peer.'.
That is a perfectly normal socket error. That will not kill your whole server.
If you go into your IDE's debugger settings, there is an option to ignore Indy "silent" exceptions (derived from EIdSilentException, such as EIdConnClosedGracefully). Or, you can also tell the debugger specific exception types to ignore, such as EIdSocketError.
The application execution is blocked ... I press F9 and the application continues running.
Exactly. Not a fatal error. The blockage is only in the debugger, it is letting you examine the exception and decide what to do with it.
For me it is not very clear what happens. My try - catch block is effective in this situation?
The IDE debugger catches exceptions before your code does. When you press F9 to continue execution, the exception will be passed back to your code, and the appropriate catch will handle it normally.
Or is it useless or harmful?
No.
I have to filter Indy exceptions and other exceptions?
IF you catch exceptions at all, handle the ones you need, and then you should re-throw any Indy-specific exceptions you caught (all Indy exceptions are derived from EIdException for easy identification), let the server handle them. If you don't, then you should disconnect the calling Connection yourself and exit the event handler gracefully. Either way, the server will then cleanup the rest as needed.
On the client side, in my application there is a TIdTCPClient object in the main form and the connection to the server is managed in the main thread. Then there is another thread to manage communication with the server.
I would move the connection management into the worker thread as well. Connect, communicate, disconnect, repeat if needed, should all be in one thread.
In the communication thread Execute method I have a try - catch block and a loop in which I send a request to the server every 2 seconds or when the user asks for data and I decode the server answer. If there is a EIdReadTimeout exception, i terminate the thread and I restart it.
If an actual read operation times out, the state of the communication is unknown and likely unrecoverable, as you don't know which byte was the one that timed out. So you should disconnect and re-connect, not just restart the thread. The only time you wouldn't need a full re-connect is if you are handling the timeout wait yourself in between messages, and know the communication hasn't been corrupted. In which case, simply restarting the thread without a full re-connect is not likely to solve the timeout condition. It would be simpler to just re-try the wait operation again.
For other exception, I terminate the thread, I disconnect/connect the TIdTCPClient and I restart the thread.
If the connect/disconnect logic were moved into the thread, they could be done in a loop, then there would be no need to restart the thread itself. Threads are expensive to create/destroy (from the OS's perspective), so try to reuse threads when possible.
I think this is a different situation because in the server the exception was managed inside the TIdTCPServer thread while in the client the exception is managed in a thread that just uses the TCPClient->Socket to communicate with the server, is it right?
Yes.
Related
I have a running HTTP server using Undertow in an embedded fashion. One thing I cannot figure out how to do is to prevent Undertow (or XNIO) from polluting the console log with useless IOException stack traces when the client abruptly disconnects during transmission.
What I want to do is emit a one-line note, only if diagnostics are enabled, that a connection ended with an exception and which handler was executing when that occurred. There is no recovery, of course, just note the fact and move on.
Unfortunately, these appear to be caught and dumped deep in the bowels of Undertow (or XNIO)code; catch clauses in my code never see these exceptions, so they have been swallowed before control returns to my handler.
I'm basically checking all the routes via request module with mocha.
https://www.npmjs.com/package/request
I'm doing a stress test, by opening two console windows side by side and running them simultaneously. Most of the time tests are successful, but then an instant comes when the tests fail without timeout error, and from postman I've this specific route that stops responding.
it happens once in around 7 times, and I'm wondering what I could do to figure this out.
Edit:
Increased to 4 console windows running tests simultaneously, they ran fine couple of times but then start to timeout.
even no console output on app.get, app.post etc. routes.
Any suggestions?
Edit
Caught some request errors based on the suggestion within tests.
Uncaught AssertionError: { [Error: connect ECONNREFUSED]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect' } == null
The corresponding code for the above error is
request({url: endpoint + "/SignIn?emailAddress=" + emailAddress + "&password=" + password}, function (error, response, body) {
assert.equal(error, null);
Edit 2
Dig further deep with console statements and noticed the mysql connection callback was not called. Attaching a screenshot and noticing some connection limit, is it because of this? I'm using connection pools though.
logs says forcing close of threads.
Probable Answer:
This thread helped with the issue.
https://github.com/felixge/node-mysql/issues/405
I set the waitForConnections: false and then started to see the error ->
[Error: No connections available.]
so it seems to me that system was waiting for the connections but test runner didn't wait and ended up with timeout error.
It also seems there's some limit on the maximum number of connections, though I was calling release on connections after each query, not sure how this works on production systems out there? do we have a limit there?
You are running out of tcp connections. You need to make few changes in system and application level, to make it handle more load.
1. Change your connection setting to keepAlive, wherever possible.
2. On unix, you have ulimit, i.e., the maximum number of file handles that any process can hold at any instant. Remember, in unix every socket is also a file.
3. Manage your time out settings, based on the response time of your database server or another web server.
You'll have to do similar changes at each level of handling request, if you have a multi-tier architecture.
I am writing an application using NodeJS, Express, mysql, so far everything works fine, but when I run my application after sometime when mysql connection is interrupted my application throughs this exception and my application goes down.
Error: read ECONNRESET
at errnoException (net.js:901:11)
at TCP.onread (net.js:556:19)
From another stackquestion i came to know that i have to handle such uncaught exceptions like this.
process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
console.log(err.stack);
});
after this now my application does not exit, but instead it hangs up, so my question is how do I handle this exception so that mysql connection is ok even after this exception and my application does not hang up.
I'm not sure if you're using the node-mysql module for your project, but I was, and I encountered the same ECONNRESET issue. Here's a repeat of my answer on my issue:
I reached out to the node-mysql folks on their Github page and got some firm answers.
MySQL does indeed prune idle connections. There's a MySQL variable "wait_timeout" that sets the number of second before timeout and the default is 8 hours. We can set the default to be much larger than that. Use show variables like 'wait_timeout'; to view your timeout setting and set wait_timeout=28800; to change it.
According to this issue, node-mysql doesn't prune pool connections after these sorts of disconnections. The module developers recommended using a heartbeat to keep the connection alive such as calling SELECT 1; on an interval. They also recommended using the node-pool module and its idleTimeoutMillis option to automatically prune idle connections.
I found the solution and I am posting if someone else is facing the same problem this might help you guys as well.
First I caught all uncaught exceptions, which made my application not to exit abnormally.
Second the problem of hanging I had was because when server would close the connection, all my requested queries would fail and my server would simply hang up I guess its node-mysql bug, but I solved it using connecting pooling, in pooling if server close the connection its re-aquired after a second or so again so my problem was solved this way.
Here is how to make most out of node-mysql pooling
I wanted to figure out if a SSIS package would run without any problems by implementing a Health Check script task at the beginning of my package. I did this by iterating through the connection managers in the package and calling the acquireconnection method. If there is an exception acquiring connection, I handle it using catch block and assume that this error would not cause the package to fail. The package shows a successful run but an error gets logged in the “Execution Results/Progress” tab of the SSIS and leads to the failure of the corresponding ExecutePackage Task of the Parent package.
If I throw an exception explicitly within the try block, the parent package doesn’t fail. This failure seems to be happening only when an exception gets thrown by the execution of the acquire connection method.
I am looking understand why this happens and if there is a way I can prevent the parent package from failing whenever acquire connection call throws an exception. I am also open to an alternate approach to figure out if all connection managers within a package will work alright.
I'm new in OCCI programming and I have one question.
I'm writing a Linux daemon, which connetcts to an Oracle database. Sometimes database server breaks connection(or db admin kills session), in that case I catch an SQLException. My question is: how should I correctly terminate OCCI connection after catching an exception?
P.S. terminateConnection method throws the same exception and I get an endless loop or uncatched exception with programm aborting.