diff options
-rw-r--r-- | lib/MGA/Advisories.pm | 88 |
1 files changed, 68 insertions, 20 deletions
diff --git a/lib/MGA/Advisories.pm b/lib/MGA/Advisories.pm index 08f5c15..2db96db 100644 --- a/lib/MGA/Advisories.pm +++ b/lib/MGA/Advisories.pm @@ -10,6 +10,7 @@ use Email::Simple; use Email::Simple::Creator; use HTTP::Request; use LWP::UserAgent; +use Parallel::ForkManager; use File::Basename; use XMLRPC::Lite; use Term::ReadKey; @@ -614,6 +615,25 @@ sub process_template { } } +# Max 10 processes for processing templates +my $pm = Parallel::ForkManager->new(10); + +# Run process_template in its own process. The process creation overhead is +# high, so this only makes sense for templates that interate over all or most +# of the advisories and not just a single one. +sub parallel_process_template { + if (! $pm->start()) { + # child + process_template(@_); + $pm->finish; # do the exit from the child process + } +} + +# Wait for all processes to finish +sub parallel_complete { + $pm->wait_all_children; +} + sub output_pages { my ($advdb) = @_; my $template = Template->new( @@ -622,27 +642,54 @@ sub output_pages { OUTPUT_PATH => $config->{out_dir}, EVAL_PERL => 1, ); - foreach my $adv (keys %{$advdb->{advisories}}) { - my $vars = { - config => $config, - advisory => $adv, - advdb => $advdb, - basename => \%basename, - tools => \%tools, - }; - process_template($template, 'advisory', $vars, $basename{ID}->($adv)); - process_template($template, 'advisory', $vars, $basename{ID}->($adv), 'json'); + + # Run this loop in parallel in its own process + if (! $pm->start()) { + # child + foreach my $adv (keys %{$advdb->{advisories}}) { + my $vars = { + config => $config, + advisory => $adv, + advdb => $advdb, + basename => \%basename, + tools => \%tools, + }; + process_template($template, 'advisory', $vars, $basename{ID}->($adv)); + } + $pm->finish; # do the exit from the child process } - foreach my $by (['rel', 'by_rel'], ['CVE', 'by_cve'], ['src', 'by_src']) { - foreach my $r (keys %{$advdb->{$by->[1]}}) { + + # Run this loop in parallel in its own process + if (! $pm->start()) { + # child + foreach my $adv (keys %{$advdb->{advisories}}) { my $vars = { config => $config, - $by->[0] => $r, + advisory => $adv, advdb => $advdb, basename => \%basename, tools => \%tools, }; - process_template($template, $by->[1], $vars, $basename{$by->[0]}->($r)); + process_template($template, 'advisory', $vars, $basename{ID}->($adv), 'json'); + } + $pm->finish; # do the exit from the child process + } + + # Run each loop in parallel in its own process + foreach my $by (['rel', 'by_rel'], ['CVE', 'by_cve'], ['src', 'by_src']) { + if (! $pm->start()) { + # child + foreach my $r (keys %{$advdb->{$by->[1]}}) { + my $vars = { + config => $config, + $by->[0] => $r, + advdb => $advdb, + basename => \%basename, + tools => \%tools, + }; + process_template($template, $by->[1], $vars, $basename{$by->[0]}->($r)); + } + $pm->finish; # do the exit from the child process } } my $vars = { @@ -651,12 +698,13 @@ sub output_pages { basename => \%basename, tools => \%tools, }; - process_template($template, 'index', $vars, 'index'); - process_template($template, 'advisories', $vars, 'advisories'); - process_template($template, 'vulns', $vars, 'vulns', 'json'); - process_template($template, 'bugs', $vars, 'bugs', 'json'); - process_template($template, 'infos', $vars, 'infos'); - process_template($template, 'CVE', $vars, 'CVE'); + parallel_process_template($template, 'index', $vars, 'index'); + parallel_process_template($template, 'advisories', $vars, 'advisories'); + parallel_process_template($template, 'vulns', $vars, 'vulns', 'json'); + parallel_process_template($template, 'bugs', $vars, 'bugs', 'json'); + parallel_process_template($template, 'infos', $vars, 'infos'); + parallel_process_template($template, 'CVE', $vars, 'CVE'); + parallel_complete(); } sub send_adv_mail { |