Hi Gerald,
I am trying to improve the shared memory usage on my server, and I've managed to
(apparently) preload all the Embperl files on two of my sites. It all seems to
work, at first. But then the shared memory goes down quite rapidly. On initial
startup, Apache::VMonitor says that most of the memory is shared, but after a
couple of hundred requests (per child) it has fallen to around half of the total
memory taken by each process. A typical total size is 33.9M, with 17.7M shared
after 250 requests (for that child). I realize that Perl is probably responsible
for this, and I have read the mod_perl performance document, but I just wanted
to check in and make sure I am doing the right sort of thing here...
First of all, I had to change my EmbperlObject files to enable preloading (using
1.3.4). The problem lay in lines like this, which are at the start of every
subroutine module:
[! Execute ({isa => '../Journal.epl'}) !]
I found that I had to change this to an absolute path, like this:
[! Execute ({isa => '/full/path/to/parent/Journal.epl'}) !]
Is this because EmbperlObject uses the filename given in Execute as a key to
some kind of internal hash?
I used Embperl::Execute in startup.epl (see below). I also had to remove the
'package => __PACKAGE__' from the files which are executed from base.epl, which
meant putting all the (formerly global) variables in the $req variable which is
passed in to every module. I experimented with using the global:: namespace, but
this seemed to cause some problems with preloaded modules: Everything would seem
to work for a while, but then there would be spurious errors along the lines of
'attempt to modify read-only value' when the variable was being initialized. So,
I got rid of all global:: vars and now it all seems to work.
I wrote a routine in startup.pl to recursively traverse the directory tree and
preload all the Embperl files which match a given pattern. Even though this is
an EmbperlObject website, I found that calling Embperl::Execute seemed to work
fine. Is that ok? Calling EmbperlObject::Execute gave these messages for every
file:
Use of uninitialized value in substitution (s///) at
/usr/lib/perl5/site_perl/5.6.0/i386-linux/HTML/EmbperlObject.pm line 181.
Use of uninitialized value in bitwise and (&) at
/usr/lib/perl5/site_perl/5.6.0/i386-linux/HTML/EmbperlObject.pm line 187.
Use of uninitialized value in concatenation (.) at
/usr/lib/perl5/site_perl/5.6.0/i386-linux/HTML/EmbperlObject.pm line 213.
I am just wondering if I am doing the right thing here, since after a while the
shared memory seems to drift down to pretty much what it was before I started
preloading the Embperl files. So is it really worth it? Here's the startup.pl,
I'd appreciate any advice as to whether I am doing something really braindead
here...
Thanks in advance,
-Neil
startup.pl:
#!/usr/local/bin/perl
# First modify the include path
BEGIN
{
use Apache ();
use lib '/www/lib/perl';
}
# Common modules
use Apache::Registry ();
use Apache::Constants ();
use Apache::File ();
use Apache::Log ();
use Safe ();
use Log::Logger ();
use File::Copy ();
use File::Path ();
use File::Glob ();
use Time::Zone ();
use CGI qw (-compile :cookie cgi_error header);
use Date::Calc qw(:all);
use Image::Magick ();
use HTML::Embperl ();
use HTML::EmbperlObject ();
use DBI ();
DBI->install_driver('mysql');
# My modules
use Apache::BlockAgent ();
use Apache::Nilspace::Access ();
use Apache::Nilspace::Handler ();
use Nilspace ();
use Nilspace::Agenda ();
use Nilspace::Commerce ();
use Nilspace::Mail ();
# Apache::VMonitor
use Apache::VMonitor();
$Apache::VMonitor::Config{BLINKING} = 1;
$Apache::VMonitor::Config{REFRESH} = 0;
$Apache::VMonitor::Config{VERBOSE} = 0;
$Apache::VMonitor::Config{SYSTEM} = 1;
$Apache::VMonitor::Config{APACHE} = 1;
$Apache::VMonitor::Config{PROCS} = 1;
$Apache::VMonitor::Config{MOUNT} = 1;
$Apache::VMonitor::Config{FS_USAGE} = 1;
$Apache::VMonitor::Config{SORT_BY} = 'size';
$Apache::VMonitor::PROC_REGEX = join "\|", qw(httpd mysql squid);
# Preload Embperl website code
preload_dir ('/www/lib/perl/Apache', '*.html *.epl');
preload_dir ('/www/neilgunton.com/htdocs', '*.html *.epl');
preload_dir ('/www/crazyguyonabike.com/htdocs', '*.html *.epl');
# Recursive directory traversal sub which preloads Embperl files
sub preload_dir
{
my ($dir, # The current directory which is to be processed
$pattern # A pattern identifying files to be processed
) = @_;
local *DIR;
opendir (DIR, $dir) or die "Could not open directory: $dir: $!";
# First, process files in this directory
# Pattern consists of a potential list of patterns,
# separated by spaces.
# First we make a list of patterns, and then glob each of these
foreach my $glob (split (/\s/, $pattern))
{
# Iterate through the resulting list of files
foreach my $file (File::Glob::glob ("$dir/$glob"))
{
if (!(-d $file) && (-e $file))
{
print "Embperl::Execute $file\n";
HTML::EmbperlObject::Execute ({inputfile => $file,
import => 0,
escmode => 0,
options => 16}) ;
}
}
}
# Now, recursively go down into subdirectories
while (defined(my $file = readdir (DIR)))
{
# Only recurse on directories, which do not start with ".",
# and skip symbolic links
if (-d "$dir/$file" &&
!(-l "$dir/$file") &&
($file !~ /^\.{1,2}$/))
{
preload_dir ("$dir/$file", $pattern);
}
}
}
1;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]