File Coverage

lib/PAGI/App/Loader.pm
Criterion Covered Total %
statement 36 43 83.7
branch 11 20 55.0
condition 2 8 25.0
subroutine 7 7 100.0
pod 0 2 0.0
total 56 80 70.0


line stmt bran cond sub pod time code
1             package PAGI::App::Loader;
2              
3 1     1   397 use strict;
  1         1  
  1         31  
4 1     1   4 use warnings;
  1         2  
  1         36  
5 1     1   3 use Future::AsyncAwait;
  1         2  
  1         5  
6              
7             =head1 NAME
8              
9             PAGI::App::Loader - Load PAGI app from file
10              
11             =head1 SYNOPSIS
12              
13             use PAGI::App::Loader;
14              
15             my $app = PAGI::App::Loader->new(
16             file => 'app.pl',
17             )->to_app;
18              
19             =cut
20              
21             sub new {
22 2     2 0 6856 my ($class, %args) = @_;
23              
24             return bless {
25             file => $args{file},
26 2   50     18 reload => $args{reload} // 0,
27             _app => undef,
28             _mtime => 0,
29             }, $class;
30             }
31              
32             sub to_app {
33 2     2 0 3 my ($self) = @_;
34              
35 2     2   27 return async sub {
36 2         3 my ($scope, $receive, $send) = @_;
37 2         5 my $app = $self->_get_app();
38              
39 2 100       4 unless ($app) {
40 1         7 await $send->({
41             type => 'http.response.start',
42             status => 500,
43             headers => [['content-type', 'text/plain']],
44             });
45 1         43 await $send->({ type => 'http.response.body', body => 'App failed to load', more => 0 });
46 1         25 return;
47             }
48              
49 1         2 await $app->($scope, $receive, $send);
50 2         10 };
51             }
52              
53             sub _get_app {
54 2     2   2 my ($self) = @_;
55              
56 2         6 my $file = $self->{file};
57              
58             # Check if reload needed
59 2 0 33     5 if ($self->{reload} && $self->{_app}) {
60 0         0 my @stat = stat($file);
61 0 0 0     0 if (@stat && $stat[9] > $self->{_mtime}) {
62 0         0 $self->{_app} = undef;
63             }
64             }
65              
66 2 50       4 return $self->{_app} if $self->{_app};
67              
68             # Load app
69 2         37 my @stat = stat($file);
70 2 100       5 $self->{_mtime} = $stat[9] if @stat;
71              
72 2         382 my $app = do $file;
73 2 50       7 if ($@) {
74 0         0 warn "Error loading $file: $@\n";
75 0         0 return;
76             }
77 2 100       5 unless ($app) {
78 1 50       36 warn "Error loading $file: $!\n" if $!;
79 1 50       7 warn "$file did not return a coderef\n" unless $app;
80 1         4 return;
81             }
82 1 50       3 unless (ref $app eq 'CODE') {
83 0         0 warn "$file did not return a coderef\n";
84 0         0 return;
85             }
86              
87 1         4 $self->{_app} = $app;
88 1         3 return $app;
89             }
90              
91             1;
92              
93             __END__