Detecting a closed connection - grails

I have an Grails application which does the following:
When a request is received from the client side, the server starts creating a zip file for that request and sends it back to the client machine. The amount of time the server takes in order to create the zip file is very high, and even though the connection is lost between the client and the server, the zip file is generated by the server continuously for 3 days or so, using 100% of the CPU, and sending the response somewhere, probably a dead-end.
I tried looking out a way to resolve this, and I find that socket programming is a way in order to detect the connection loss.
This question may look broad, but I just want to know the ways, a connection loss can be found out, so that I can dig around that approach and find out the solution.

Check if the object holding the results of the connect() method is null.
You can also wrap a try catch statement around the code that attempts the connection, and print out the exception if it fails so you know where/what happened.

Related

Firebird ISC ERROR CODE:335544721

We have had this error recently reported by our clients and we on't know how we can fix this. We are using Delphi XE6 to develop our application and it connect to Firebird (v2.5) database as back-end. We also have used IBObjects for working with Firebird database in Delphi.
We have managed to replicate the error on the dev machine by stopping Firebird windows service before running a query but we haven't found a way to detect the connection lost in the code (e.g. by having an event) so as we don't know when this happens so we cannot reconnect to the database in the code either.
By the way, this is full error message if it helps:
ISC ERROR CODE:335544721
ISC ERROR MESSAGE:
Unable to complete network request to host "BON-VFS-01".
Error writing data to the connection.
Any help really appreciated.
From IBOBjects FAQ
Is there a way to detect a lost connection and try to reconnect
automatically, without user action?
Hook into the OnError event and look for the ERRCODE that denotes a
lost connection. Then, you can take whatever action you deem necessary
to deal with the problem. If the connection is lost you need to do a
disconnect and then connect again.
And from one of the base members of the IBObjects:
However, perhaps the "something" you are missing is that, if the
connection is broken by an external cause, the client application has
no way to know that it is not still connected. Its first knowledge of
that fact will come the next time it tries to access the server. The
API will report "Connection lost to database" and return GDSCODE
335544741, which is identified by the constant
isc_lost_db_connection.
At the point where this exception occurs, the TIB_Connection still
thinks it is connected - the Connected property will be true. If you
try to reconnect by calling Connect, you will get an IBO exception.
It is necessary to call Disconnect. This does not simply reset a
property. The Disconnect method performs all of the necessary cleanup
to invalidate the broken transactions and cancel any now invalid
postings, datasets and caches. Once Disconnect has completed its
work, you can then place a Connect call inside a retry loop and
attempt to get going again.
I do not know of a working example, but the simplest way to deal with
this is to write a RestoreConnection handler procedure that you can
call from your IB_Session.OnError handler whenever argument ERRCODE
returns isc_lost_db_connection.
Have your RestoreConnection procedure do whatever you need to do,
trying to call Connect and handling the exception that occurs if the
request fails, until no exception occurs. Test the Connected property
after each iteration. When Connected is finally True, you are in
business. You can drop out of the retry code and inform the user that
the connection has been restored - perhaps with a sound and/or a
message in the status bar, to avoid having to show a dialog box that
she has to respond to. (if you like the idea of sound and status bar
cues, you could devise "connection lost" warning sound and status bar
message code to run at the beginning of your handler procedure as
well...)
If these broken connections are a frequent occurrence, you might like
to consider making a distinctive custom cursor that you can display
while your procedure is running, and enclose the retry code in a
non-yielding BeginBusy...EndBusy block with UseCursor enabled and
BusyCursor set to use this special cursor image.
And if re-establishing a connection is likely to take a long time, or
to be temporarily impossible, you would need to provide the ability
for the user to intervene and choose not to keep trying. You can use
the session timer for this, enclosing your "busy" block inside
another iterative block the prompts the user to "Cancel" or "Keep
Trying", at reasonable intervals.
Source
Check out if their database file is located on mapped network drive. Even if database file path appear to be local to file system, when using embedded Firebird server, function isc_attach_database will return error code 335544721 on attempt to establish connection. Exactly that was happening on my VirtualBox guest Windows XP when I first share entire host D drive and then mapped it again as D drive in virtual guest OS.
Workaround will be to move database file to local partition drive.
check your query length
max query length is 8191 chars UTF-8
its solved my problem
connect your pc to the internet, and the problem will be fixed,but i don't how it works

Raknet connection issue on Unity3D + iOS (il2cpp)

I have weird issue running the last version of Raknet on iOS with Unity3D: I get CONNECTION_ATTEMPT_FAILED when trying to connect to the server.
Now let's me detail the issue:
he exact same Library connects fine when used in an ObjectiveC application, so the issue seems to be Unity3D related.
I already managed to pinpoint my issue to be located in Raknet reliability layer:
Apparently, during the last step of the connection process (when the connection handshake as been completed) the reliability layer of the server thinks that the ID_CONNECTION_REQUEST packet received from the client is an acknowledgment instead of a message. Therefore it doesn't answer. Ultimately after a few tries, (and a 10s timeout) the client fails with the CONNECTION_ATTEMPT_FAILED error.
Does anybody there as an idea? I will update the question when I manage to get more info.
Update
We are using Unity3D 5.1.1f1
We managed to find a workaround! See answer for more information. As the workaround doesn't tell us much about what really happened, I would gladly hear some C++/XCode/Unity/iOS/AppleLLVM6.1 experts around here explain what really happened.
The issue was that the Raknet header wasn't properly generated by the iOS client. Namely we were sending ACK messages in place of simple packets. The rest of the message was considered as garbage by the server and the packet was dropped. The client kept trying to send the corrupted handshake packet a few times before timeouting.
This doesn't tell us why, doesn't it? Apparently the serialize method of the class DatagramHeaderFormat wasn't called as it should have been when running Raknet in Unity (iOS). Something else (and I don't know what) was linked in place of this method and was filling the BitStream with a corrupted header.
I am quite sure that the serialize method wasn't called because printf calls from inside weren't displayed in the console.
We renamed DatagramHeaderFormat::serialize into DatagramHeaderFormat::serializeHeader and... voila, it works.
Now I only want to understand what did the compiler (and why).

Detect "Delay write failed" occurence

I am loosing my patience with "delay write failed" errors. It silently disconnects the database from the application so nothing gets saved in the database while using it. Is there a way to detect the occurrence itself so I can flash a warning ? Or perhaps monitoring the connection itself for a disconnection ? Everyone seems to miss the balloon tip from the Windows XP so I figured to flash a more visible warning that the application must be restarted. It seems Microsoft has found a way to force people to upgrade....
I suppose this could be done with a timer and constantly check connected users:
cxlabel1.Caption := IntToStr(DataModule2.ABSDatabase1.GetDBFileConnectionsCount);
But I was thinking more of checking/detecting for the occurence itself. Is there something in Delphi that can detect this?
I would like to hear your ideas on this...
Putting this as an answer because the comment length is limited.
I have seen this before. IIRC, the problem you have is that the Delayed Write Error is an OS error, it has nothing to do with your application. Windows has already told you that the write has been committed correctly to disk. You would have to try and hook into the OS errors to see when this is happening.
You need to get the network issues resolved because that's where the problem is. In our situation it was a faulty router that was causing the problem.
It's unfair to expect users to check for the error message and then handle it. They could be out at lunch when it occurs as it's not immediate. They also have no way of know what has been saved and what hasn't. It's only a matter of time before your database is corrupted.
The problem with a timer is that it might tell you everything is fine because it triggers after the network resolves the problems.
A far better approach would be to switch to a Client/Server database. You can do this by setting up your own server that listens for web service or another remote call or switch to a database that supports client/server instead of using a file based database. This will tell you immediately when there is a problem with the save of data.

Set a timeout for a slow network connection in iOS?

I have a JSON database connection for my app, and it is set to load (refresh) on the app's initial launch. The JSON data is stored on the phone, and retrievable if no internet connection is discovered on relaunching the app--so there's always data in there.
If the user has a slow connection to the internet--as in patchy <3G--the app will hang. I would like to set a timeout that reverts the database to the saved information (as it would if there were no connection at all). Unfortunately, I think that setting the timeout in the wrong function could make the app crash.
I've read there's no publicly available class to determine a connection speed, but can anyone suggest alternatives?
You could set a timeout for the NSURLRequest, if thats what you're using. In the callback that handles the timeout you could fall back to your local copy of the data. Check the following answer provided by another user.
NSURLConnection timeout?
If you wanted to determine the actual connection speed, you could have your app download a piece of arbitrary data of fixed length, and record the time it takes to complete. This has its own flaws though. You would have to decide when to do this, and how frequently. It may also suffer from the problem that you are trying to solve. And, for example, if the user was on a train, their connection may be great one moment, and poor the next. I think that the timeout solution would work ok, it just means that the user has to wait a period of time before the app falls back to the local copy of the data.

How can I detect dropped connection with CFStream/NSStream?

Here's the setup:
I have an input stream created with CFReadStreamCreateForStreamedHTTPRequest. It has the kCFStreamPropertyHTTPAttemptPersistentConnection property set (I'm pooling connections). The server I'm connecting to is returning data with chunked encoding.
Everything works well in our normal case. My problem is that the server I'm talking to drops my connection if there are any problems. For the life of me I can't figure out how to detect the dropped connection.
In my stream's event callback I just see kCFStreamEventEndEncountered but no error is ever reported even though in Wireshark I can clearly see that the connections are getting FIN long before the end-of-stream chunked encoding marker is sent.
It seems like I should be getting a kCFURLErrorNetworkConnectionLost error event when the server drops the connection but I just get end-encountered.
Any suggestions greatly appreciated.
It took some digging but it turns out that this is, in fact, a problem with CFNetwork. I went back to the 10.4.10 Darwin sources and found this comment in CFHTTPFilter.c
// Premature end of stream. However, some servers send simply CRLF for their last chunk instead of 0CRLF; be tolerant of this.
So it seems that the built-in HTTP chunk decoder in iOS and OS X will consider a dropped connection to be orderly (and not report an error) if it successfully read the CRLF after the chunked data block and there are no more bytes outstanding in the buffer.

Resources