File Coverage

lib/Ubic/Service/Plack.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package Ubic::Service::Plack;
2             {
3             $Ubic::Service::Plack::VERSION = '1.18';
4             }
5              
6 1     1   224521 use strict;
  1         4  
  1         58  
7 1     1   9 use warnings;
  1         3  
  1         50  
8              
9             # ABSTRACT: Helper for running psgi applications with ubic and plackup
10              
11              
12 1     1   10 use base qw(Ubic::Service::Skeleton);
  1         2  
  1         3158  
13              
14             use Params::Validate qw(:all);
15             use Plack;
16              
17             use Ubic::Daemon qw(:all);
18              
19              
20             my $plackup_command = $ENV{'UBIC_SERVICE_PLACKUP_BIN'} || 'plackup';
21              
22             sub new {
23             my $class = shift;
24              
25             my $params = validate(@_, {
26             server => { type => SCALAR },
27             app => { type => SCALAR },
28             app_name => { type => SCALAR, optional => 1 },
29             server_args => { type => HASHREF, default => {} },
30             user => { type => SCALAR, optional => 1 },
31             group => { type => SCALAR | ARRAYREF, optional => 1 },
32             status => { type => CODEREF, optional => 1 },
33             port => { type => SCALAR, regex => qr/^\d+$/, optional => 1 },
34             ubic_log => { type => SCALAR, optional => 1 },
35             stdout => { type => SCALAR, optional => 1 },
36             stderr => { type => SCALAR, optional => 1 },
37             proxy_logs => { type => BOOLEAN, optional => 1 },
38             pidfile => { type => SCALAR, optional => 1 },
39             cwd => { type => SCALAR, optional => 1 },
40             env => { type => HASHREF, optional => 1 },
41             });
42              
43             return bless $params => $class;
44             }
45              
46             sub pidfile {
47             my $self = shift;
48             return $self->{pidfile} if defined $self->{pidfile};
49             return "/tmp/$self->{app_name}.pid" if defined $self->{app_name};
50             return "/tmp/".$self->full_name.".pid";
51             }
52              
53             sub bin {
54             my $self = shift;
55              
56             my @cmd = split(/\s+/, $plackup_command);
57              
58             my %args = (
59             server => $self->{server},
60             ($self->{port} ? (port => $self->{port}) : ()),
61             $self->defaults,
62             %{$self->{server_args}},
63             );
64             for my $key (keys %args) {
65             my $cmd_key = (length $key == 1) ? '-' : '--';
66             $cmd_key .= $key;
67             my $v = $args{$key};
68             next unless defined $v;
69             if (ref $v eq 'ARRAY') {
70             for my $value (@$v) {
71             push @cmd, $cmd_key, $value;
72             }
73             }
74             else {
75             push @cmd, $cmd_key, $v;
76             }
77             }
78             push @cmd, $self->{app};
79             return \@cmd;
80             }
81              
82             sub start_impl {
83             my $self = shift;
84              
85             my $daemon_opts = {
86             bin => $self->bin,
87             pidfile => $self->pidfile,
88             term_timeout => 5, # TODO - configurable?
89             };
90             for (qw/ env cwd stdout stderr ubic_log /, ($Ubic::Daemon::VERSION gt '1.48' ? 'proxy_logs' : ())) {
91             $daemon_opts->{$_} = $self->{$_} if defined $self->{$_};
92             }
93             start_daemon($daemon_opts);
94             return;
95             }
96              
97             sub stop_impl {
98             my $self = shift;
99             return stop_daemon($self->pidfile, { timeout => 7 });
100             }
101              
102             sub status_impl {
103             my $self = shift;
104             my $running = check_daemon($self->pidfile);
105             return 'not running' unless ($running);
106             if ($self->{status}) {
107             return $self->{status}->();
108             } else {
109             return 'running';
110             }
111             }
112              
113             sub user {
114             my $self = shift;
115             return $self->{user} if defined $self->{user};
116             return $self->SUPER::user;
117             };
118              
119             sub group {
120             my $self = shift;
121             my $groups = $self->{group};
122             return $self->SUPER::group() if not defined $groups;
123             return @$groups if ref $groups eq 'ARRAY';
124             return $groups;
125             }
126              
127             sub timeout_options {
128             # TODO - make them customizable
129             return {
130             start => { trials => 15, step => 0.1 },
131             stop => { trials => 15, step => 0.1 },
132             };
133             }
134              
135             sub port {
136             my $self = shift;
137             # we should leave only one of these, but I can't decide which one
138             # -- mmcleric
139             return $self->{port} if defined $self->{port};
140             return $self->{server_args}{port};
141             }
142              
143             sub defaults {
144             return ();
145             }
146              
147              
148             1;
149              
150             __END__