PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

sybperl-l Archive

Up    Prev    Next    

From: andrew dot x dot dear at jpmchase dot com
Subject: sybperl occasionally causes script to 'die' when cancelling a query
Date: Jun 5 2008 9:55AM

(Apologies if this appears twice - I did could not see the first send on 
the list).

Hi. I have a daemon script which runs sql and sets up a timeout in case 
the sql gets stuck due to a problem on the server (usually in the ct_fetch 
loop). At that point the msg_cb cancels the query and the rest of the 
script should carry on.

Often this works fine, however occasionally the perl script dies - which 
is bad news for our daemon script - and it looks like this 'die' is called 
from within sybperl. Here are the error messages received by the 
msg_handler (where everything has 'Error:' or 'Info:' prepended) and the 
final 'die' message (which has nothing prepended and so does not come from 
our handlers):

Info: Cancelling query on dbh.
Error: Client Message: 6, Severity 5, Origin 3
Error: ct_fetch(): network packet layer: internal net library error: 
Net-Library operation terminated due to disconnect
Error: Client Message: 0, Severity 0, Origin 0
Error: ct_cancel(): unable to get layer message string: unable to get 
origin message string: error string not available
ct_cancel() failed - dying at /home/edgdba/bin/spid line 2433.

Looking a little deeper I can see this final message in CTlib.so:

strings CTlib.so | grep cancel
Sybase::CTlib::ct_cancel
ct_cancel() failed - dying

Tested on Perl 5.8.4/Sybperl 2.17       and     Perl 5.10.0/Sybperl 2.18

Are there any plans to get rid of this 'die' call in the sybperl library? 
Do you know how I can avoid it? (short of calling ct_fetch in an eval, 
which - while I haven't tried it - doesn't look too pleasant or correct).

Finally here is the msg_cb code snippet dealing with the timeouts:


sub msg_cb
{
        my($layer, $origin, $severity, $number, $msg, $osmsg, $dbh) = @_;
-
-
-
-
        # Handle query timeout messages
        if ($layer == 1 and $origin == 2 and $number == 63) {
                $Total_blocked_secs = 0 unless $Total_blocked_secs;
                $Total_blocked_secs += $Sql_timeout;

                if (!defined($dbh) or $dbh->DBDEAD()) {
                        # This is a connection timeout
                        out("\nInfo: Connection attempt has been blocked 
for the last $Total_blocked_secs seconds.\n");
                        if ( $Total_blocked_secs >= $Max_blocked_secs ) {
                                # Cancel the connection attempt
                                out("\nError: Connection attempt blocked 
for longer than max allowed time ($Max_blocked_secs secs). Cancelling 
connection attempt.\n");
                                return CS_FAIL;
                        } else {
                                return CS_SUCCEED;      # Keep trying
                        }
                } else {
                        # This is a query timeout
                        our ($Current_sql_section);
                        out("\nInfo: Spid sql query has been blocked on 
the server (processing section $Current_sql_section) for the last 
$Total_blocked_secs seconds.\n");

                        if ( $Total_blocked_secs >= $Max_blocked_secs ) {
                                # Cancel the query and force a reconnect
                                out("\nError: Query blocked on server 
(processing section $Current_sql_section) for longer than max allowed time 
($Max_blocked_secs secs). Cancelling query and reconnecting.\n");

                                # Use ATTN, not ALL since we're in a 
handler
                                if (defined $dbh ) {
                                        out("\nInfo: Cancelling query on 
dbh.\n");
                                        $dbh->ct_cancel(CS_CANCEL_ATTN);
                                } else {
                                        # We don't always get $dbh, so try 
our main connection otherwise
                                        out("\nInfo: Cancelling query on 
Con.\n"), $Con->ct_cancel(CS_CANCEL_ATTN) if defined($Con);
                                }

                                # Don't actually close the connection here 
- let it complete the message and
                                # this script will reconnect
                                $Connection_dead = $true;
                                $Status = "TIMED_OUT";
                                return CS_SUCCEED;
                        } else {
                                return CS_SUCCEED;      # Continue for now
                        }
                }
        }


Thanks for any help.

Andrew

-----------------------------------------
This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.

This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.

Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to UK legal entities.