File Coverage

blib/lib/Perlbal/Plugin/ServerStarter.pm
Criterion Covered Total %
statement 27 85 31.7
branch 0 24 0.0
condition 0 2 0.0
subroutine 9 20 45.0
pod 0 4 0.0
total 36 135 26.6


line stmt bran cond sub pod time code
1             package Perlbal::Plugin::ServerStarter;
2              
3 1     1   5 use strict;
  1         1  
  1         37  
4 1     1   5 use warnings;
  1         1  
  1         44  
5              
6             our $VERSION = '0.04';
7              
8 1     1   815 use Perlbal;
  1         274605  
  1         42  
9 1     1   984 use Server::Starter qw( server_ports );
  1         12950  
  1         355  
10              
11             sub load {
12 0     0 0   my $class = shift;
13            
14             Perlbal::register_global_hook(
15             'manage_command.listen' => sub {
16 0     0     my $mc = shift->parse(
17             qr{^listen\s*=\s*((?:.*:)?\d+)},
18             "usage: Listen = ",
19             );
20 0           my ($port) = $mc->args;
21              
22 0           my %port_to_fd = %{ server_ports() };
  0            
23 0           my $svc = Perlbal->service($mc->{ctx}{last_created});
24 0           my $listener = Perlbal::SocketListener->new($port_to_fd{$port}, $svc);
25 0           $svc->{listener} = $listener;
26              
27 0           Perlbal::log(debug => $listener->as_string) if Perlbal::DEBUG;
28              
29 0           return $mc->ok;
30             },
31 0           );
32              
33 0           return 1;
34             }
35              
36             sub unload {
37 0     0 0   my $class = shift;
38 0           Perlbal::unregister_global_hook('manage_command.listen');
39 0           return 1;
40             }
41              
42 0     0 0   sub unregister { 1 }
43 0     0 0   sub register { 1 }
44              
45              
46             package # hide from CPAN
47             Perlbal::SocketListener;
48              
49 1     1   12 use base 'Perlbal::Socket';
  1         3  
  1         273  
50 1     1   7 use fields qw( service port_fd );
  1         1  
  1         11  
51              
52 1     1   57 use Perlbal;
  1         3  
  1         20  
53 1     1   5 use IO::Socket::INET;
  1         2  
  1         11  
54 1     1   897 use Socket qw( SOL_SOCKET SO_SNDBUF );
  1         2  
  1         762  
55              
56             sub new {
57 0     0     my Perlbal::SocketListener $self = shift;
58 0           my ($fd, $service, $opts) = @_;
59              
60 0 0         $self = fields::new($self) unless ref $self;
61 0   0       $opts ||= {};
62              
63 0           my $sock = IO::Socket::INET->new(Proto => 'tcp');
64 0 0         $sock->fdopen($fd, 'w') or die "failed to bind to socket: $!";
65 0 0         if ($sock->blocking) {
66 0 0         $sock->blocking(0) or die "$!";
67             }
68              
69 0           $self->SUPER::new($sock);
70 0           $self->{service} = $service;
71 0           $self->{port_fd} = $fd;
72 0           $self->watch_read(1);
73              
74 0           return $self;
75             }
76              
77             sub event_read {
78 0     0     my Perlbal::SocketListener $self = shift;
79              
80 0           while (my ($psock, $peeraddr) = $self->{sock}->accept) {
81 0 0         if ($psock->blocking) {
82 0 0         $psock->blocking(0) or die "$!";
83             }
84 0 0         if (my $sndbuf = $self->{service}->{client_sndbuf_size}) {
85 0           my $rv = setsockopt($psock, SOL_SOCKET, SO_SNDBUF, pack("L", $sndbuf));
86             }
87 0           $self->class_new_socket($psock);
88             }
89             }
90              
91             ## following methods are almost copied from Perlbal::TCPListener (v1.80)
92              
93             sub class_new_socket {
94 0     0     my Perlbal::SocketListener $self = shift;
95 0           my $psock = shift;
96              
97 0           my $service_role = $self->{service}->role;
98 0 0         if ($service_role eq "reverse_proxy") {
    0          
    0          
    0          
    0          
99 0           return Perlbal::ClientProxy->new($self->{service}, $psock);
100             }
101             elsif ($service_role eq "management") {
102 0           return Perlbal::ClientManage->new($self->{service}, $psock);
103             }
104             elsif ($service_role eq "web_server") {
105 0           return Perlbal::ClientHTTP->new($self->{service}, $psock);
106             }
107             elsif ($service_role eq "selector") {
108 0           return Perlbal::ClientHTTPBase->new($self->{service}, $psock, $self->{service});
109             }
110             elsif (my $creator = Perlbal::Service::get_role_creator($service_role)) {
111 0           return $creator->($self->{service}, $psock);
112             }
113             }
114              
115             sub as_string {
116 0     0     my Perlbal::SocketListener $self = shift;
117 0           my $ret = $self->SUPER::as_string;
118 0           my Perlbal::Service $svc = $self->{service};
119 0           $ret .= ": listening on FD:$self->{port_fd} via 'start_server' for service '$svc->{name}'";
120 0           return $ret;
121             }
122              
123             sub as_string_html {
124 0     0     my Perlbal::SocketListener $self = shift;
125 0           my $ret = $self->SUPER::as_string_html;
126 0           my Perlbal::Service $svc = $self->{service};
127 0           $ret .= ": listening on FD:$self->{port_fd} via start_server for service $svc->{name}";
128 0           return $ret;
129             }
130              
131             sub die_gracefully {
132 0     0     my $self = shift;
133 0           $self->close('graceful_death');
134             }
135              
136             1;
137              
138             =pod
139              
140             =head1 NAME
141              
142             Perlbal::Plugin::ServerStarter - Perlbal plugin for Server::Starter support
143              
144             =head1 SYNOPSIS
145              
146             ## in perlbal.conf
147             LOAD ServerStarter
148             CREATE SERVICE web
149             SET role = web_server
150             SET docroot = /path/to/htdocs
151             LISTEN = 5000
152             ENABLE web
153              
154             ## command line
155             $ start_server --port 5000 -- perlbal -c perlbal.conf
156              
157             ## use nifty wrapper script of start_server and perlbal combination
158             $ start_perlbal -c perlbal.conf
159              
160             =head1 DESCRIPTION
161              
162             Perlbal::Plugin::ServerStarter is a plugin to be able to run perlbal via I command of L. Therefor, the hot deployment of upgrading perlbal, plugins and configration changes is available by Perlbal!!
163              
164             =head1 COMMANDS
165              
166             =over 4
167              
168             =item LISTEN = [ip:]port
169              
170             Set port number listened by I. Under using this plugin, all of 'SET listen = [ip:]port' lines should be replaced in this command, because I generate multiple perlbal processes with same configration at restarting processes.
171              
172             =back
173              
174             =head1 SEE ALSO
175              
176             =over
177              
178             =item L
179              
180             =item L
181              
182             =back
183              
184             =head1 AUTHOR
185              
186             Hiroshi Sakai Eziguzagu@cpan.orgE
187              
188             Repository available on github: L
189              
190             =head1 LICENSE
191              
192             This library is free software; you can redistribute it and/or modify
193             it under the same terms as Perl itself.
194              
195             =cut