File Coverage

blib/lib/Riak/Light/Timeout/SetSockOpt.pm
Criterion Covered Total %
statement 51 51 100.0
branch 14 16 87.5
condition n/a
subroutine 14 14 100.0
pod 0 4 0.0
total 79 85 92.9


line stmt bran cond sub pod time code
1             #
2             # This file is part of Riak-Light
3             #
4             # This software is copyright (c) 2013 by Weborama.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9             ## no critic (RequireUseStrict, RequireUseWarnings)
10             package Riak::Light::Timeout::SetSockOpt;
11             {
12             $Riak::Light::Timeout::SetSockOpt::VERSION = '0.12';
13             }
14             ## use critic
15              
16 1     1   60918 use POSIX qw(ETIMEDOUT ECONNRESET);
  1         35  
  1         8  
17 1     1   108 use Socket;
  1         3  
  1         649  
18 1     1   682 use IO::Select;
  1         1483  
  1         38  
19 1     1   6 use Time::HiRes;
  1         2  
  1         10  
20 1     1   553 use Riak::Light::Util qw(is_netbsd is_solaris);
  1         3  
  1         50  
21 1     1   5 use Carp;
  1         2  
  1         49  
22 1     1   4 use Moo;
  1         1  
  1         9  
23 1     1   665 use Types::Standard -types;
  1         2  
  1         20  
24              
25             with 'Riak::Light::Timeout';
26              
27             # ABSTRACT: proxy to read/write using IO::Select as a timeout provider only for READ operations.
28              
29             has socket => ( is => 'ro', required => 1 );
30             has in_timeout => ( is => 'ro', isa => Num, default => sub {0.5} );
31             has out_timeout => ( is => 'ro', isa => Num, default => sub {0.5} );
32             has is_valid => ( is => 'rw', isa => Bool, default => sub {1} );
33              
34             sub BUILD {
35              
36             # carp "This Timeout Provider is EXPERIMENTAL!";
37              
38 6 100   6 0 280 croak "NetBSD no supported yet"
39             if is_netbsd();
40             ## TODO: see https://metacpan.org/source/ZWON/RedisDB-2.12/lib/RedisDB.pm#L235
41              
42 5 100       43 croak "Solaris is not supported"
43             if is_solaris();
44              
45 4         35 $_[0]->_set_so_rcvtimeo();
46 3         105 $_[0]->_set_so_sndtimeo();
47             }
48              
49             sub _set_so_rcvtimeo {
50 4     4   9 my ($self) = @_;
51 4         22 my $seconds = int( $self->in_timeout );
52 4         18 my $useconds = int( 1_000_000 * ( $self->in_timeout - $seconds ) );
53 4         33 my $timeout = pack( 'l!l!', $seconds, $useconds );
54              
55 4 100       54 $self->socket->setsockopt( SOL_SOCKET, SO_RCVTIMEO, $timeout )
56             or croak "setsockopt(SO_RCVTIMEO): $!";
57             }
58              
59             sub _set_so_sndtimeo {
60 3     3   7 my ($self) = @_;
61 3         12 my $seconds = int( $self->out_timeout );
62 3         11 my $useconds = int( 1_000_000 * ( $self->out_timeout - $seconds ) );
63 3         13 my $timeout = pack( 'l!l!', $seconds, $useconds );
64              
65 3 100       30 $self->socket->setsockopt( SOL_SOCKET, SO_SNDTIMEO, $timeout )
66             or croak "setsockopt(SO_SNDTIMEO): $!";
67             }
68              
69             sub clean {
70 1     1 0 96 $_[0]->socket->close();
71 1         339 $_[0]->is_valid(0);
72 1         57 $! = ETIMEDOUT; ## no critic (RequireLocalizedPunctuationVars)
73             }
74              
75             sub sysread {
76 3     3 0 4 my $self = shift;
77 3 50       74 $self->is_valid
78             or $! = ECONNRESET,
79             return; ## no critic (RequireLocalizedPunctuationVars)
80              
81 3         82 my $result = $self->socket->sysread(@_);
82              
83 3 100       497341 $self->clean() unless ($result);
84              
85 3         23 $result;
86             }
87              
88             sub syswrite {
89 3     3 0 6 my $self = shift;
90 3 100       67 $self->is_valid
91             or $! = ECONNRESET,
92             return; ## no critic (RequireLocalizedPunctuationVars)
93              
94 2         734 my $result = $self->socket->syswrite(@_);
95              
96 2 50       155 $self->clean() unless ($result);
97              
98 2         8 $result;
99             }
100              
101             1;
102              
103              
104             =pod
105              
106             =head1 NAME
107              
108             Riak::Light::Timeout::SetSockOpt - proxy to read/write using IO::Select as a timeout provider only for READ operations.
109              
110             =head1 VERSION
111              
112             version 0.12
113              
114             =head1 DESCRIPTION
115              
116             Internal class
117              
118             =head1 AUTHORS
119              
120             =over 4
121              
122             =item *
123              
124             Tiago Peczenyj
125              
126             =item *
127              
128             Damien Krotkine
129              
130             =back
131              
132             =head1 COPYRIGHT AND LICENSE
133              
134             This software is copyright (c) 2013 by Weborama.
135              
136             This is free software; you can redistribute it and/or modify it under
137             the same terms as the Perl 5 programming language system itself.
138              
139             =cut
140              
141              
142             __END__