Reputation: 12283
When I run the command
montage -background black -geometry +0+0 -mode Unframe -tile ${num_digits}x1 $filelist gif:- > ~/temp/count.gif
It takes 0.1 seconds to execute (I used time montage...
).
When I put that command in my perl cgi script
print LOG "starting montage\n";
open(GRFX,
"montage -background black -geometry +0+0 -mode Unframe -tile ${num_digits}x1 $filelist gif:- |"
);
print LOG "finish montage\n";
print <GRFX>;
print LOG "finish output\n";
close(GRFX);
The time between "finish montage" and "finish output" is 6 seconds!!
If I run the cgi script from the command line it takes 0.1 seconds. But from within Apache it takes the 6 seconds, even when accessed with a browser on the same computer as Apache (so it is not the Internet slowing things down, also, all other pages load fast regardless of whether the browser is on the same computer).
The resulting gif file generated by montage is 1.7k.
Any ideas why this is so slow when run within Apache?
The only header output is print "Content-type: image/gif\n\n";
Upvotes: 2
Views: 499
Reputation: 118128
You are using print <GRFX>;
to print the output, reading all the lines of output from the piped shell command.
LINES is the operative word here. Presumably, the trailing sequence of bytes does not end in a newline, and therefore Perl is waiting around for it. Eventually, it times out.
You can set local $/ = 4096
to read 4096 byte chunks at a time. Then, output using print while <GRFX>
.
It would be good form to also binmode
both GRFX
and STDOUT
so you don't get bit by problems like this. See also my blog post on a related question.
I would be tempted to re-write your code like this (untested):
sub output_image {
my $num_digits = shift;
my $filelist = shift;
print LOG "starting montage\n";
my @cmd = (
montage => qw(
-background black
-geometry +0+0
-mode Unframe
-tile),
"${num_digits}x1",
split(/ /,$filelist),
'gif:-'
);
open my $GRFX, '-|', @cmd
or die "Failed to open pipe: $!";
{
local $/ = 4096;
binmode $GRFX;
binmode STDOUT;
print while <$GRFX>;
}
close $GRFX
or die "Failed to close pipe: $!";
print LOG "finish montage\n";
}
Upvotes: 1