Jump to content
bobD

Fail faster than calling Connected := True?

Recommended Posts

Posted (edited)

Environment is current Delphi 10.4.2

FIreDac working against up-to-date network IB server.

 

I have an app that opens the database on startup. However, while calling Connected := True is fine if it works, it can take seeming-forever to fail if the server can't be reached. Is there a faster call in FD/IB to make sure that a network server can be reached?

My standing practice has been to call FileExists(<db or marker file>) as a simple precheck on a connection, but that doesn't work in this case because the server does not publish its existence. FB can connect, but the server doesn't show up in standard network browsing. So if you type in a server location in FileExplorer it will request connection credentials, but FileExists simply fails. I haven't found an access-credentialed version of DirectoryExists or FileExists that I can use.

Thanks for any help/pointers,

bobD 

 

 

 

Edited by bobD

Share this post


Link to post

I think your only option is to lower the connection timeout if you want it to fail faster. The timeout is there for a reason so lowering it will also mean that you become less resistant against connection issues.

 

Don't try to use the file system to verify the existence of the DB server. The server might not have the required ports open or the file sharing service available. Perfectly normal (and good sense) for a DB server.

 

You could try to do a ping against the server but again, there's no guarantee that the ICMP service is available and you will still have the same problem of not knowing if lack of response means the server is down or if it's simply a transient connection issue.

Share this post


Link to post
Posted (edited)

All checks except the actual connect to the base you want are unreliable. Show splash screen if your app is useless without DB or connect in background thread otherwise.

Edited by Fr0sT.Brutal

Share this post


Link to post
41 minutes ago, Anders Melander said:

Don't try to use the file system to verify the existence of the DB server. The server might not have the required ports open or the file sharing service available. Perfectly normal (and good sense) for a DB server.

Thanks Anders--

Home network, so the connection itself is 99.9+% reliable. The only time it can change is if I do it. What normally happens is that the laptop for whatever reason loses its wifi connection to the server. Turning wifi off and on always fixes things. And I simply don't see any failures on the wired-in desktops. So I'm perfectly fine with a file check not actually testing the connection validity, just whether the server is reachable.

Share this post


Link to post
19 minutes ago, Fr0sT.Brutal said:

All checks except the actual connect to the base you want are unreliable. Show splash screen if your app is useless without DB or connect in background thread otherwise.

Thanks Fr0st--

See my reply to Anders--Given the type of connection fails I get, I'm not actually looking for a 100% solution. Unreliable might be fine depending on why the test fails. For example, I wonder whether I can ask the router if the sever is available rather than even trying to even talk to it. The server itself doesn't publish for network browsing, nor does it even respond to pings--effectively it's stealth except for the database connection (on the standard 3050 port).

Share this post


Link to post

Here's a book to read for 10.4   If Marco took the time to write it.  We should take to time read it or at least read the stuff about connection and event and wrapping connect with try..finally.

 

Also I would look for Cary Jensen He has books and videos about client data sets that may help your app.

 

 

MC D104handbook.png

Share this post


Link to post
58 minutes ago, bobD said:

For example, I wonder whether I can ask the router if the sever is available rather than even trying to even talk to it

I'm afraid you can't. Just try to connect with a socket to addr:3050 (thus you can easily use threads/async check). Or create a thread with its own connection objects and try to request, f.ex., server props. It won't require any DB connection and will be as light as it could.

Btw, it's weird you have to wait too long. Windows has 20 sec timeout for inaccessible connect attempts.

Share this post


Link to post

Why not just set the database connection timeout to the desired max. Connecting to the server with some other method fileshare/port 3050/whatever amounts to the same thing. The only reason they can get the result faster is that they have a smaller timeout defined.

Share this post


Link to post
4 hours ago, Anders Melander said:

Why not just set the database connection timeout to the desired max. Connecting to the server with some other method fileshare/port 3050/whatever amounts to the same thing. The only reason they can get the result faster is that they have a smaller timeout defined.

I'll probably go with that for the moment. And I'll admit that 'seeming forever' is a very subjective complaint. The app normally opens with a fully populated dataset w/i a second or 2, so waiting is just waiting for inevitable exception handler.

bobD

Share this post


Link to post

When i had direct connections to DBs from applications, i would do the connection in a thread so the UI at least was responsive during a possible time-out trial.

The only solution that will cover this is a middle-tier. One could probably write a very small https server that only knows/cares about the DBs availability (sits on the same machine) and thus every now and then checks the DB. You could the make a simple request to that "database discovery service".

 

/D

Share this post


Link to post
5 hours ago, Dany Marmur said:

When i had direct connections to DBs from applications, i would do the connection in a thread so the UI at least was responsive during a possible time-out trial.

The only solution that will cover this is a middle-tier. One could probably write a very small https server that only knows/cares about the DBs availability (sits on the same machine) and thus every now and then checks the DB. You could the make a simple request to that "database discovery service".

Thanks for suggestion.

I've actually isolated the problem at this point to the WiFi connection being flaky, since the app works fine on the wired-in network machines even as the laptop fails to connect, and stopping/starting the laptop wifi service always fixes the problem. The DB machine and DB are solid as a rock.

One of the things I'm thinking about doing as the app evolves is making it briefcase-enabled by running an local DB, and having the app run locally if the server isn't available. That creates an obvious synchronization requirement of course, and hence my interest in learning about change views. But that might be way more complicated than I actually need--the data at this point is pretty stable.

Share this post


Link to post

@bobD, well, you'll have to choose "technology" from the base of your needs.

FTOMH, Some DACs have the concept of "delayed updates". Might work good with a DB without too many triggers. This is a kind of client-centered approach since the client has the logic for updating several rows at a time (deferred posts).

Then you could synchronize DBs server-wise, here comes changed views (or FB triggers) in use. Good for a database where the "main stuff" (i.e. the sychronized tables) are few and their updating not over-complicated.

None of these two approaches requires you to write a middle-tier server (perhaps you would need a server-side process with a DAC to do the actual synching but that is another thing)

A middle tier would pack a request of data into some proprietary format (yes, a ClientDataSet could be used to transport the data) and send that up the line.

For changes a middle-tier server could either work with the client using a "delta"-scheme (to only process changes) or a edit-post-scheme (communicate the events of a TDataSet).

I'm sure there are additional techniques. 

 

Share this post


Link to post

It's been a while since I last wrote a briefcase enabled database client, but AFAIR TClientDataSet has all the required functionality and doesn't require (but can use) a middle tier.

Share this post


Link to post
19 minutes ago, Anders Melander said:

AFAIR TClientDataSet has all the required functionality and doesn't require (but can use) a middle tier.

That is quite similar to what TFDQuery implements with Cached Updates.

Share this post


Link to post

For whatever reason I've never used cached updates.

Fuller context is that I have an app on my local home network that uses an IB server. There are two main failure conditions: (1) the laptop's Wifi connection to the server is wonky, or (2) I'm off traveling and not on the home network at all.  I'm currently considering three different architectural approaches as I go from simple C/S design to briefcase (or more generally a 'network-optional' design).

 

1. Use IB's built-in change views--this would be preferred if I could find a decent tutorial for getting started. Major documentation shortfall here.

2. Use a server first approach (app tries to connect to IB server, failing that it opens local IB database). Obviously that requires I write a server<-->local reconciliation routine.

3. Use a local-first approach. That removes the need for solving the network slow-fail issue, because all server communication would be confined to the background reconciliation thread.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×