Subject Re: [IBO] lost connection
Author Helen Borrie
At 12:58 AM 12/08/2005 +0000, you wrote:
>Hi All,
>I'm trying to recover from lost connection failures, have read the FAQ
>entry on hooking to OnError event handler, but it seems I'm still
>missing something. I also did a search in the samples folder, but
>failed to understand the example I've found on DM_UCCsync.pas.
>The connections are created on demand, at runtime, and are meant to
>stay connected until the application exits.
>Can someone put me in the right track, please, perhaps by pointing to
>an working example?
>IBO 4.2Ie, D5, FB 1.52

As you rightly observe, connections are expected to stay in a Connected
state until they are explicitly Disconnected by the application.

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 doesn't 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 don't 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

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.