Newer Older
172 lines | 4.578kb
copy gitweblite soruce code
root authored on 2012-11-23
1
package Mojo::Server::Morbo;
2
use Mojo::Base -base;
3

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
4
# "Linda: With Haley's Comet out of ice, Earth is experiencing the devastating
5
#         effects of sudden, intense global warming.
6
#  Morbo: Morbo is pleased but sticky."
copy gitweblite soruce code
root authored on 2012-11-23
7
use Mojo::Home;
8
use Mojo::Server::Daemon;
9
use POSIX 'WNOHANG';
10

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
11
has watch => sub { [qw(lib templates)] };
copy gitweblite soruce code
root authored on 2012-11-23
12

            
13
sub check_file {
14
  my ($self, $file) = @_;
15

            
16
  # Check if modify time and/or size have changed
17
  my ($size, $mtime) = (stat $file)[7, 9];
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
18
  return undef unless defined $mtime;
copy gitweblite soruce code
root authored on 2012-11-23
19
  my $cache = $self->{cache} ||= {};
20
  my $stats = $cache->{$file} ||= [$^T, $size];
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
21
  return undef if $mtime <= $stats->[0] && $size == $stats->[1];
22
  return !!($cache->{$file} = [$mtime, $size]);
copy gitweblite soruce code
root authored on 2012-11-23
23
}
24

            
25
sub run {
26
  my ($self, $app) = @_;
27

            
update Mojolicious 4.07
Yuki Kimoto authored on 2013-06-03
28
  # Clean manager environment
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
29
  local $SIG{CHLD} = sub { $self->_reap };
30
  local $SIG{INT} = local $SIG{TERM} = local $SIG{QUIT} = sub {
copy gitweblite soruce code
root authored on 2012-11-23
31
    $self->{finished} = 1;
32
    kill 'TERM', $self->{running} if $self->{running};
33
  };
34
  unshift @{$self->watch}, $app;
35
  $self->{modified} = 1;
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
36

            
37
  # Prepare and cache listen sockets for smooth restarting
38
  my $daemon = Mojo::Server::Daemon->new(silent => 1)->start->stop;
39

            
copy gitweblite soruce code
root authored on 2012-11-23
40
  $self->_manage while !$self->{finished} || $self->{running};
41
  exit 0;
42
}
43

            
44
sub _manage {
45
  my $self = shift;
46

            
47
  # Discover files
48
  my @files;
49
  for my $watch (@{$self->watch}) {
50
    if (-d $watch) {
51
      my $home = Mojo::Home->new->parse($watch);
52
      push @files, $home->rel_file($_) for @{$home->list_files};
53
    }
54
    elsif (-r $watch) { push @files, $watch }
55
  }
56

            
57
  # Check files
58
  for my $file (@files) {
59
    next unless $self->check_file($file);
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
60
    say qq{File "$file" changed, restarting.} if $ENV{MORBO_VERBOSE};
copy gitweblite soruce code
root authored on 2012-11-23
61
    kill 'TERM', $self->{running} if $self->{running};
62
    $self->{modified} = 1;
63
  }
64

            
65
  $self->_reap;
66
  delete $self->{running} if $self->{running} && !kill 0, $self->{running};
67
  $self->_spawn if !$self->{running} && delete $self->{modified};
68
  sleep 1;
69
}
70

            
71
sub _reap {
72
  my $self = shift;
73
  while ((my $pid = waitpid -1, WNOHANG) > 0) { delete $self->{running} }
74
}
75

            
76
sub _spawn {
77
  my $self = shift;
78

            
79
  # Fork
80
  my $manager = $$;
81
  $ENV{MORBO_REV}++;
82
  die "Can't fork: $!" unless defined(my $pid = fork);
83

            
84
  # Manager
85
  return $self->{running} = $pid if $pid;
86

            
87
  # Worker
88
  $SIG{CHLD} = 'DEFAULT';
89
  $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = sub { $self->{finished} = 1 };
90
  my $daemon = Mojo::Server::Daemon->new;
91
  $daemon->load_app($self->watch->[0]);
92
  $daemon->silent(1) if $ENV{MORBO_REV} > 1;
93
  $daemon->start;
94
  my $loop = $daemon->ioloop;
95
  $loop->recurring(
96
    1 => sub { shift->stop if !kill(0, $manager) || $self->{finished} });
97
  $loop->start;
98
  exit 0;
99
}
100

            
101
1;
102

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
103
=encoding utf8
104

            
copy gitweblite soruce code
root authored on 2012-11-23
105
=head1 NAME
106

            
107
Mojo::Server::Morbo - DOOOOOOOOOOOOOOOOOOM!
108

            
109
=head1 SYNOPSIS
110

            
111
  use Mojo::Server::Morbo;
112

            
113
  my $morbo = Mojo::Server::Morbo->new;
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
114
  $morbo->run('/home/sri/myapp.pl');
copy gitweblite soruce code
root authored on 2012-11-23
115

            
116
=head1 DESCRIPTION
117

            
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
118
L<Mojo::Server::Morbo> is a full featured, self-restart capable non-blocking
119
I/O HTTP and WebSocket server, built around the very well tested and reliable
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
120
L<Mojo::Server::Daemon>, with IPv6, TLS, Comet (long polling), keep-alive,
121
connection pooling, timeout, cookie, multipart and multiple event loop
122
support. Note that the server uses signals for process management, so you
123
should avoid modifying signal handlers in your applications.
copy gitweblite soruce code
root authored on 2012-11-23
124

            
125
To start applications with it you can use the L<morbo> script.
126

            
127
  $ morbo myapp.pl
128
  Server available at http://127.0.0.1:3000.
129

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
130
For better scalability (epoll, kqueue) and to provide IPv6 as well as TLS
131
support, the optional modules L<EV> (4.0+), L<IO::Socket::IP> (0.16+) and
132
L<IO::Socket::SSL> (1.75+) will be used automatically by L<Mojo::IOLoop> if
133
they are installed. Individual features can also be disabled with the
134
MOJO_NO_IPV6 and MOJO_NO_TLS environment variables.
upgraded Mojolicious to v3.7...
Yuki Kimoto authored on 2013-01-28
135

            
136
See L<Mojolicious::Guides::Cookbook> for more.
copy gitweblite soruce code
root authored on 2012-11-23
137

            
138
=head1 ATTRIBUTES
139

            
140
L<Mojo::Server::Morbo> implements the following attributes.
141

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
142
=head2 watch
copy gitweblite soruce code
root authored on 2012-11-23
143

            
144
  my $watch = $morbo->watch;
145
  $morbo    = $morbo->watch(['/home/sri/myapp']);
146

            
147
Files and directories to watch for changes, defaults to the application script
148
as well as the C<lib> and C<templates> directories in the current working
149
directory.
150

            
151
=head1 METHODS
152

            
153
L<Mojo::Server::Morbo> inherits all methods from L<Mojo::Base> and implements
154
the following new ones.
155

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
156
=head2 check_file
copy gitweblite soruce code
root authored on 2012-11-23
157

            
update Mojolicious to 4.57
Yuki Kimoto authored on 2013-12-02
158
  my $bool = $morbo->check_file('/home/sri/lib/MyApp.pm');
copy gitweblite soruce code
root authored on 2012-11-23
159

            
160
Check if file has been modified since last check.
161

            
update Mojolicious and added...
Yuki Kimoto authored on 2013-03-20
162
=head2 run
copy gitweblite soruce code
root authored on 2012-11-23
163

            
164
  $morbo->run('script/myapp');
165

            
166
Run server for application.
167

            
168
=head1 SEE ALSO
169

            
170
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
171

            
172
=cut