Permalink
Browse files

supports retring

  • Loading branch information...
1 parent 243f186 commit ffa1a62bb92e7b82bfcc4b1761d32a157a6e731b @kazeburo committed May 24, 2011
Showing with 66 additions and 8 deletions.
  1. +41 −6 lib/Scope/Container/DBI.pm
  2. +23 −1 t/01_basic.t
  3. +2 −1 xt/01_podspell.t
View
47 lib/Scope/Container/DBI.pm
@@ -6,6 +6,8 @@ use Scope::Container;
use Log::Minimal;
use List::Util qw/shuffle/;
use Data::Dumper;
+use Try::Tiny;
+use Time::HiRes qw//;
use Class::Load qw/load_class/;
use Carp;
use DBI;
@@ -46,17 +48,28 @@ sub connect {
return $cached_dbh if $cached_dbh;
my ($dsn, $user, $pass, $attr) = @dsn;
+ $attr ||= {};
$attr->{AutoInactiveDestroy} = 1;
-
+ my $retry = exists $attr->{ScopeContainerConnectRetry} ? delete $attr->{ScopeContainerConnectRetry} : 1;
+ my $sleep = delete $attr->{ScopeContainerConnectRetrySleep};
+ $sleep = $sleep / 1000 if $sleep;
load_class $DBI_CLASS;
my $dbh = do {
- if ($INC{'Apache/DBI.pm'} && $ENV{MOD_PERL}) {
- local $DBI::connect_via = 'connect'; # Disable Apache::DBI.
- $DBI_CLASS->connect( $dsn, $user, $pass, $attr );
- } else {
- $DBI_CLASS->connect( $dsn, $user, $pass, $attr );
+ my $connect;
+ for ( 1..$retry ) {
+ try {
+ if ($INC{'Apache/DBI.pm'} && $ENV{MOD_PERL}) {
+ local $DBI::connect_via = 'connect'; # Disable Apache::DBI.
+ $connect = $DBI_CLASS->connect( $dsn, $user, $pass, $attr );
+ } else {
+ $connect = $DBI_CLASS->connect( $dsn, $user, $pass, $attr );
+ }
+ };
+ last if $connect;
+ Time::HiRes::sleep($sleep) if $sleep && $retry != $_;
}
+ $connect;
};
croak($DBI::errstr) if !$dbh;
@@ -177,6 +190,28 @@ You can give multiple dsn with arrayref, Scope::Container::DBI chooses database
=back
+
+=head1 ADDITIONAL ATTRIBUTES
+
+=over 4
+
+=item ScopeContainerConnectRetry
+
+number of connection retry, if failed connection.
+
+ my $dbh = Scope::Container::DBI->connect(
+ 'dbi:mysql:mydb;host=myhost', 'myuser', 'mypasswd',
+ { RaiseError => 1, mysql_connect_timeout => 4, ScopeContainerConnectRetry => 2 }
+ );
+
+If connection failed, Scope::Container::DBI retries 2 times internally.
+
+=item ScopeContainerConnectRetrySleep
+
+millisecond. interval seconds of connection retry.
+
+=back
+
=head1 NOTE
=over 4
View
24 t/01_basic.t
@@ -1,7 +1,7 @@
use strict;
use Test::More;
use Test::SharedFork;
-use File::Temp qw/tempfile/;
+use File::Temp qw/tempfile tempdir/;
use Scope::Container;
use Scope::Container::DBI;
@@ -19,6 +19,9 @@ use Scope::Container::DBI;
my $dbh3 = Scope::Container::DBI->connect("dbi:SQLite:dbname=$tmp1","","", { RaiseError => 1 } );
ok($dbh3);
isnt($dbh,$dbh3);
+
+ my $dbh4 = Scope::Container::DBI->connect("dbi:SQLite:dbname=$tmp1","","", { RaiseError => 1, ScopeContainerConnectRetry => 2 } );
+ ok($dbh4);
}
@@ -76,4 +79,23 @@ use Scope::Container::DBI;
unlink($tmp1);
}
+{
+ my $sc = start_scope_container();
+ my $dir = tempdir( CLEANUP => 1 );
+ chmod '0400', $dir;
+
+ my $pid = fork();
+ if ($pid == 0) {
+ sleep 1;
+ chmod '0755', $dir;
+ exit;
+ }
+
+ my $dbh = Scope::Container::DBI->connect("dbi:SQLite:dbname=$dir/foo","","", { RaiseError => 1, ScopeContainerConnectRetry => 4, ScopeContainerConnectRetrySleep => 500 } );
+ ok($dbh);
+
+ waitpid($pid,0);
+}
+
+
done_testing();
View
3 xt/01_podspell.t
@@ -13,4 +13,5 @@ DBI's
InactiveDestroy
dsn
RootClass
-
+ScopeContainerConnectRetry
+ScopeContainerConnectRetrySleep

0 comments on commit ffa1a62

Please sign in to comment.