File Coverage

blib/lib/Cassandra/Client/Policy/Throttle/Adaptive.pm
Criterion Covered Total %
statement 20 45 44.4
branch 0 8 0.0
condition 0 13 0.0
subroutine 7 11 63.6
pod 0 3 0.0
total 27 80 33.7


line stmt bran cond sub pod time code
1             package Cassandra::Client::Policy::Throttle::Adaptive;
2             our $AUTHORITY = 'cpan:TVDW';
3             $Cassandra::Client::Policy::Throttle::Adaptive::VERSION = '0.21';
4 2     2   1754 use parent 'Cassandra::Client::Policy::Throttle::Default';
  2         5  
  2         18  
5 2     2   199 use 5.010;
  2         8  
6 2     2   10 use strict;
  2         4  
  2         63  
7 2     2   8 use warnings;
  2         5  
  2         138  
8 2     2   11 use Time::HiRes qw/CLOCK_MONOTONIC/;
  2         2  
  2         17  
9 2     2   181 use Ref::Util qw/is_blessed_ref/;
  2         5  
  2         105  
10 2     2   1044 use Cassandra::Client::Error::ClientThrottlingError;
  2         7  
  2         989  
11              
12             sub new {
13 0     0 0   my ($class, %args)= @_;
14             return bless {
15             ratio => $args{ratio} || 2,
16 0   0       time => $args{time} || 120,
      0        
17              
18             window => [],
19             window_success => 0,
20             window_total => 0,
21             }, $class;
22             }
23              
24             sub _process_window {
25 0     0     my ($self)= @_;
26 0           my $now= Time::HiRes::clock_gettime(CLOCK_MONOTONIC);
27 0   0       while (@{$self->{window}} && $self->{window}[0][0] < $now) {
  0            
28 0           my $entry= shift @{$self->{window}};
  0            
29 0           $self->{window_total}--;
30 0 0         $self->{window_success}-- if $entry->[1];
31             }
32 0           return;
33             }
34              
35             sub should_fail {
36 0     0 0   my ($self)= @_;
37 0           $self->_process_window;
38              
39 0           my $fail= ( rand() < (($self->{window_total} - ($self->{ratio} * $self->{window_success})) / ($self->{window_total} + 1)) );
40 0 0         return unless $fail;
41              
42 0           $self->count(undef, 1);
43 0           return Cassandra::Client::Error::ClientThrottlingError->new;
44             }
45              
46             sub count {
47 0     0 0   my ($self, $error, $force_error)= @_;
48              
49 0 0 0       return if is_blessed_ref($error) && $error->isa('Cassandra::Client::Error::ClientThrottlingError');
50              
51 0           $self->{window_total}++;
52 0   0       my $success= !(is_blessed_ref($error) && $error->is_timeout) && !$force_error;
53 0           push @{$self->{window}}, [ Time::HiRes::clock_gettime(CLOCK_MONOTONIC)+$self->{time}, $success ];
  0            
54 0 0         $self->{window_success}++ if $success;
55 0           return;
56             }
57              
58             1;
59              
60             __END__