File Coverage

blib/lib/JSON/RPC2/AnyEvent/Server/Handle.pm
Criterion Covered Total %
statement 61 69 88.4
branch 6 20 30.0
condition 2 6 33.3
subroutine 19 20 95.0
pod 2 3 66.6
total 90 118 76.2


line stmt bran cond sub pod time code
1             package JSON::RPC2::AnyEvent::Server::Handle;
2 2     2   98692 use 5.010;
  2         16  
3 2     2   9 use strict;
  2         4  
  2         56  
4 2     2   21 use warnings;
  2         5  
  2         95  
5              
6             our $VERSION = "0.03";
7              
8 2     2   816 use AnyEvent::Handle;
  2         18431  
  2         83  
9 2     2   12 use Carp qw(croak);
  2         4  
  2         88  
10 2     2   14 use Errno ();
  2         11  
  2         32  
11 2     2   1330 use JSON;
  2         19075  
  2         11  
12 2     2   278 use Scalar::Util qw(blessed reftype openhandle);
  2         4  
  2         115  
13              
14 2     2   445 use JSON::RPC2::AnyEvent::Server;
  2         5  
  2         57  
15 2     2   13 use JSON::RPC2::AnyEvent::Constants qw(ERR_PARSE_ERROR);
  2         3  
  2         870  
16              
17              
18             sub new {
19 1     1 1 4 my ($class, $srv, $hdl) = @_;
20            
21 1 50 33     14 croak "Not an JSON::RPC2::AnyEvent::Server object: $srv" unless blessed $srv && $srv->isa('JSON::RPC2::AnyEvent::Server');
22            
23 1 50 33     7 unless ( blessed $hdl && $hdl->isa('AnyEvent::Handle') ) {
24 1 50       8 $hdl = openhandle $hdl or croak "Neither AnyEvent::Handle nor open filehandle: $hdl";
25 1         6 $hdl = AnyEvent::Handle->new(fh => $hdl);
26             }
27            
28 1         72 my $self = bless {
29             hdl => $hdl,
30             srv => $srv,
31             }, $class;
32            
33             $hdl->on_read(sub{
34             shift->push_read(json => sub{
35 2         121 my ($h, $json) = @_;
36             $self->{srv}->dispatch($json)->cb(sub{
37 2         28 my $res = shift->recv;
38 2 50       26 $h->push_write(json => $res) if defined $res;
39 2         9 });
40 2     2   152 });
41 1         8 });
42            
43             $hdl->on_eof(sub{
44 1     1   2674 my $on_end = $self->{on_end};
45 1         5 $self->destroy;
46 1 50       6 $on_end->($self) if $on_end;
47 1         41 });
48            
49             $hdl->on_error(sub{
50 0     0   0 my ($h, $fatal, $msg) = @_;
51 0 0       0 if ( $! == Errno::EBADMSG ) { # JSON Parse error
    0          
52 0         0 my $res = JSON::RPC2::AnyEvent::Server::_make_error_response(undef, ERR_PARSE_ERROR, 'Parse error');
53 0         0 $h->push_write(json => $res);
54             } elsif ( $self->{on_error} ){
55 0         0 $self->{on_error}->($self, $fatal, $msg);
56 0 0       0 $self->destroy if $fatal;
57             } else {
58 0 0       0 $self->destroy if $fatal;
59 0         0 croak "JSON::RPC2::AnyEvent::Handle uncaught error: $msg";
60             }
61 1         9 });
62            
63 1         5 $self;
64             }
65              
66              
67             sub JSON::RPC2::AnyEvent::Server::dispatch_fh{
68 1     1 0 1006130 my ($self, $fh) = @_;
69 1         12 __PACKAGE__->new($self, $fh);
70             }
71              
72              
73             # Create on_xxx methods
74             for my $name ( qw/ on_end on_error / ) {
75 2     2   16 no strict 'refs';
  2         3  
  2         351  
76             *$name = sub {
77 2     2   15 my ($self, $code) = @_;
78 2 50       10 reftype $code eq 'CODE' or croak "coderef must be specified";
79 2         9 $self->{$name} = $code;
80             };
81             }
82              
83              
84             # This DESTROY-pattern originates from AnyEvent::Handle code.
85             sub DESTROY {
86 1     1   3 my ($self) = @_;
87 1         3 $self->{hdl}->destroy;
88             }
89              
90             sub destroy {
91 1     1 1 2 my ($self) = @_;
92 1         4 $self->DESTROY;
93 1         31 %$self = ();
94 1         8 bless $self, "JSON::RPC2::AnyEvent::Server::Handle::destroyed";
95             }
96              
97       1     sub JSON::RPC2::AnyEvent::Server::Handle::destroyed::AUTOLOAD {
98             #nop
99             }
100              
101              
102             1;
103             __END__