Improving mod_perl Driven Site's Performance -- Part IV: Sharing Memory Page 4

Now if you need to compare more than variable, doing it by hand can be quite time consuming and error prune. Therefore it's better to correct the testing script to dump the Perl data-types into files (e.g /tmp/dump.20988, where 20988 is the PID of the process) and then using diff(1) utility to see whether there is some difference.

So correcting the dump() function to write the info to the file will do the job. Notice that I use Devel::Peek and not Apache::Peek. The both are almost the same, but Apache::Peek prints it output directly to the opened socket so I cannot intercept and redirect the result to the file. Since Devel::Peek dumps results to the STDERR stream I can use the old trick of saving away the default STDERR handler, and open a new filehandler using the STDERR. In our example when Devel::Peek now prints to STDERR it actually prints to our file. When I'm done, I make sure to restore the original STDERR filehandler.

So this is the resulting code:

  package MyShared2;
  use Devel::Peek;

  my  = "Chris";

  sub match    {  =~ /\w/g;               }
  sub print_pos{ print "pos: ",pos(),"\n";}
  sub dump{
    my  = "/tmp/dump.20988";
    print "Dumping the data into \n";
    open OLDERR, ">&STDERR";
    open STDERR, ">". or die "Can't open : ";
    close STDERR ;
    open STDERR, ">&OLDERR";

When if I modify the code to use the modified module:

  use MyShared2;
  print "Content-type: text/plain\r\n\r\n";
  print "PID: 20988\n";

And run it as before (with MaxClients 2), two dump files will be created in the directory /tmp. In our test these were created as /tmp/dump.1224 and /tmp/dump.1225. When I run diff(1):

  % diff /tmp/dump.1224 /tmp/dump.1225
  <       MG_LEN = 1
  >       MG_LEN = 2

We see that the two padlists (of the variable readonly) are different, as we have observed before when I did a manual comparison.

In fact if we think about these results again, we get to a conclusion that there is no need for two processes to find out whether the variable gets modified (and therefore unshared). It's enough to check the datastructure before the script was executed and after that. You can modify the MyShared2 module to dump the padlists into a different file after each invocation and then to run the diff(1) on the two files.

If you want to watch whether some lexically scoped (with my()) variables in your Apache::Registry script inside the same process get changed between invocations you can use the Apache::RegistryLexInfo module instead. Since it does exactly this: it makes a snapshot of the padlist before and after the code execution and shows the difference between the two. This specific module was written to work with Apache::Registry scripts so it won't work for loaded modules. Use the technique I have described above for any type of variables in modules and scripts.

This article was originally published on Jan 8, 2001

Thanks for your registration, follow us on our social networks to keep up-to-date