[svn:dbd-oracle] r15295 - in dbd-oracle/trunk: . lib/DBD

[email protected] Tue, 24 Apr 2012 02:25:21 -0700 (PDT)
Newsgroups perl.dbd.oracle.changes
Message-ID <[email protected]>
Author: mjevans
Date: Tue Apr 24 02:25:19 2012
New Revision: 15295

Modified:
   dbd-oracle/trunk/Changes
   dbd-oracle/trunk/Oracle.xs
   dbd-oracle/trunk/dbdimp.c
   dbd-oracle/trunk/lib/DBD/Oracle.pm
   dbd-oracle/trunk/oci8.c

Log:
Export OCI_FO_RETRY in :ora_fail_over
Add debug for taf function name and sleep values
Fix taf example wrt taf_sleep => ora_taf_sleep
In TAF don't do retries unless OCI_FO_RETRY returned from handler


Modified: dbd-oracle/trunk/Changes
==============================================================================
--- dbd-oracle/trunk/Changes	(original)
+++ dbd-oracle/trunk/Changes	Tue Apr 24 02:25:19 2012
@@ -16,6 +16,11 @@
 
  - skip 24implicit_utf8.t if chr set is not UTF-8 (Martin J. Evans)
 
+ - Fixed RT76268 - ora_taf_sleep was documented as taf_sleep by
+   accident. There was no way to stop the TAF reconnect attempts.
+   If you want to try another connect attempt in your taf handler you
+   now need to return OCI_FO_RETRY from it. (Martin J. Evans)
+
  [MISCELLANEOUS]
 
  - minor change to confusing debug output for input parameters

Modified: dbd-oracle/trunk/Oracle.xs
==============================================================================
--- dbd-oracle/trunk/Oracle.xs	(original)
+++ dbd-oracle/trunk/Oracle.xs	Tue Apr 24 02:25:19 2012
@@ -59,6 +59,7 @@
 	OCI_FO_SESSION			= OCI_FO_SESSION
 	OCI_FO_SELECT			= OCI_FO_SELECT
 	OCI_FO_TXNAL			= OCI_FO_TXNAL
+	OCI_FO_RETRY			= OCI_FO_RETRY
 	OCI_STMT_SCROLLABLE_READONLY 	= 0x08
 	OCI_PRELIM_AUTH 		= 0x00000008
 	OCI_DBSTARTUPFLAG_FORCE 	= 0x00000001

Modified: dbd-oracle/trunk/dbdimp.c
==============================================================================
--- dbd-oracle/trunk/dbdimp.c	(original)
+++ dbd-oracle/trunk/dbdimp.c	Tue Apr 24 02:25:19 2012
@@ -487,7 +487,6 @@
 		imp_dbh->taf_sleep = 5; /* 5 second default */
 
     	DBD_ATTRIB_GET_IV( attr, "ora_taf_sleep",  13, svp, imp_dbh->taf_sleep);
-
 		if ((svp=DBD_ATTRIB_GET_SVP(attr, "ora_taf_function",  16)) && SvOK(*svp)) {
 			STRLEN  svp_len;
 			if (!SvPOK(*svp))
@@ -495,6 +494,11 @@
 			imp_dbh->taf_function = (char *) SvPV (*svp, svp_len );
 
 		}
+        if (DBIc_DBISTATE(imp_dbh)->debug || dbd_verbose >= 3)
+            PerlIO_printf(
+                DBIc_LOGPIO(imp_dbh),
+                "taf sleep = %d, taf_function = %s\n",
+                imp_dbh->taf_sleep, imp_dbh->taf_function ? imp_dbh->taf_function : "");
 	}
 
     imp_dbh->server_version = 0;

Modified: dbd-oracle/trunk/lib/DBD/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/lib/DBD/Oracle.pm	(original)
+++ dbd-oracle/trunk/lib/DBD/Oracle.pm	Tue Apr 24 02:25:19 2012
@@ -39,7 +39,7 @@
     	ora_exe_modes     => [ qw( OCI_STMT_SCROLLABLE_READONLY)],
     	ora_fail_over     => [ qw( OCI_FO_END OCI_FO_ABORT OCI_FO_REAUTH OCI_FO_BEGIN
     				   OCI_FO_ERROR OCI_FO_NONE OCI_FO_SESSION OCI_FO_SELECT
-    				   OCI_FO_TXNAL)],
+    				   OCI_FO_TXNAL OCI_FO_RETRY)],
     );
     @EXPORT_OK = qw(OCI_FETCH_NEXT OCI_FETCH_CURRENT OCI_FETCH_FIRST OCI_FETCH_LAST OCI_FETCH_PRIOR
     		    OCI_FETCH_ABSOLUTE 	OCI_FETCH_RELATIVE ORA_OCI SQLCS_IMPLICIT SQLCS_NCHAR ora_env_var ora_cygwin_set_env );
@@ -1251,7 +1251,7 @@
 =item :ora_fail_over
 
   OCI_FO_END OCI_FO_ABORT OCI_FO_REAUTH OCI_FO_BEGIN OCI_FO_ERROR
-  OCI_FO_NONE OCI_FO_SESSION OCI_FO_SELECT OCI_FO_TXNAL
+  OCI_FO_NONE OCI_FO_SESSION OCI_FO_SELECT OCI_FO_TXNAL OCI_FO_RETRY
 
 =back
 
@@ -1415,7 +1415,7 @@
   #set up TAF on the connection
   # NOTE since DBD::Oracle uses call_pv you may need to pass a full
   # name space as the function e.g., 'main::handle_taf'
-  my $dbh = DBI->connect('dbi:Oracle:XE','hr','hr',{ora_taf=>1,taf_sleep=>5,ora_taf_function=>'handle_taf'});
+  my $dbh = DBI->connect('dbi:Oracle:XE','hr','hr',{ora_taf=>1,ora_taf_sleep=>5,ora_taf_function=>'handle_taf'});
 
   #create the perl TAF event function
 
@@ -1444,6 +1444,9 @@
     }
     elsif ($fo_event == OCI_FO_ERROR){
        print " Failover error Sleeping...\n";
+       # DBD::Oracle will sleep for ora_taf_sleep if you return OCI_FO_RETRY
+       # If you want to stop retrying just return 0
+       return OCI_FO_RETRY;
     }
     else {
        printf(" Bad Failover Event: %d.\n",  $fo_event);
@@ -1557,10 +1560,15 @@
      return;
   }
 
+Note you'll probably have to use the full name space when setting the
+TAF function e.g., 'main::my_taf_function' and not just
+'my_taf_function'.
+
 =head4 ora_taf_sleep
 
-The amount of time in seconds the OCI client will sleep between attempting
-successive failover events when the event is OCI_FO_ERROR.
+The amount of time in seconds DBD::Oracle will sleep between attempting
+successive failover events when the event is OCI_FO_ERROR and OCI_FO_RETRY
+is returned from the TAF handler.
 
 =head4 ora_session_mode
 

Modified: dbd-oracle/trunk/oci8.c
==============================================================================
--- dbd-oracle/trunk/oci8.c	(original)
+++ dbd-oracle/trunk/oci8.c	Tue Apr 24 02:25:19 2012
@@ -1308,6 +1308,8 @@
 taf_cbk(dvoid *svchp, dvoid *envhp, dvoid *fo_ctx,ub4 fo_type, ub4 fo_event )
 {
 	dTHX;
+    int return_count;
+    int ret;
 	taf_callback_t *cb =(taf_callback_t*)fo_ctx;
 
 	dSP;
@@ -1315,8 +1317,15 @@
 	XPUSHs(sv_2mortal(newSViv(fo_event)));
 	XPUSHs(sv_2mortal(newSViv(fo_type)));
 	PUTBACK;
-	call_pv(cb->function, G_DISCARD);
+	return_count = call_pv(cb->function, G_SCALAR);
 
+    SPAGAIN;
+    
+    if (return_count != 1)
+        croak("Expected one scalar back from taf handler");
+
+    ret = POPi;
+    
 	switch (fo_event){
 
 		case OCI_FO_BEGIN:
@@ -1328,8 +1337,10 @@
 		}
 		case OCI_FO_ERROR:
 		{
-			sleep(cb->sleep);
-			return OCI_FO_RETRY;
+            if (ret == OCI_FO_RETRY) {
+                sleep(cb->sleep);
+                return OCI_FO_RETRY;
+            }
 			break;
 		}
 
@@ -1338,6 +1349,8 @@
 			break;
 		}
 	}
+    PUTBACK;
+    
 	return 0;
 }