James K. Lowden
jklowden at schemamania.org
Mon Jun 14 10:10:27 EDT 2004
On Sat, 05 Jun 2004, Frediano Ziglio <freddyz77 at tin.it> wrote:
> Il mar, 2004-06-01 alle 07:36, James K. Lowden ha scritto:
> > 2. Fix login.c. Use 'connect_timeout' for the initial connection,
> > and initialize 'timeout' according to the default from freetds.conf or
> > e.g. dbsettime().
> That's not use connect_timeout to init timeout and query_timeout.
> Agreed. connect_timeout it's only used to timeout connect() call. The
> only reason to use connect_timeout to init timeout it's to implement a
> login_timeout (required by ODBC and dblib...). Was this the original
> intent ??
I don't know. From the comments, it looks like Brian's original db-lib
implementation had no timeout logic. Later, something like a timeout was
"hacked in". Nick said some time ago that it didn't look right to him,
and I agree: if it ever was right, it's not now.
> > 3. Rename 'timeout' to 'query_timeout'. Add "query timeout" as a
> > freetds.conf entry, while retaining "timeout" as an undocumented (but
> > working) alias.
> ?? why delete query_timeout than use timeout than rename timeout to
> query_timeout ??
Only because query_timeout is a better name, but timeout is more nearly
> as you can see query_timeout is not used. Well.. it's used to init
> tds->timeout in login.c... Perhaps should longquery_timeout and
> query_timeout be the same thing ??
I think so. I haven't studied ODBC timeouts. AFAIK, there are only 2
that can matter: login_timeout and query_timeout.
> The key in code it's goodread (src/tds/read.c, cfr "goodread... not so
> fine" on ML).
Thanks for the reminder.
> I don't understand why in
> login.c we set timeout and longquery_timeout based on connect_timeout...
Looks bogus to me.
> timeout is used in read.c to do polling (using chkintr and hndlintr
> fields of TDSSOCKET) and in write.c to check if server it's reading our
> data. Perhaps a write_timeout would help making things more clear ??
> query_timeout not used :(
AFAIK, the libraries define query_timeout for reads, not writes. Unless
one of the client libraries supports the notion, we shouldn't have a write
> longquery_timeout it's used in goodread to break loop. However in
> tds_read_packet if we get some bytes from goodread we continue calling
> goodread... this IMHO lead to strange behavior and timeouts. Assuming
> server returns a row every 10 seconds, timeout = 12 and
> longquery_timeout = 120 even if we get 1000000 rows libTDS continue to
> get data... Is this expected ??
As far as I'm concerned, no, it's not expected. query_timeout controls
how long we'll wait for a packet from the server. Getting *any* response
constitutes success; returning rows slowly is allowed. Only if no
response is received does the timer elapse.
query_timeout should apply between non-final packets, too. If we receive
some rows in one packet, and for some reason the server has trouble coming
up with the next packet, the client has no good way to cancel the query
unless the timeout applies.
The whole longquery_timeout logic is bogus as far as I'm concerned. All
need only measure the time between anticipated packets, to allow the
application to avoid waiting indefinitely.
> Also if goodread (in tds_read_packet)
> return <1 we close connection... opinable things... perhaps client wants
> simply to cancel is a timeout is reached... however how to signal to
> client this condition ?
Timeouts are communicated via the error handler.
When the server does not respond within the timeout period, FreeTDS is
supposed to call the client's installed error handler. For db-lib, the
error handler is passed SYBETIME. According to Sybase, the error handler
may return INT_CONTINUE, telling goodread() to try again, or it may return
INT_TIMEOUT, causing the called function (dbsqlexec(), say) to return
FAIL. Microsoft's description is slightly different.
ct-lib and ODBC define different semantics.
> Another issue concerns no-blocking socket. If we have connect_timeout
> socket it's no-blocking otherwise it's blocking; in read.c code works
> either in blocking or no-blocking (cause it always use select before
> read) however to simplify things it would better to decide blocking
We need to thoroughly understand what ct-lib needs. It offers synchronous
and asynchronous modes, so I think libtds has to support both.
> I don't like queryStarttime field name... we never used capitalized word
> to compute names... query_starttime would IMHO be better (at least one
> easy things to solve :) )
Well, at least something's easy. ;-)
More information about the FreeTDS