File Coverage

blib/lib/Mojo/Phantom/Process.pm
Criterion Covered Total %
statement 15 37 40.5
branch 1 4 25.0
condition 0 3 0.0
subroutine 5 9 55.5
pod 2 2 100.0
total 23 55 41.8


line stmt bran cond sub pod time code
1             package Mojo::Phantom::Process;
2              
3 5     5   26 use Mojo::Base 'Mojo::EventEmitter';
  5         8  
  5         34  
4              
5 5     5   832 use constant DEBUG => $ENV{MOJO_PHANTOM_DEBUG};
  5         8  
  5         428  
6              
7 5     5   32 use Mojo::IOLoop;
  5         25  
  5         60  
8 5     5   173 use Mojo::IOLoop::Stream;
  5         10  
  5         61  
9              
10             has [qw/error exit_status pid stream/];
11              
12             sub kill {
13 0     0 1 0 my ($self) = @_;
14 0 0       0 return unless my $pid = $self->pid;
15 0         0 warn "Killing $pid\n" if DEBUG;
16 0         0 kill KILL => $pid;
17 0         0 waitpid $pid, 0;
18 0         0 $self->exit_status($?);
19 0         0 $self->stream->close;
20             };
21              
22             sub start {
23 5     5 1 9 my ($self, $file) = @_;
24              
25 5         33 my $pid = open my $pipe, '-|', 'phantomjs', "$file";
26 5 50       15916 die 'Could not spawn' unless defined $pid;
27 0           $self->pid($pid);
28 0           $self->emit(spawn => $pid);
29              
30 0           my $stream = Mojo::IOLoop::Stream->new($pipe);
31 0           my $id = Mojo::IOLoop->stream($stream);
32 0           $self->stream($stream);
33 0     0     $stream->on(error => sub { $self->error($_[1])->kill });
  0            
34 0     0     $stream->on(read => sub { $self->emit(read => $_[1]) });
  0            
35             $stream->on(close => sub {
36 0     0     my $pid = delete $self->{pid};
37 0           warn "Stream for $pid closed\n" if DEBUG;
38 0   0       $self->{exit_status} ||= $?;
39 0           $self->emit('close');
40 0           });
41              
42 0           return $self;
43             }
44              
45             1;
46              
47             =head1 NAME
48              
49             Mojo::Phantom::Process - Represents the running phantom process and its stream
50              
51             =head1 SYNOPSIS
52              
53             my $proc = Mojo::Phantom::Process->new;
54             $proc->start($file);
55              
56             =head1 DESCRIPTION
57              
58             A very utilitarian class representing a single execution of the PhantomJS executable.
59             It forks the new process and attaches a stream watcher to its STDOUT and attaches to various stream events.
60             This class is just process management and transport.
61             All real behavior is defined by the executed javascript file and the listeners to the events defined by this class.
62              
63             =head1 EVENTS
64              
65             L inherits all the events from L and emits the following new ones
66              
67             =head2 close
68              
69             $proc->on(close => sub { ($proc) = @_; ... });
70              
71             Emitted when the process has exitted (possibly with errors) and the stream has closed.
72             The user will want to check L and L.
73              
74             =head2 read
75              
76             $proc->on(read => sub { ($proc, $bytes) = @_; ... });
77              
78             Re-emitted after bytes have been read from the L.
79              
80             =head2 spawn
81              
82             $proc->on(spawn => sub { my ($proc, $pid) = @_; ... });
83              
84             Emitted just after the child process is spawned.
85             Passed the new child pid.
86              
87             =head1 ATTRIBUTES
88              
89             =head2 error
90              
91             Holds errors caught from the L's error event.
92             Note that when such an error event is caught, the process is then killed by the L method immediately afterwards.
93              
94             =head2 exit_status
95              
96             The exit status C<$?> from the closed pid.
97              
98             =head2 pid
99              
100             The pid of the spawned process.
101             The stream's close event will clear this value once the process has ended.
102              
103             =head2 stream
104              
105             The instance of L used to monitor the STDOUT of the external process.
106             It is created automatically attacted to the L by running L.
107              
108             =head1 METHODS
109              
110             =head2 kill
111              
112             $proc->kill
113              
114             Kills the child process (KILL) and closes the stream.
115             Note that since the process might exit before the kill signal is sent, it is not guaranteed that the L will reflect the signal.
116              
117             =head2 start
118              
119             $proc->start($file);
120              
121             Starts a PhantomJS in a child process running a given file, creates a stream listener and attaches to its events.
122             Returns itself.
123