import FCGI-ProcManager 0.15 from CPAN 0.15
James E Jurach Jr [Wed, 31 Jan 2001 07:30:26 +0000 (23:30 -0800)]
git-cpan-module:   FCGI-ProcManager
git-cpan-version:  0.15
git-cpan-authorid: JURACH
git-cpan-file:     authors/id/J/JU/JURACH/FCGI-ProcManager-0.15.tar.gz

ChangeLog [new file with mode: 0644]
MANIFEST
ProcManager.pm
README
t/exporter.t
t/procmanager.t

diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..9543b5c
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,80 @@
+2001-01-31 01:13  James Jurach  <muaddib@erf.net>
+
+       * README: more documentation
+
+       * ProcManager.pm: re-organized method layout.  separated manager
+       vs. server vs. common moved more intialization into managing_init()
+       and handling_init() created pm_die() to be called when manager
+       should die.  cleaned up error messages and notifications.
+
+       * t/: exporter.t, procmanager.t: revised test messages
+
+2001-01-30 16:35  James Jurach  <muaddib@erf.net>
+
+       * t/: exporter.t, procmanager.t: removed call to pm_state()
+
+       * ProcManager.pm: removed sleep() call after testing
+       signal-during-fork-loop
+
+2001-01-30 12:49  James Jurach  <muaddib@erf.net>
+
+       * ProcManager.pm: Cleaned up pm_manage().  removed signal
+       registration routines.  replaced by direct %SIG access.  there is
+       now a manager signal handler and a handler signal handler.  added
+       checks to die when getppid() changes.
+
+2001-01-20 02:06  James Jurach  <muaddib@erf.net>
+
+       * MANIFEST: removed Changes from MANIFEST
+
+2001-01-13 00:44  James Jurach  <muaddib@erf.net>
+
+       * t/procmanager.t: corrected various recent method name changes. 
+       removed calls to want_to_die().  added request loop hooks to
+       pm_pre_dispatch(), pm_post_dispatch().  renamed sample_handler() to
+       sample_request_loop().
+
+       * ProcManager.pm: renamed request loop hooks to pm_pre_dispatch(),
+       pm_post_dispatch().  when pm_manage() is called with
+       n_processes==0, return through goto.  renamed pre_manage_init() to
+       managing_init().  renamed post_manage_init() to handling_init(). 
+       added received_signal() to remember that a signal was received. 
+       signal handler simpler: now only notes signal and propagates
+       signal.
+
+       * t/exporter.t: this uses non-OO calling mode.
+
+       * MANIFEST: added t/exporter.t.
+
+       * Changes: ChangeLog is where per-file changes are listed.
+
+2000-12-22 05:58  James Jurach  <muaddib@erf.net>
+
+       * ProcManager.pm: corrected logic error in self_or_default(). 
+       changed all occurances of write_pid_file() to pm_write_pid_file(). 
+       changed all occurances of remove_pid_file() to
+       pm_remove_pid_file().
+
+2000-12-14 17:54  James Jurach  <muaddib@erf.net>
+
+       * ProcManager.pm: corrected state() -> pm_state() method call.
+
+2000-12-10 17:25  James Jurach  <muaddib@erf.net>
+
+       * ProcManager.pm: corrected some method renaming issues.
+
+2000-12-09 19:48  James Jurach  <muaddib@erf.net>
+
+       * t/procmanager.t: effected the changes to these subroutine names.
+
+       * ProcManager.pm: made this module OO/Exporter hybrid.  removed
+       treatment of $ENV{PROCMANAGER_PROCESSES} from constructor.  changed
+       several subroutine names.
+
+2000-12-05 22:23  James Jurach  <muaddib@erf.net>
+
+       * ProcManager.pm: made SIGHUP's do what SIGTERM's do
+
+2000-11-20  James Jurach  <muaddib@erf.net>
+
+       * Released first public version.
index ffd614e..9d66c4e 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,6 +1,7 @@
 COPYING
 MANIFEST
 MANIFEST.SKIP
+ChangeLog
 Makefile.PL
 ProcManager.pm
 README
index 5d90a82..d11835b 100644 (file)
@@ -5,23 +5,22 @@ package FCGI::ProcManager;
 # Public License, Version 2.1.  Please read the important licensing and
 # disclaimer information included below.
 
-# $Id: ProcManager.pm,v 1.12 2001/01/13 06:44:34 muaddib Exp $
+# $Id: ProcManager.pm,v 1.15 2001/01/31 07:00:55 muaddib Exp $
 
 use strict;
 use Exporter;
 
-use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS $Q @valid_states);
+use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS $Q);
 BEGIN {
-  $VERSION = '0.14';
+  $VERSION = '0.15';
   @ISA = qw(Exporter);
-  @EXPORT_OK = qw(pm_manage pm_parameter pm_state pm_warn pm_abort pm_exit
+  @EXPORT_OK = qw(pm_manage pm_die pm_reap_server
                  pm_write_pid_file pm_remove_pid_file
                  pm_pre_dispatch pm_post_dispatch
-                 pm_register_sig_handler pm_unregister_sig_handler);
+                 pm_change_process_name pm_received_signal pm_parameter 
+                 pm_warn pm_notify pm_abort pm_exit);
   $EXPORT_TAGS{all} = \@EXPORT_OK;
   $FCGI::ProcManager::Default = 'FCGI::ProcManager';
-
-  @valid_states = qw(managing handling idle);
 }
 
 =head1 NAME
@@ -30,19 +29,49 @@ BEGIN {
 
 =head1 SYNOPSIS
 
- # In its simplest form.
+{
+ # In Object-oriented style.
  use CGI::Fast;
  use FCGI::ProcManager;
- my $proc_manager = FCGI::ProcManager->new({n_processes=>10});
- $proc_manager->manage();
+ my $proc_manager = FCGI::ProcManager->new({ n_processes => 10 });
+ $proc_manager->pm_manage();
  while (my $cgi = CGI::Fast->new()) {
+   $proc_manager->pm_pre_dispatch();
+   # ... handle the request here ...
+   $proc_manager->pm_post_dispatch();
+ }
+
+ # This style is also supported:
+ use CGI::Fast;
+ use FCGI::ProcManager qw(pm_manage pm_pre_dispatch pm_post_dispatch);
+ pm_manage( n_processes => 10 );
+ while (my $cgi = CGI::Fast->new()) {
+   pm_pre_dispatch();
    #...
+   pm_post_dispatch();
+ }
 
 =head1 DESCRIPTION
 
-FCGI::ProcManager is used to serve as a FastCGI process manager.
-The parent uses fork(2) and wait(2) to manage a set of FastCGI application
-servers.  more later.
+FCGI::ProcManager is used to serve as a FastCGI process manager.  By
+re-implementing it in perl, developers can more finely tune performance in
+their web applications, and can take advantage of copy-on-write semantics
+prevalent in UNIX kernel process management.  The process manager should
+be invoked before the caller''s request loop
+
+The primary routine, C<pm_manage>, enters a loop in which it maintains a
+number of FastCGI servers (via fork(2)), and which reaps those servers
+when they die (via wait(2)).
+
+C<pm_manage> provides too hooks:
+
+ C<managing_init> - called just before the manager enters the manager loop.
+ C<handling_init> - called just before a server is returns from C<pm_manage>
+
+It is necessary for the caller, when implementing its request loop, to
+insert a call to C<pm_pre_dispatch> at the top of the loop, and then
+7C<pm_post_dispatch> at the end of the loop.
+
 
 =head1 METHODS
 
@@ -53,7 +82,11 @@ servers.  more later.
 sub new {
   my ($proto,$init) = @_;
 
-  my $this = {};
+  my $this = { 
+             role => "manager",
+             start_delay => 0,
+             die_timeout => 60
+            };
   $init and %$this = %$init;
 
   bless $this, ref($proto)||$proto;
@@ -63,27 +96,7 @@ sub new {
   return $this;
 }
 
-=head2 self_or_default
-
- private global
- (ProcManager, @args) self_or_default([ ProcManager, ] @args);
-
-DESCRIPTION:
-
-This is a helper subroutine to acquire or otherwise create a singleton
-default object if one is not passed in, e.g., a method call.
-
-=cut
-
-sub self_or_default {
-  return @_ if defined $_[0] and !ref $_[0] and $_[0] eq 'FCGI::ProcManager';
-  if (!defined $_[0] or (ref($_[0]) ne 'FCGI::ProcManager' and
-                        !UNIVERSAL::isa($_[0],'FCGI::ProcManager'))) {
-    $Q or $Q = $FCGI::ProcManager::Default->new;
-    unshift @_, $Q;
-  }
-  return wantarray ? @_ : $Q;
-}
+=head1 Manager methods
 
 =head2 pm_manage
 
@@ -97,73 +110,62 @@ When this is called by a FastCGI script to manage application servers.
 =cut
 
 sub pm_manage {
-  my ($this) = self_or_default(@_);
-
-  # initialize state and begin to handle signals.
-  $this->pm_register_sig_handler();
+  my ($this,%values) = self_or_default(@_);
+  map { $this->pm_parameter($_,$values{$_}) } keys %values;
 
-  # switch to handling state right away if we are not managing any processes.
+  # skip to handling now if we won't be managing any processes.
   $this->n_processes() or goto HANDLING;
 
-  # begin the managing sequence.
-  $this->pm_state("managing");
-
-  # call the (possibly overloaded) managing initialization.
+  # call the (possibly overloaded) management initialization hook.
+  $this->role("manager");
   $this->managing_init();
+  $this->pm_notify("initialized");
 
-  # write out the pid file.
-  $this->pm_write_pid_file();
+  my $manager_pid = $$;
 
-  my ($pid);
-  MANAGE: while (1) {
-
-    # do things that we only do when we're not already managing processes..
-    if (! %{$this->{PIDS}}) {
-      if ($this->received_signal()) {
-       $this->pm_remove_pid_file();
-       $this->pm_exit("Manager $$ dying from death request.\n");
-      } elsif ($this->n_processes() < 0) {
-       $this->pm_remove_pid_file();
-       $this->pm_abort("Manager $$ dying from processes number exception: ".
-                       $this->n_processes(), -( 1 + $this->n_processes()));
-      }
-    }
+ MANAGING_LOOP: while (1) {
+
+    # if the calling process goes away, perform cleanup.
+    getppid() == 1 and
+      return $this->pm_die("calling process has died");
 
-    # if we have fewer children than we want..
-    PIDS: while (keys(%{$this->{PIDS}}) < $this->n_processes()) {
+    $this->n_processes() > 0 or
+      return $this->pm_die();
 
-      # fork.
-      if ($pid = fork()) {
-       # the parent notes the child.
-       $this->pm_warn("started process $pid\n");
+    # while we have fewer servers than we want.
+  PIDS: while (keys(%{$this->{PIDS}}) < $this->n_processes()) {
+
+      if (my $pid = fork()) {
+       # the manager remembers the server.
        $this->{PIDS}->{$pid} = { pid=>$pid };
+        $this->pm_notify("server (pid $pid) started");
 
       } elsif (! defined $pid) {
-       # handle errors um  gracefully.
-       $this->pm_abort("fork: $!\n");
+       return $this->pm_abort("fork: $!");
 
       } else {
-       # the child returns to the calling application.
-       last MANAGE;
+       $this->role("server");
+       $this->{MANAGER_PID} = $manager_pid;
+       # the server exits the managing loop.
+       last MANAGING_LOOP;
       }
-    }
 
-    # wait on the next child to die.
-    $this->pm_abort("wait: $!\n") if ($pid = wait()) < 0;
+      for (my $s = $this->start_delay(); $s; $s = sleep $s) {};
+    }
 
-    # notify when one of our children have died.
-    delete $this->{PIDS}->{$pid} and
-      $this->pm_warn("Child process $pid died with exit status $?\n");
+    # this should block until the next server dies.
+    $this->pm_reap_server();
 
   }# while 1
 
-  HANDLING:
-  $this->pm_state("handling");
+HANDLING:
 
-  # call the (possibly overloaded) handling initialization.
+  # call the (possibly overloaded) handling init hook
+  $this->role("server");
   $this->handling_init();
+  $this->pm_notify("initialized");
 
-  # children and parent with n_processes == 0 return to calling app.
+  # server returns 
   return 1;
 }
 
@@ -173,35 +175,62 @@ sub pm_manage {
 
 sub managing_init {
   my ($this) = self_or_default(@_);
-}
 
-=head2 handling_init
+  # begin to handle signals.
+  $SIG{TERM} = sub { $this->sig_manager(@_) };
+  $SIG{HUP}  = sub { $this->sig_manager(@_) };
 
-=cut
+  # change the name of this process as it appears in ps(1) output.
+  $this->pm_change_process_name("perl-fcgi-pm");
 
-sub handling_init {
-  my ($this) = self_or_default(@_);
+  $this->pm_write_pid_file();
 }
 
-=head2 pm_pre_dispatch
+
+=head2 pm_die
 
 =cut
 
-sub pm_pre_dispatch {
-  my ($this) = self_or_default(@_);
+sub pm_die {
+  my ($this,$msg,$n) = self_or_default(@_);
+
+  # stop handling signals.
+  $SIG{HUP}  = 'DEFAULT';
+  $SIG{TERM} = 'DEFAULT';
+
+  $this->pm_remove_pid_file();
+
+  # prepare to die no matter what.
+  if (defined $this->die_timeout()) {
+    $SIG{ARLM} = sub { $this->pm_abort("reap timeout") };
+    alarm $this->die_timeout();
+  }
+
+  # send a TERM to each of the servers.
+  kill "TERM", keys %{$this->{PIDS}};
+
+  # wait for the servers to die.
+  while (%{$this->{PIDS}}) {
+    $this->pm_reap_server();
+  }
+
+  # die already.
+  $this->pm_exit("dying: ".$msg,$n);
 }
 
-=head2 pm_post_dispatch
+=head2 pm_reap_server
 
 =cut
 
-sub pm_post_dispatch {
+sub pm_reap_server {
   my ($this) = self_or_default(@_);
-  if (my $name = $this->received_signal()) {
-    if ($name eq "HUP" or $name eq "TERM") {
-      $this->pm_exit("Process $$ responding to $name death request.\n");
-    }
-  }
+
+  # wait for the next server to die.
+  next if (my $pid = wait()) < 0;
+
+  # notify when one of our servers have died.
+  delete $this->{PIDS}->{$pid} and
+    $this->pm_notify("server (pid $pid) exited with status $?");
 }
 
 =head2 pm_write_pid_file
@@ -212,7 +241,7 @@ sub pm_write_pid_file {
   my ($this,$fname) = self_or_default(@_);
   $fname ||= $this->pid_fname() or return;
   if (!open PIDFILE, ">$fname") {
-    $this->pm_warn("open: $fname: $!\n");
+    $this->pm_warn("open: $fname: $!");
     return;
   }
   print PIDFILE "$$\n";
@@ -226,93 +255,166 @@ sub pm_write_pid_file {
 sub pm_remove_pid_file {
   my ($this,$fname) = self_or_default(@_);
   $fname ||= $this->pid_fname() or return;
-  my $ret = unlink($fname) or $this->pm_warn("unlink: $fname: $!\n");
+  my $ret = unlink($fname) or $this->pm_warn("unlink: $fname: $!");
   return $ret;
 }
 
-=head2 pm_parameter
+=head2 sig_manager
 
 =cut
 
-sub pm_parameter {
-  my ($this,$key,$value) = self_or_default(@_);
-  defined $value and $this->{$key} = $value;
-  return $this->{$key};
+sub sig_manager {
+  my ($this,$name) = @_;
+  if ($name eq "TERM" or $name eq "HUP") {
+    $this->pm_die("received signal $name");
+  } else {
+    $this->pm_notify("ignoring signal $name");
+  }
 }
 
-=head2 n_processes
+=head1 Handler methods
 
-=head2 no_signals
-
-=head2 pid_fname
+=head2 handling_init
 
 =cut
 
-sub n_processes     { shift->pm_parameter("n_processes",     @_); }
-sub pid_fname       { shift->pm_parameter("pid_fname",       @_); }
-sub received_signal { shift->pm_parameter("received_signal", @_); }
-sub no_signals      { shift->pm_parameter("no_signals",      @_); }
-
-=head2 pm_state
+sub handling_init {
+  my ($this) = self_or_default(@_);
 
-=cut
+  # begin to handle signals.
+  $SIG{TERM} = sub { $this->sig_handler(@_) };
+  $SIG{HUP}  = sub { $this->sig_handler(@_) };
 
-sub pm_state {
-  my ($this,$new_state) = self_or_default(@_);
-  if (defined $new_state) {
-    if (!grep {$new_state eq $_} @valid_states) {
-      $this->pm_abort("Invalid state: $new_state\n");
-    }
-    $this->{state} = $new_state;
-  }
-  defined $this->{state} or $this->{state} = "idle";
-  return $this->{state};
+  # change the name of this process as it appears in ps(1) output.
+  $this->pm_change_process_name("perl-fcgi");
 }
 
-=head2 pm_register_sig_handler
+=head2 pm_pre_dispatch
 
 =cut
 
-sub pm_register_sig_handler {
+sub pm_pre_dispatch {
   my ($this) = self_or_default(@_);
-  return if $this->no_signals();
-  $SIG{TERM} = sub { $this->sig_method(@_) };
-  $SIG{HUP}  = sub { $this->sig_method(@_) };
 }
 
-=head2 pm_unregister_sig_handler
+=head2 pm_post_dispatch
 
 =cut
 
-sub pm_unregister_sig_handler {
+sub pm_post_dispatch {
   my ($this) = self_or_default(@_);
-  return if $this->no_signals();
-  undef $SIG{TERM};
-  undef $SIG{HUP};
+  if ($this->pm_received_signal("TERM")) {
+    $this->pm_exit("safe exit after SIGTERM");
+  }
+  if ($this->pm_received_signal("HUP")) {
+    $this->pm_exit("safe exit after SIGHUP");
+  }
+  if (getppid() != $this->{MANAGER_PID}) {
+    $this->pm_exit("safe exit: manager has died");
+  }
 }
 
-=head2 sig_method
+=head2 sig_handler
 
 =cut
 
-sub sig_method {
+sub sig_handler {
   my ($this,$name) = @_;
-  # note which signal we've received.
-  $this->{received_signal} = $name;
-  $this->n_processes(0);
-  # propagate this signal to children.  (is this necessary?)
-  if (%{$this->{PIDS}}) {
-    kill $name, keys %{$this->{PIDS}};
+  $this->pm_received_signal($name,1);
+}
+
+=head1 Common methods and routines
+
+=head2 self_or_default
+
+ private global
+ (ProcManager, @args) self_or_default([ ProcManager, ] @args);
+
+DESCRIPTION:
+
+This is a helper subroutine to acquire or otherwise create a singleton
+default object if one is not passed in, e.g., a method call.
+
+=cut
+
+sub self_or_default {
+  return @_ if defined $_[0] and !ref $_[0] and $_[0] eq 'FCGI::ProcManager';
+  if (!defined $_[0] or (ref($_[0]) ne 'FCGI::ProcManager' and
+                        !UNIVERSAL::isa($_[0],'FCGI::ProcManager'))) {
+    $Q or $Q = $FCGI::ProcManager::Default->new;
+    unshift @_, $Q;
   }
+  return wantarray ? @_ : $Q;
+}
+
+=head2 pm_change_process_name
+
+=cut
+
+sub pm_change_process_name {
+  my ($this,$name) = self_or_default(@_);
+  $0 = $name;
+}
+
+=head2 pm_received_signal
+
+=cut
+
+sub pm_received_signal {
+  my ($this,$sig,$received) = self_or_default(@_);
+  $sig or return $this->{SIG_RECEIVED};
+  $received and $this->{SIG_RECEIVED}->{$sig}++;
+  return $this->{SIG_RECEIVED}->{$sig};
+}
+
+=head2 pm_parameter
+
+=cut
+
+sub pm_parameter {
+  my ($this,$key,$value) = self_or_default(@_);
+  defined $value and $this->{$key} = $value;
+  return $this->{$key};
 }
 
+=head2 n_processes
+
+=head2 no_signals
+
+=head2 pid_fname
+
+=head2 die_timeout
+
+=head2 role
+
+=head2 start_delay
+
+=cut
+
+sub n_processes     { shift->pm_parameter("n_processes",     @_); }
+sub pid_fname       { shift->pm_parameter("pid_fname",       @_); }
+sub no_signals      { shift->pm_parameter("no_signals",      @_); }
+sub die_timeout     { shift->pm_parameter("die_timeout",     @_); }
+sub role            { shift->pm_parameter("role",            @_); }
+sub start_delay     { shift->pm_parameter("start_delay",     @_); }
+
 =head2 pm_warn
 
 =cut
 
 sub pm_warn {
   my ($this,$msg) = self_or_default(@_);
-  print STDERR $msg;
+  $this->pm_notify($msg);
+}
+
+=head2 pm_notify
+
+=cut
+
+sub pm_notify {
+  my ($this,$msg) = self_or_default(@_);
+  $msg =~ s/\s*$/\n/;
+  print STDERR "FastCGI: ".$this->role()." (pid $$): ".$msg;
 }
 
 =head2 exit
diff --git a/README b/README
index 7ca6c0c..fbe7f8c 100644 (file)
--- a/README
+++ b/README
@@ -1,11 +1,13 @@
-$Id: README,v 1.3 2000/11/15 20:14:56 muaddib Exp $
+$Id: README,v 1.4 2001/01/31 07:13:44 muaddib Exp $
 
 General Information
 -------------------
 
-FCGI-ProcManager is a process manager for FCGI.
+FCGI-ProcManager is a process manager for FCGI.  By implementing the
+process manager in perl, we can more finely tune FastCGI performance, and 
+we can take CPU and memory advantages of fast forks and copy-on-right UNIX
+process management characteristics.
 
-more info later.
 
 Installation
 ------------
index 553cd31..6580997 100644 (file)
@@ -5,17 +5,15 @@
 # General Public License, Version 2.1, a copy of which can be
 # found in the "COPYING" file of this distribution.
 
-# $Id: exporter.t,v 1.1 2001/01/13 06:44:33 muaddib Exp $
+# $Id: exporter.t,v 1.3 2001/01/31 06:57:09 muaddib Exp $
 
 use strict;
 use Test;
 
-BEGIN { plan tests => 5; }
+BEGIN { plan tests => 4; }
 
 use FCGI::ProcManager qw(:all);
 
-ok pm_state() eq "idle";
-
 ok pm_parameter('n_processes',100) == 100;
 ok pm_parameter('n_processes',2) == 2;
 ok pm_parameter('n_processes',0) == 0;
@@ -27,7 +25,7 @@ ok pm_manage();
 #ok $@ =~ /dying from number of processes exception: -3/;
 #undef $@;
 
-pm_parameter('n_processes',20);
+pm_parameter('n_processes',10);
 
 #pm_manage();
 #sample_request_loop();
@@ -39,15 +37,15 @@ sub sample_request_loop {
   while (1) {
     # Simulate blocking for a request.
     my $t1 = int(rand(2)+1);
-    print "$$ waiting for $t1..\n";
+    print "TEST: simulating blocking for request: $t1 seconds.\n";
     sleep $t1;
     # (Here is where accept-fail-on-intr would exit request loop.)
 
     pm_pre_dispatch();
 
     # Simulate a request dispatch.
-    my $t = int(rand(3)+1);
-    print "$$ sleeping $t..\n";
+    my $t = int(rand(3)+2);
+    print "TEST: simulating request: sleeping $t seconds.\n";
     while (my $nslept = sleep $t) {
       $t -= $nslept;
       last unless $t;
index 28131c3..e4b0076 100644 (file)
@@ -5,19 +5,18 @@
 # General Public License, Version 2.1, a copy of which can be
 # found in the "COPYING" file of this distribution.
 
-# $Id: procmanager.t,v 1.4 2001/01/13 06:44:35 muaddib Exp $
+# $Id: procmanager.t,v 1.6 2001/01/31 06:57:28 muaddib Exp $
 
 use strict;
 use Test;
 
-BEGIN { plan tests => 6; }
+BEGIN { plan tests => 5; }
 
 use FCGI::ProcManager;
 
 my $m;
 
 ok $m = FCGI::ProcManager->new();
-ok $m->pm_state() eq "idle";
 
 ok $m->n_processes(100) == 100;
 ok $m->n_processes(2) == 2;
@@ -30,7 +29,7 @@ ok $m->pm_manage();
 #ok $@ =~ /dying from number of processes exception: -3/;
 #undef $@;
 
-$m->n_processes(20);
+$m->n_processes(10);
 
 #$m->pm_manage();
 #sample_request_loop($m);
@@ -42,16 +41,16 @@ sub sample_request_loop {
 
   while (1) {
     # Simulate blocking for a request.
-    my $t1 = int(rand(2)+1);
-    print "$$ waiting for $t1..\n";
+    my $t1 = int(rand(2)+2);
+    print "TEST: simulating blocking for request: $t1 seconds.\n";
     sleep $t1;
     # (Here is where accept-fail-on-intr would exit request loop.)
 
     $m->pm_pre_dispatch();
 
     # Simulate a request dispatch.
-    my $t = int(rand(3)+1);
-    print "$$ sleeping $t..\n";
+    my $t = int(rand(3)+2);
+    print "TEST: simulating new request: $t seconds.\n";
     while (my $nslept = sleep $t) {
       $t -= $nslept;
       last unless $t;