File Coverage

blib/lib/Mojolicious/Plugin/Minion/Workers.pm
Criterion Covered Total %
statement 3 61 4.9
branch 0 28 0.0
condition 0 34 0.0
subroutine 1 11 9.0
pod 2 7 28.5
total 6 141 4.2


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Minion::Workers;
2 1     1   54193 use Mojo::Base 'Mojolicious::Plugin::Minion';
  1         153389  
  1         6  
3              
4             our $VERSION = '0.9095';# as to Minion version/10+
5              
6             has minion => undef, weak=>1;
7             has qw(conf);
8              
9             sub register {
10 0     0 1   my ($self, $app, $conf) = @_;
11              
12 0           my $workers = delete $conf->{workers};
13 0           my $manage = delete $conf->{manage};
14 0   0       my $tasks = delete $conf->{tasks} || {};
15            
16 0           my $helper = $app->renderer->get_helper('minion');
17            
18 0           my @backend = keys %$conf;
19             require Carp
20 0 0 0       and Carp::croak("Too many config args for Mojolicious::Plugin::Minion")
      0        
21             if @backend > 1 && !$helper;
22              
23             $conf->{ $backend[0] } = $conf->{ $backend[0] }->($app)
24 0 0 0       if $backend[0] && ref($conf->{ $backend[0] }) eq 'CODE';
25              
26 0 0 0       $self->SUPER::register($app, $conf)
27             if $backend[0] && !$helper;
28              
29 0           $self->minion($app->minion);
30             $self->conf({
31             %$conf,
32             workers => $workers,
33             is_manage => !$ARGV[0]
34             || $ARGV[0] eq 'daemon'
35             || $ARGV[0] eq 'prefork',
36             is_prefork => $ENV{HYPNOTOAD_APP}
37 0   0       || ($ARGV[0] && $ARGV[0] eq 'prefork'),
      0        
38             });
39              
40 0     0     $app->minion->attr('workers'=> sub { $self }, weak=>1);
  0            
41            
42 0           while (my ($name, $sub) = each %$tasks) {
43 0           $app->log->debug(sprintf("Applied Minion task [%s] in [%s] from config", $name, $app->minion->add_task($name => $sub)));
44             }
45            
46             $self->manage()
47 0 0 0       and $self->conf->{is_manage} = 0
48             if $manage;
49              
50 0           return $self;
51             }
52              
53             sub manage {
54 0     0 1   my ($self, $workers) = @_;
55 0           my $conf = $self->conf;
56             return
57 0 0         unless $conf->{is_manage};
58              
59             $workers ||= $conf->{workers}
60 0 0 0       or return;
61              
62 0           my $minion = $self->minion;
63              
64 0 0         if ($conf->{is_prefork}) {
65 0           $self->prefork;
66             } else {
67 0           $self->subprocess;
68             }
69 0           return $self;
70             }
71              
72             # Cases: hypnotoad script/app.pl | perl script/app.pl prefork
73             sub prefork {
74 0     0 0   my ($self) = @_;
75            
76             # case hot deploy and kill -USR2
77             return
78             #~ if $hypnotoad_pid && !$ENV{HYPNOTOAD_STOP};
79 0 0 0       if $ENV{HYPNOTOAD_PID} && !$ENV{HYPNOTOAD_STOP};
80              
81 0           $self->kill_workers;
82            
83 0 0         return if $ENV{HYPNOTOAD_STOP};
84              
85 0           my $workers = $self->conf->{workers};
86 0           while ($workers--) {
87 0 0         defined(my $pid = fork())
88             || die "Can't fork: $!";
89 0 0         next if $pid;
90 0           detach();
91 0           $self->worker_run;
92 0           CORE::exit(0);
93             }
94             }
95              
96             # Cases: morbo script/app.pl | perl script/app.pl daemon
97             sub subprocess {
98 0     0 0   my ($self) = @_;
99              
100 0           $self->kill_workers;
101              
102             # subprocess allow run/restart worker later inside app worker
103 0           my $subprocess = Mojo::IOLoop::Subprocess->new();
104             $subprocess->run(
105             sub {
106 0     0     my $subprocess = shift;
107 0           $self->worker_run;
108 0           return $$;
109             },
110 0     0     sub {1}
111 0           );
112             # Dont $subprocess->ioloop->start here!
113             }
114              
115             sub worker_run {
116 0     0 0   my ($self) = @_;
117 0           my $minion = $self->minion;
118 0           $ENV{MINION_PID} = $$;
119 0           $0 = "$0 minion worker";
120 0           $minion->app->log->info("Minion worker (pid $$) was starting");
121 0           $minion->worker->run;
122             }
123              
124              
125              
126             sub kill_workers {
127 0     0 0   my ($self, $workers) = @_;
128 0           my $minion = $self->minion;
129 0   0       $workers ||= $minion->backend->list_workers(0,1000)->{workers};
130              
131             kill 'QUIT', $_->{pid}
132             and $minion->app->log->info("Minion worker (pid $_->{pid}) was stopped")
133 0   0       for @$workers;
134             }
135              
136             sub detach {
137             #~ chdir("/") || die "can't chdir to /: $!";
138             #~ defined(my $pid = fork()) || die "can't fork: $!";
139             #~ return 0
140             #~ if $pid; # parent
141            
142             #~ require POSIX;
143             #~ (POSIX::setsid() != -1) || die "Can't start a new session: $!";
144 0 0   0 0   open(STDIN, "< /dev/null") || die "Can't read /dev/null: $!";
145 0 0         open(STDOUT, "> /dev/null") || die "Can't write to /dev/null: $!";
146 0 0         open(STDERR, ">&STDOUT") || die "Can't dup stdout: $!";
147              
148             #~ return $$;
149             }
150              
151             1;
152              
153             __END__