File Coverage

blib/lib/KelpX/Symbiosis/Engine.pm
Criterion Covered Total %
statement 20 25 80.0
branch 6 8 75.0
condition 2 3 66.6
subroutine 6 8 75.0
pod 4 4 100.0
total 38 48 79.1


line stmt bran cond sub pod time code
1             package KelpX::Symbiosis::Engine;
2             $KelpX::Symbiosis::Engine::VERSION = '2.11';
3 13     13   7977 use Kelp::Base;
  13         39  
  13         108  
4 13     13   3317 use Carp;
  13         38  
  13         1107  
5 13     13   81 use Scalar::Util qw(blessed refaddr);
  13         21  
  13         7097  
6              
7             attr adapter => sub { croak 'adapter is required' };
8             attr app_runners => sub { {} };
9              
10             sub run_app
11             {
12 28     28 1 435 my ($self, $app) = @_;
13              
14 28 100       138 if (blessed $app) {
    50          
15 23         67 my $addr = refaddr $app;
16              
17 23 50       159 croak 'Symbiosis: class ' . ref($app) . ' cannot run()'
18             unless $app->can("run");
19              
20             # cache the ran application so that it won't be ran twice. Also run the
21             # application lazily to maintain backwards compatibility
22 23         46 my $app_obj = $app;
23             $app = $self->app_runners->{$addr} //= sub {
24 33     33   128471 state $real_app = $app_obj->run;
25 33         15539 goto $real_app;
26 23   66     88 };
27             }
28             elsif (ref $app ne 'CODE') {
29 0         0 croak "Symbiosis: mount point is neither an object nor a coderef: $app";
30             }
31              
32 28         239 return $app;
33             }
34              
35             sub build
36             {
37 13     13 1 70 my ($self, %args) = @_;
38              
39             # mount through adapter so that it will be seen in mounted hash
40             $self->adapter->mount($args{mount}, $self->adapter->app)
41 13 100       64 if $args{mount};
42             }
43              
44             sub mount
45             {
46 0     0 1   my ($self, $path, $app) = @_;
47 0           croak 'mount needs to be overridden';
48             }
49              
50             sub run
51             {
52 0     0 1   my ($self) = @_;
53 0           croak 'run needs to be overridden';
54             }
55              
56             1;
57             __END__
58              
59             =head1 NAME
60              
61             KelpX::Symbiosis::Engine - Base class for engine implementation
62              
63             =head1 SYNOPSIS
64              
65             See the code of L<KelpX::Symbiosis::Engine::URLMap> as an example.
66              
67             =head1 DESCRIPTION
68              
69             This is a base to be reimplemented for a specific way to run an ecosystem. An
70             engine should be able to mount plack apps under itself and route traffic to
71             them.
72              
73             =head1 USAGE
74              
75             =head2 Attributes
76              
77             =head3 adapter
78              
79             An instance of C<KelpX::Symbiosis::Adapter>.
80              
81             =head3 app_runners
82              
83             A cache for L</run_app>.
84              
85             =head2 Methods
86              
87             =head3 run_app
88              
89             Finds, runs and caches an app to be mounted. Returns a coderef with the
90             plackified app. No need to override this, but can be useful when mounting an
91             app
92              
93             =head3 build
94              
95             Builds this engine. Run once after instantiating, passing all the Symbiosis
96             configuration. Can be overriden, by default mounts the app to where it was
97             configured to mount (but does not mount under C</> by default).
98              
99             =head3 mount
100              
101             Mount a plack app under the given path. Must be overridden.
102              
103             =head3 run
104              
105             Run the ecosystem, but without the top-level middleware. Must be overridden.
106