Updated callbacks

Using anonymous subs for the simple callbacks instead of named subs
Using reference rather than direct hash access to construct the response
This commit is contained in:
Ben Roberts
2010-02-20 01:32:39 +00:00
parent f71987cbb6
commit e9bfe27782
2 changed files with 63 additions and 39 deletions

View File

@@ -121,12 +121,25 @@ my $client = Gearman::Client->new;
$client->job_servers($options->{job_servers});
# Add new ripping task for each job to run
my @running_tasks;
my $taskset = $client->new_task_set;
foreach my $job (@jobs) {
$taskset->add_task("handbrake_rip", freeze($job),
$taskset->add_task('handbrake_rip', freeze($job),
{
on_status => sub {
my $numerator = shift;
my $denominator = shift or die;
$log->notice("Ripping task at ", ($numerator/$denominator), "% complete");
},
on_complete => \&on_complete_handler,
on_fail => \&on_fail_handler,
on_retry => sub {
my $attempt = shift or die;
$log->warning("Retrying rip");
},
on_fail => sub {
$log->warning("Rip failed");
},
}
);
}
@@ -164,10 +177,6 @@ sub on_complete_handler {
$log->notice("Completed rip to $response->{real_output_filename}");
}
sub on_fail_handler {
$log->error("Failed to distribute job");
}
# Reads configuration options from a config file, expands the internal references, and returns the expanded form.
sub parse_config {
my $config_file = shift;

View File

@@ -6,7 +6,7 @@ use strict;
use Data::Dumper;
use Gearman::Worker;
use Getopt::Long;
use IPC::Open2;
use IPC::Open3;
use Log::Handler;
use Pod::Usage;
use String::Random qw/random_string/;
@@ -70,70 +70,85 @@ $worker->work while 1;
sub handbrake_rip {
my $job = shift;
my %rip_options = %{ thaw($job->arg) };
my $rip_options = thaw($job->arg);
my %response;
my $response = {};
$log->notice("Beginning new rip to $rip_options{output_filename}");
$log->notice("Beginning new rip to $rip_options->{output_filename}");
# Generate a unique filename based on the output filename to prevent clashes from previous runs
my $uuid = random_string('cccccc');
$rip_options{real_output_filename} = $rip_options{output_filename};
$rip_options{real_output_filename} =~ s/\.([^\.]+)$/\.$uuid\.$1/;
$response{real_output_filename} = $rip_options{real_output_filename};
$rip_options->{real_output_filename} = $rip_options->{output_filename};
$rip_options->{real_output_filename} =~ s/\.([^\.]+)$/\.$uuid\.$1/;
$response->{real_output_filename} = $rip_options->{real_output_filename};
# Generate the command line for handbrake
my @handbrake_cmd = (
# Reduce the priority of the ripping process, since it is very processor intensive
'nice', '-n', $rip_options{nice},
'nice', '-n', $rip_options->{nice},
# Construct the handbrake command line
$options{handbrake},
get_options(\%rip_options, 'input_filename', '-i'),
get_options(\%rip_options, 'real_output_filename', '-o'),
get_options(\%rip_options, 'title'),
get_options(\%rip_options, 'format', '-f'),
get_options(\%rip_options, 'video_codec', '-e'),
get_options(\%rip_options, 'quantizer', '-q'),
get_options(\%rip_options, 'video_width', '-w'),
get_options(\%rip_options, 'video_height', '-l'),
get_options(\%rip_options, 'deinterlace'),
get_options(\%rip_options, 'audio_tracks', '-a'),
get_options(\%rip_options, 'audio_codec', '-E'),
get_options(\%rip_options, 'audio_names', '-A'),
get_options(\%rip_options, 'subtitle_tracks', '-s'),
get_options($rip_options, 'input_filename', '-i'),
get_options($rip_options, 'real_output_filename', '-o'),
get_options($rip_options, 'title'),
get_options($rip_options, 'format', '-f'),
get_options($rip_options, 'video_codec', '-e'),
get_options($rip_options, 'quantizer', '-q'),
get_options($rip_options, 'video_width', '-w'),
get_options($rip_options, 'video_height', '-l'),
get_options($rip_options, 'deinterlace'),
get_options($rip_options, 'audio_tracks', '-a'),
get_options($rip_options, 'audio_codec', '-E'),
get_options($rip_options, 'audio_names', '-A'),
get_options($rip_options, 'subtitle_tracks', '-s'),
);
# Return a copy of the command used to rip the title
$response{handbrake_cmd} = @handbrake_cmd;
$response->{handbrake_cmd} = @handbrake_cmd;
# flag the start of the job
$job->set_status(0, 100);
# Execute the ripping process
$log->debug("Beginning ripping process with command:\n" . join(' ', @handbrake_cmd));
my ($child_in, $child_out);
my $child_pid = open2($child_out, $child_in, @handbrake_cmd);
my ($child_in, $child_out, $child_err);
my $child_pid = open3($child_in, $child_out, $child_err, @handbrake_cmd);
# No need to write to the child process
close($child_in);
# Log the output from handbrake, and return it back to the client
$response{log} = ();
$response->{log} = ();
my $line;
while ($line = <$child_out>) {
push @{ $response{log} }, $line;
$log->debug($line);
# If the line is a progress report, record the current status
# otherwise, log the line
# Encoding: task 1 of 1, 0.87 % (34.71 fps, avg 62.95 fps, ETA 00h07m56s)
if ($line =~ m/Encoding: task \d+ of \d+, (\d+\.\d+) %/) {
my $numerator = $1 * 100;
$job->set_status($numerator, 100);
$log->notice("Task is $numerator% complete");
} else {
push @{ $response->{log} }, $line;
$log->notice($line);
}
}
close($child_out);
$job->set_status(100, 100);
# If the rip process failed, report an error status here
waitpid($child_pid, 0);
$response{status} = $? >> 8;
$response{success} = $response{status} == 0;
if ($response{success}) {
$log->notice("Finished rip to $rip_options{real_output_filename}");
$response->{status} = $? >> 8;
$response->{success} = $response->{status} == 0;
if ($response->{success}) {
$log->notice("Finished rip to $response->{real_output_filename}");
} else {
$log->warning("Ripping process returned error status: $response{status}");
$log->warning("Ripping process returned error status: $response->{status}");
}
return freeze(\%response);
return freeze($response);
}
sub get_options {