Last active
April 4, 2016 06:32
-
-
Save alfasado/f7d0e6993f02538eb71e to your computer and use it in GitHub Desktop.
Alternative script of MT::Worker::Publish.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
package MT::Tool::SpeedRebuild; | |
use strict; | |
use warnings; | |
use File::Spec; | |
use FindBin; | |
use lib map File::Spec->catdir( $FindBin::Bin, File::Spec->updir, $_ ), qw/lib extlib/; | |
use base qw( MT::Tool ); | |
use MT::FileMgr; | |
use MT::Util qw( log_time ); | |
use Time::HiRes qw/usleep/; | |
our $microseconds = 700000; | |
our $proc_lifetime = 1800; | |
sub usage { '--per_proc 30 --max_proc 10' } | |
our $verbose; | |
our $per_proc; | |
our $max_proc; | |
our $work_dir; | |
our $pid_file; | |
our $sleeptime; | |
our $proc_name = 'mt-speed-rebuild.pid'; | |
our $fmgr; | |
sub help { | |
return q { | |
Alternative script of MT::Worker::Publish. | |
--per_proc 30 --max_proc 10 --proc_lifetime 3600 | |
}; | |
} | |
my ( $debug ); | |
sub options { | |
return ( | |
'per_proc=i' => \$per_proc, | |
'max_proc=i' => \$max_proc, | |
'proc_lifetime=i' => \$proc_lifetime, | |
'proc_name=s' => \$proc_name, | |
); | |
} | |
sub main { | |
my $class = shift; | |
$verbose = $class->SUPER::main( @_ ); | |
my $app = MT->instance; | |
my $tmp_dir = $app->config->TempDir; | |
if (! $per_proc ) { | |
$per_proc = $app->config->RebuildPerProc || 30; | |
} | |
if (! $proc_lifetime ) { | |
$proc_lifetime = 1800; | |
} | |
$sleeptime = $app->config->RebuildWaitTime || 5; | |
$fmgr = MT::FileMgr->new( 'Local' ); | |
$pid_file = File::Spec->catfile( $tmp_dir, $proc_name ); | |
if ( -f $pid_file ) { | |
return 1; | |
} | |
$fmgr->put_data( '', $pid_file ); | |
chmod 0777, $pid_file; | |
$work_dir = File::Spec->catdir( $tmp_dir, 'RebuildProcDir' ); | |
if (! -d $work_dir) { | |
$fmgr->mkpath( $work_dir ); | |
} | |
require MT::TheSchwartz::FuncMap; | |
require MT::TheSchwartz::Job; | |
require MT::FileInfo; | |
require MT::WeblogPublisher; | |
my $funcmap = MT::TheSchwartz::FuncMap->load( { funcname => 'MT::Worker::Publish' } ); | |
return unless $funcmap; | |
my @jobs = MT::TheSchwartz::Job->load( { funcid => $funcmap->funcid, }, | |
{ 'sort' => 'priority', | |
direction => 'decend', | |
}, | |
); | |
my @works = (); | |
my $pub = MT::WeblogPublisher->new(); | |
my $rebuilt; | |
for my $job ( @jobs ) { | |
push ( @works, $job ); | |
if ( ( scalar @works ) >= $per_proc ) { | |
if ( $rebuilt ) { | |
usleep ( $microseconds ); | |
} | |
_do_work( \@works ); | |
@works = (); | |
} | |
$rebuilt++; | |
} | |
if ( @works ) { | |
if ( $rebuilt ) { | |
usleep ( $microseconds ); | |
} | |
_do_work( \@works ); | |
} | |
while ( _count_dir( $work_dir ) ) { | |
sleep $sleeptime; | |
} | |
unlink $pid_file; | |
1; | |
} | |
sub _do_work { | |
my $works = shift; | |
my $app = MT->instance(); | |
if (! $max_proc ) { | |
$max_proc = $app->config->RebuildMaxProc || 4; | |
} | |
$sleeptime = $app->config->RebuildWaitTime || 5; | |
while ( $max_proc <= _count_dir( $work_dir ) ) { | |
sleep $sleeptime; | |
} | |
my $rebuild_sub = sub { | |
my $token = _make_magic_token(); | |
my $work_file = File::Spec->catdir( $work_dir, $token ); | |
$fmgr->put_data( '', $work_file ); | |
chmod 0777, $work_file; | |
my $i = 0; | |
for my $job ( @$works ) { | |
if ( my $fi = MT::FileInfo->load( $job->uniqkey ) ) { | |
$i++; | |
$fi->{ from_queue } = 1; | |
my $res = MT->instance->publisher->rebuild_from_fileinfo( $fi ); | |
if ( defined $res ) { | |
$app->log( | |
{ ( $fi->blog_id ? ( blog_id => $fi->blog_id ) : () ), | |
message => $app->translate('Background Publishing Done') . ' : ' . $i, | |
metadata => log_time() . ' ' | |
. $app->translate( 'Published: [_1]', $fi->file_path ), | |
category => "publish", | |
level => MT::Log::INFO(), | |
} | |
); | |
$job->remove; # or die $job->errstr; | |
} else { | |
my $error = $app->publisher->errstr; | |
my $errmsg = $app->translate( "Error rebuilding file [_1]:[_2]", | |
$fi->file_path, $error ); | |
MT::TheSchwartz->debug($errmsg); | |
$job->permanent_failure($errmsg); | |
require MT::Log; | |
$app->log( | |
{ ( $fi->blog_id ? ( blog_id => $fi->blog_id ) : () ), | |
message => $errmsg, | |
metadata => log_time() . ' ' . $errmsg . ":\n" . $error, | |
category => "publish", | |
level => MT::Log::ERROR(), | |
} | |
); | |
} | |
} else { | |
$job->remove;# or die $job->errstr; | |
} | |
} | |
unlink $work_file; | |
}; | |
_background_rebuild( $rebuild_sub ); | |
} | |
sub _count_dir { | |
my $dir = shift; | |
my @files; | |
opendir my $dh, $dir or die "$dir:$!"; | |
while ( my $file = readdir $dh ) { | |
next if $file =~ /^\./; | |
$file = File::Spec->catfile( $dir, $file ); | |
my $modified = ( stat $file )[9]; | |
if ( ( time() - $modified ) > $proc_lifetime ) { | |
unlink $file; | |
} else { | |
push @files, $file; | |
} | |
} | |
closedir $dh; | |
return scalar @files; | |
} | |
sub _make_magic_token { | |
my @alpha = ( 'a' .. 'z', 'A' .. 'Z', 0 .. 9 ); | |
my $token = join '', map $alpha[ rand @alpha ], 1 .. 40; | |
$token; | |
} | |
sub _background_rebuild { | |
my $app = MT->instance(); | |
my $default = $app->config->LaunchBackgroundTasks; | |
$app->config( 'LaunchBackgroundTasks', 1 ); | |
my $res = MT::Util::start_background_task( @_ ); | |
$app->config( 'LaunchBackgroundTasks', $default ); | |
return $res; | |
} | |
__PACKAGE__->main() unless caller; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment