Skip to Content.
Sympa Menu

freetds - [freetds] SOLVED: timeouts

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "James K. Lowden" <jklowden AT freetds.org>
  • To: TDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: [freetds] SOLVED: timeouts
  • Date: Mon, 15 Jan 2007 00:33:06 -0500

If you've been following the list at all lately, you know Frediano and I
have been working on timeout logic. The history of this part of the
project isn't particularly pretty. Like a lot of things, it got attention
when someone got around to it, and only enough attention to fix the
immediate problem. It's a hard problem, IMHO, because you have to know
something about tcp/ip networking, something about SQL Server and TDS,
something about the API definitions, and quite a bit about our
implementation.

A lot of FreeTDS can be coded simply by reading the documentation and
writing conformant code. A fair bit of libtds involves adhering to the
protocol, seeing what the server sends and responding such that it doesn't
close the connection. There's also a chunk that prepares or parses
packets. The networking part is quite small: counted in lines of code,
net.c is only 6% of libtds.

Apart from technical knowledge, errors from network timeouts are difficult
to handle because each client library has its own way to do it. ODBC is
the simplest: the application sets a timeout value and the login/query
succeeds or fails, period. ct-lib is the closest to the wire: the
application can catch the error and, if it so chooses, send a cancel
packet or tell libtds to break the connection. db-lib has an ungainly set
of options that make sense only if you spend a lot of time understanding
their implications. db-lib and ct-lib share the capability of installing
a callback for errors that can direct the library.

Over the years I've posted pleas from time to time for some network expert
to swoop in and fix the timeout logic. No one did. Little did I know
that networking knowledge was less than half the battle. Now that I've
done it, I can say it's not that hard to learn tcp/ip basics and how to
use non-blocking sockets. The real work was to define an interface to
libtds suitable to all the client libraries, and to make them use it.

That work I now declare done. Timeouts work as specified. If you write
your handler correctly, you can tell libtds to keep waiting as long as you
want to, request it cancel the pending request, or tell it to give up and
close the connection. If you set a timeout of 20 seconds and pull out the
wire, your db-lib handler will get SYBETIME 20 seconds later. After that,
it's up to you.

As an added bonus, dbsettime() works, too. So you can write your own
interrupt handler if you want to. I wonder if there's a single
application out there waiting for that feature. We could also have
dbsetidle() and dbsetbusy(). Someone has to ask, though. dbpoll() is
possible, too, and only a little more work.

ODBC's specification is a little vague. Probably if you set a query
timeout of 20 seconds and pull the wire, you'll get a failure in 40
seconds, because when the timer expires the library will make one
good-faith effort to cancel the pending request (which will itself timeout
20 seconds later). I'm sure Frediano made a sensible choice in any case.

As it happens, my own use of FreeTDS doesn't depend on timeouts working
correctly. I created my own itch, if you will; I didn't like the
perplexed messages that show up on this list every few months saying that
timeout didn't seem to work right. A person can waste a lot of time
before coming to the conclusion that it's FreeTDS's fault. Fixing the
code was my little act of mercy.

So, Happy New Year. Thanks for listening, and enjoy your subtly improved
library.

--jkl




Archive powered by MHonArc 2.6.24.

Top of Page