Timeout

CS_TIMEOUT specifies the length of time, in seconds, that Client-Library waits for a server response to a command.

The default timeout value is CS_NO_LIMIT, which represents an infinite timeout period. Negative and zero values are not allowed for CS_TIMEOUT.


Setting timeout values

ct_config is called to set the timeout value before or after a call to ct_connect creates an open connection. It takes effect for all open connections immediately upon being called.

The following code fragment sets a 60-second timeout limit:

CS_INT timeval;
 timeval = 60;
 if (ct_config(ctx, CS_SET, CS_TIMEOUT, 
             (CS_VOID *)&timeval,
             CS_UNUSED, NULL) 
     != CS_SUCCEED)
 {
   fprintf(stdout,“Can't config timeout. Exiting.“); 
   (void)ct_exit(ctx, CS_FORCE_EXIT);
   (void)cs_ctx_drop(ctx);
   exit(1);
 }

Handling timeout errors

Timeout errors occur in synchronous applications that have set either or both of the CS_TIMEOUT or CS_LOGIN_TIMEOUT properties to values other than CS_NO_LIMIT. CS_LOGIN_TIMEOUT sets the timeout period for reading the server’s response to a login attempt, while CS_TIMEOUT sets the timeout period for reading the results of a server command. The application receives the same Client-Library message for timeouts in both cases. (See “Login timeout” for a description of the CS_LOGIN_TIMEOUT property).

Applications that use inline error handling must set the CS_DIAG_TIMEOUT property to specify whether Client-Library should abort or retry when a timeout occurs. See “Diagnostic timeout fail” for more information.

Applications that handle Client-Library messages with a callback can identify the timeout error and either cancel the operation or retry for another timeout period. A client message callback has the following options for handling a timeout message:

A timeout error is identified by breaking the error number (identified by the number field of the CS_CLIENTMSG structure) into its four components and checking whether the error number matches the following characteristics:

An application breaks an error number into components with the CS_SEVERITY, CS_NUMBER, CS_ORIGIN, and CS_LAYER macros. See “Client-Library message numbers” for a description of these macros. An example of testing for timeout errors is provided below.

The callback checks the value of the CS_LOGIN_STATUS connection property to see whether the timeout is happening during connection establishment or during command processing. If the property is CS_TRUE, the connection is already established and the server has timed out during command processing.

The following code fragment defines a client message callback that handles timeout errors:

/*
 ** ERROR_SNOL(error_numb, severity, number, origin, layer)
 **
 **   Error comparison for Client-Library or CS-Library errors.
 **   Breaks down a message number and compares it to the given
 **   constants for severity, number, origin, and layer.
 **   Returns non-zero if the error number matches the 4
 **   constants.
 */
 #define ERROR_SNOL(e, s, n, o, l) \
   ( (CS_SEVERITY(e) == s) && (CS_NUMBER(e) == n) \
    && (CS_ORIGIN(e) == o) && (CS_LAYER(e) == l ) )
CS_RETCODE  client_msg_handler(cp, conn, emsgp)
 CS_CONTEXT     *cp;    
 CS_CONNECTION  *conn;
 CS_CLIENTMSG   *emsgp;
 { 
   CS_RETCODE ret;   
   CS_INT     status;
   
   ... code to print message details and handle any other 
       errors besides timeout ...
 /*
   ** Is this a timeout error?
   */
   if (ERROR_SNOL(emsgp->msgnumber, CS_SV_RETRY_FAIL, 63, 2, 1))
   {
     /*
     ** Read from server timed out. Timeouts happen on synchronous
     ** connections only, and you must have set one or both of the
     ** following context properties to see them:
     **  CS_TIMEOUT for results timeouts
     **  CS_LOGIN_TIMEOUT for login-attempt timeouts
     **
     ** If we return CS_FAIL, the connection is marked as dead and
     ** unrecoverable.  If we return CS_SUCCEED, the timeout 
     ** continues for another quantum.
     **   
     ** We kill the connection for login timeouts, and send a 
     ** cancel for results timeouts. We determine which case we 
     ** have through the CS_LOGIN_STATUS property.
     */
     status = 0;
     if (ct_con_props(conn, CS_GET, CS_LOGIN_STATUS, 
                     (CS_VOID *)&status,
                      CS_UNUSED, NULL) != CS_SUCCEED)
     {
       fprintf(stdout, "ct_con_props() failed in error handler.");
       return CS_FAIL;
     }
   if (status)
     {
       /* Results timeout */
       fprintf(stdout, "Issuing a cancel on the query...\n");
       (CS_VOID)ct_cancel(conn, (CS_COMMAND *)NULL,
                          CS_CANCEL_ATTN);
     }
   else
     {   
       /* Login timeout */
       fprintf(stdout, "Aborting connection attempt...\n");
       return CS_FAIL;
     }
   }  
   return (CS_SUCCEED);
}