File Coverage

blib/lib/Test/mysqld/Pool.pm
Criterion Covered Total %
statement 15 61 24.5
branch 0 16 0.0
condition 0 3 0.0
subroutine 5 13 38.4
pod 0 3 0.0
total 20 96 20.8


line stmt bran cond sub pod time code
1             package Test::mysqld::Pool;
2 1     1   6 use strict;
  1         2  
  1         22  
3 1     1   4 use warnings;
  1         2  
  1         20  
4 1     1   404 use Mouse;
  1         23250  
  1         4  
5 1     1   734 use Test::mysqld;
  1         34678  
  1         31  
6 1     1   589 use Cache::FastMmap;
  1         4540  
  1         716  
7              
8             has jobs => ( is => 'rw', isa => 'Int', );
9             has share_file => ( is => 'rw', isa => 'Str', required => 1 );
10             has cache => ( is => 'rw', lazy => 1,
11             default => sub {
12             my ($self) = @_;
13              
14             # only need this for atomical get_and_set
15             # is there anything better?
16              
17             # dont let Cache::FastMmap delete the share_file,
18             # File::Temp does that
19             return Cache::FastMmap->new(
20             share_file => $self->share_file,
21             init_file => 0,
22             empty_on_exit => 0,
23             unlink_on_exit => 0,
24             cache_size => '1k',
25             );
26             });
27             has preparer => ( is => 'rw', isa => 'Maybe[CodeRef]' );
28             has my_cnf => ( is => 'rw', isa => 'HashRef',
29             default => sub {
30             {
31             'skip-networking' => '', # no TCP socket
32             };
33             } );
34             has instances => ( is => 'rw', isa => 'ArrayRef' );
35             has _owner_pid => ( is => 'ro', isa => 'Int', default => sub { $$ } );
36              
37             sub prepare {
38 0     0 0   my ($self) = @_;
39              
40 0           my @instances = Test::mysqld->start_mysqlds($self->jobs, my_cnf => $self->my_cnf);
41 0           $self->instances( \@instances );
42              
43 0           my $orig = $SIG{INT};
44             $SIG{INT} = sub {
45 0     0     Test::mysqld->stop_mysqlds(grep {defined($_)} @instances);
  0            
46 0 0         $self->instances([]) if $self;
47 0 0         if ($orig) {
48 0           $orig->();
49             } else {
50 0           $SIG{INT} = 'DEFAULT';
51 0           kill INT => $$;
52             }
53 0           };
54              
55 0 0         if ($self->preparer) {
56 0           $self->preparer->($_) for @instances;
57             }
58              
59 0           $self->cache->clear;
60             $self->cache->set( dsns => {
61 0           map { $_->dsn => 0 } @instances
  0            
62             });
63             }
64              
65             sub alloc {
66 0     0 0   my ($self) = @_;
67              
68 0           my $ret_dsn;
69 0           do {
70             $self->cache->get_and_set( dsns => sub {
71 0     0     my ($key, $val) = @_;
72              
73 0           for my $dsn (keys %$val) {
74 0 0         if ( $val->{ $dsn } == 0 ) {
75             # alloc one from unused
76 0           $ret_dsn = $dsn;
77 0           $val->{ $dsn } = $$; # record pid
78 0           return $val;
79             }
80             }
81              
82 0           return $val;
83 0           });
84              
85 0 0         return $ret_dsn if $ret_dsn;
86              
87 0           sleep 1;
88              
89             } while ( ! $ret_dsn );
90             }
91              
92             sub dealloc_unused {
93 0     0 0   my ($self) = @_;
94              
95             $self->cache->get_and_set( dsns => sub {
96 0     0     my ($key, $val) = @_;
97 0           for my $dsn (keys %$val) {
98              
99 0 0         my $pid = $val->{ $dsn }
100             or next;
101              
102 0 0         if ( ! $self->_pid_lives( $pid ) ) {
103 0           $val->{ $dsn } = 0; # dealloc
104             }
105             }
106              
107 0           return $val;
108 0           });
109             }
110              
111             sub _pid_lives {
112 0     0     my ($self, $pid) = @_;
113              
114 0           my $command = "ps -o pid -p $pid | grep $pid";
115 0           my @lines = qx{$command};
116 0           return scalar @lines;
117             }
118              
119             sub DESTROY {
120 0     0     my $self = shift;
121 0 0 0       Test::mysqld->stop_mysqlds(grep { defined($_) } @{$self->instances})
  0            
  0            
122             if $self->instances && $$ == $self->_owner_pid;
123             }
124              
125             1;
126              
127             __END__