RE: Breaks in mod_perl, works in Perl

2002-03-06 Thread Mark Hazen

Mark Hazen wrote:
 I am hoping there is a someone brilliant on this list that can help me.
A
 little while ago, I posted to clp.perl asking how I can capture the trace
 output from DBI into a variable.  Since DBI is an external process, I
 couldn't do it just by piping STDERR.  Benjamin Goldberg came up with a
 module called IO::Capture (see below).  It works amazingly well in
standard
 Perl.  Here is a sample script:

 use IO::Capture;
 $capturer = IO::Capture-new(\*STDERR);

Doesn't IO::Scalar do the same?
http://perl.apache.org/guide/porting.html#Redirecting_STDOUT_into_a_Scalar

IO::Scalar can redirect STDOUT for the mod_perl script itself, but not any
external processes like DBI.  I am still left without a solution.  It amazes
me.

Mark




Re: Breaks in mod_perl, works in Perl

2002-03-06 Thread Brian Reichert

On Wed, Mar 06, 2002 at 11:02:51AM -0700, Mark Hazen wrote:
 IO::Scalar can redirect STDOUT for the mod_perl script itself, but not any
 external processes like DBI.  I am still left without a solution.  It amazes
 me.

But using DBI isn't an 'external process', is it?  It's a part of your
process, and hence should make use of whatver you're STDERR handle is.

WHy not cop oot, and just redirect STDERR to a file, and collect
it's output when youre done?  Not graceful, but low-tech...

 
 Mark
 

-- 
Brian 'you Bastard' Reichert[EMAIL PROTECTED]
37 Crystal Ave. #303Daytime number: (603) 434-6842
Derry NH 03038-1713 USA Intel architecture: the left-hand path



RE: Breaks in mod_perl, works in Perl

2002-03-06 Thread Mark Hazen

On Wed, Mar 06, 2002 at 11:02:51AM -0700, Mark Hazen wrote:
 IO::Scalar can redirect STDOUT for the mod_perl script itself, but not
any
 external processes like DBI.  I am still left without a solution.  It
amazes
 me.

But using DBI isn't an 'external process', is it?  It's a part of your
process, and hence should make use of whatver you're STDERR handle is.

WHy not cop oot, and just redirect STDERR to a file, and collect
it's output when youre done?  Not graceful, but low-tech...

I wish this were true, but no one will ever get IO::Scalar to catch DBI's
STDERR output.  Throwing all this stuff into a file is already something DBI
can do, but as I already said, opening several hundred files per minute will
overwhelm my system.

Mark




RE: Breaks in mod_perl, works in Perl

2002-03-06 Thread Mark Hazen

Mark Hazen wrote:
 I wish this were true, but no one will ever get IO::Scalar to catch DBI's
 STDERR output.

If so, it's only because STDERR under mod_perl is already tied.  DBI is
not an external process.

 Throwing all this stuff into a file is already something DBI
 can do, but as I already said, opening several hundred files per minute
will
 overwhelm my system.

I don't think it does that.  It should open one file per process that
has tracing turned on and keep writing to it.  I already suggested that
you can just turn it on for a single process.  That would mean one file
being written to by one process, which is very unlikely to overwhelm any
system.

That's your opinion.  In my opinion, a bunch of disk IO and file seeks are a
waste of resources.  The bigger issue here is that it is better to store in
memory, and it saddens me that it doesn't seem possible.

Mark




Re: Breaks in mod_perl, works in Perl

2002-03-06 Thread Paul Lindner

On Wed, Mar 06, 2002 at 11:27:28AM -0700, Mark Hazen wrote:
 Mark Hazen wrote:
  I wish this were true, but no one will ever get IO::Scalar to catch DBI's
  STDERR output.
 
 If so, it's only because STDERR under mod_perl is already tied.  DBI is
 not an external process.
 
  Throwing all this stuff into a file is already something DBI
  can do, but as I already said, opening several hundred files per minute
 will
  overwhelm my system.
 
 I don't think it does that.  It should open one file per process that
 has tracing turned on and keep writing to it.  I already suggested that
 you can just turn it on for a single process.  That would mean one file
 being written to by one process, which is very unlikely to overwhelm any
 system.
 
 That's your opinion.  In my opinion, a bunch of disk IO and file seeks are a
 waste of resources.  The bigger issue here is that it is better to store in
 memory, and it saddens me that it doesn't seem possible.

This is a design flaw of DBI then.  You might get more results if you
post on the DBI users list.  We got part of the way there by
redefining the trace_msg function, the only part that remains is
gathering the output of the lower-level DBD calls, that might involve
modifying some XS code, (or it might not)..

Propose a 'callback' interface on dbi-users, you'll probably get a
warm reception.

-- 
Paul Lindner[EMAIL PROTECTED]   | | | | |  |  |  |   |   |

mod_perl Developer's Cookbook   http://www.modperlcookbook.org/
 Human Rights Declaration   http://www.unhchr.ch/udhr/index.htm



Re: Breaks in mod_perl, works in Perl

2002-03-06 Thread Stas Bekman

Mark Hazen wrote:
 Mark Hazen wrote:
 
I wish this were true, but no one will ever get IO::Scalar to catch DBI's
STDERR output.

 
If so, it's only because STDERR under mod_perl is already tied.  DBI is
not an external process.

 
Throwing all this stuff into a file is already something DBI
can do, but as I already said, opening several hundred files per minute

 will
 
overwhelm my system.

 
I don't think it does that.  It should open one file per process that
has tracing turned on and keep writing to it.  I already suggested that
you can just turn it on for a single process.  That would mean one file
being written to by one process, which is very unlikely to overwhelm any
system.

 
 That's your opinion.  In my opinion, a bunch of disk IO and file seeks are a
 waste of resources.  The bigger issue here is that it is better to store in
 memory, and it saddens me that it doesn't seem possible.

Hmm, then create a ramdisk and read from the file virtually stored in 
the RAM.

_
Stas Bekman JAm_pH  --   Just Another mod_perl Hacker
http://stason.org/  mod_perl Guide   http://perl.apache.org/guide
mailto:[EMAIL PROTECTED]  http://ticketmaster.com http://apacheweek.com
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/




Re: Breaks in mod_perl, works in Perl

2002-03-06 Thread Mark Fowler

On Thu, 7 Mar 2002, Stas Bekman wrote:

 Mark Hazen wrote:
  That's your opinion.  In my opinion, a bunch of disk IO and file seeks are a
  waste of resources.  The bigger issue here is that it is better to store in
  memory, and it saddens me that it doesn't seem possible.
 
 Hmm, then create a ramdisk and read from the file virtually stored in 
 the RAM.

Why should this be necessary?  Since writes to disk don't happen 
immediatly writing to 'disk' and reading it back in again and then 
deleting the file should all happen in cache and not actually hit the hdd 
at all (unless of course you run out of memory in which case slamming it 
to disk would be no worse than a page hit) correct?

Or am I missing something?

Later.

Mark.

-- 
s''  Mark Fowler London.pm   Bath.pm
 http://www.twoshortplanks.com/  [EMAIL PROTECTED]
';use Term'Cap;$t=Tgetent Term'Cap{};print$t-Tputs(cl);for$w(split/  +/
){for(0..30){$|=print$t-Tgoto(cm,$_,$y). $w;select$k,$k,$k,.03}$y+=2}





RE: Breaks in mod_perl, works in Perl

2002-03-06 Thread Mark Hazen

Hmm, then create a ramdisk and read from the file virtually stored in
the RAM.

Stas,

This is an elegant solution that I had not thought of.  My problem is that I
can't get ramdisks to work on my Red Hat 6.2 with 2.4.9 machine.  But that's
really my problem, and you've all been a big help.

Thanks
Mark




RE: Breaks in mod_perl, works in Perl

2002-03-06 Thread Mark Hazen


This is a design flaw of DBI then.  You might get more results if you
post on the DBI users list.  We got part of the way there by
redefining the trace_msg function, the only part that remains is
gathering the output of the lower-level DBD calls, that might involve
modifying some XS code, (or it might not)..

Propose a 'callback' interface on dbi-users, you'll probably get a
warm reception.

I agree.  This always was a design flaw of DBI.  I was only hoping that
there would be another way around it.  I took this to the creator of DBI
long before posting here and never heard back.  I will take it to dbi-users
and see where I get.

Thanks for all the help you gave.
Mark




Re: Breaks in mod_perl, works in Perl

2002-03-06 Thread Jeremy Howard

Mark Hazen wrote:
 Hmm, then create a ramdisk and read from the file virtually stored in
 the RAM.

 Stas,

 This is an elegant solution that I had not thought of.  My problem is that
I
 can't get ramdisks to work on my Red Hat 6.2 with 2.4.9 machine.  But
that's
 really my problem, and you've all been a big help.

Have a look at TMPFS. It creates a RAM-based filesystem that is more
flexible than a RAM disk. Add to your /etc/fstab:

none  /tmpfs   tmpfs  defaults,noatime,size=200M 0 0

...or something similar, and away you go!





Breaks in mod_perl, works in Perl

2002-03-05 Thread Mark Hazen

I am hoping there is a someone brilliant on this list that can help me.  A
little while ago, I posted to clp.perl asking how I can capture the trace
output from DBI into a variable.  Since DBI is an external process, I
couldn't do it just by piping STDERR.  Benjamin Goldberg came up with a
module called IO::Capture (see below).  It works amazingly well in standard
Perl.  Here is a sample script:

use IO::Capture;
$capturer = IO::Capture-new(\*STDERR);

use DBI;
$dbh = DBI-connect (DBI:mysql:test:localhost, username, password, {
RaiseError = 0, PrintError = 0 });

DBI-trace( 1 );

$sth = $dbh-prepare (qq{
 CREATE TABLE IF NOT EXISTS test_table
 (
a CHAR(15) NOT NULL,
b INT UNSIGNED NOT NULL
 )
 });
$sth-execute ();
$sth-finish ();

$dbh-disconnect ();

$text = $capturer-capture;

print qq{
Output is:
$text
};



The problem is that once I try this script through mod_perl, it hangs the
child process infinitely.  And then on subsequent requests, it has to create
a new process.  This eventually results in the whole machine spiraling down
because hundreds of Apache children are hung.  What I am hoping is that
someone will spot something that neither Ben nor I have been able to spot.
The module appears after my name.

Thanks for any help you can provide.
Mark


package IO::Capture;
use strict;
use warnings;
use Symbol qw(gensym);

sub new {
   (my ($class, $filehandle) = _) == 2
   or croak(Usage: IO::Capture-new(\$filehandle));
   if( ref $filehandle or ref \$filehandle eq GLOB ) {
  $filehandle = \*$filehandle; # this is a sort of typecast.
   } else {
  $filehandle = caller() . :: . $filehandle
  unless $filehandle =~ /::/ or
  $filehandle =~ /^STD(?:IN|OUT|ERR)\z/;
  no strict 'refs';
  $filehandle = \*$filehandle;
   }
   defined(fileno $filehandle)
   or croak(Argument to IO::Capture-new has no fileno());
   my $save = gensym;
   open $save, .fileno($filehandle)
  or die sprintf(Couldn't dup2(%s,%s): $!\n,
 fileno($save),fileno($filehandle));
   my  ($getresponse, $sendresponse) = (gensym, gensym);
   pipe($getresponse, $sendresponse) or die pipe: $!;
   my  ($readnew, $writenew) = (gensym, gensym);
   pipe($readnew, $writenew) or die pipe: $!;
   open( $filehandle,  . fileno($writenew) )
  or die sprintf(Couldn't dup2(%s,%s): $!\n,
 fileno($filehandle),fileno($writenew));
   close($writenew);
   defined( my $pid = fork ) or do {
  my $err = $!;
  unless( open $filehandle, .fileno $save ) {
 my $err2 = $!;
 open STDERR, $^O =~ /win/i ? con : /dev/tty
 if $filehandle == \*STDERR;
 die fork: $err, dup2: $err2;
  }
  die fork: $err;
   };
   # readnew, writenew, and sendresponse are automatically closed
   # when we return here in the parent because they go out of scope,
   # resulting in their their refcounts going to 0.
   return bless [$filehandle, $save, $getresponse, $pid], $class
  if $pid;
   close($getresponse); # not used, so close it.
   close($writenew); # MUST close this, or deadlock will occur!
   # MUST close or re-open $filehandle, or deadlock will occur!
   $filehandle == \*STDERR and (
  open STDERR, .fileno $save or
  open STDERR, $^O =~ /win/i ? con : /dev/tty
   ) or close $filehandle;
   close $save; # not used from here on, so close it.
   my ($got, $n) = ;
   1 while $n = sysread $readnew, $got, 4096, length $got;
   die sysread: $! unless defined $n;
   print $sendresponse $got or die print: $!;
   exit;
}

sub capture {
   my $self = shift;
   my ($fh, $saved, $get, $pid) = splice $self, 0;
   unless( open $fh,  . fileno $saved ) {
  open $fh, $^O =~ /win/i ? con : /dev/tty
 if $fh == \*STDERR;
  die Couldn't restore filehandle: $!;
   } else { close $saved }
   my ($got, $n) = ;
   while($n = sysread $get, $got, 4096, length $got) {}
   defined($n) or die sysread: $!;
   if( waitpid $pid, 0 ) {
  warn sprintf Child exited with code 0x%04X, $? if $?;
   } else { warn waitpid: $! } return $got;
}

# like using autouse.pm but even more lightweight.
sub croak {
   undef croak;
   require Carp;
   *croak = \Carp::croak;
   goto croak;
}

1;
__END__
perl -MIO::Capture
   $x = IO::Capture-new(\*STDERR);
   print now capturing\n;
   warn qq[captured ok\n];
   print captured text 'captured ok' shouldn't have appeard\n;
   $y = $x-capture;
   print capture didn't block\n;
   print $y;
   warn Restored ok\n;
__END__
now capturing
captured text 'captured ok' shouldn't have appeard
capture didn't block
captured ok
Restored ok

perl -MIO::Capture
   $x = IO::Capture-new(\*STDERR);
   print now capturing\n;
   system(q[perl -e print STDERR qq[captured ok\n]]);
   print captured text 'captured ok' shouldn't have appeard\n;
   $y = $x-capture;
   print capture didn't block\n;
   print $y;
   warn Restored ok\n;
__END__
now capturing
captured text 'captured ok' shouldn't have appeard
capture didn't block
captured ok
Restored ok




Re: Breaks in mod_perl, works in Perl

2002-03-05 Thread Robert Landrum

At 1:14 PM -0700 3/5/02, Mark Hazen wrote:
I am hoping there is a someone brilliant on this list that can help me  A
little while ago, I posted to clpperl asking how I can capture the trace
output from DBI into a variable  Since DBI is an external process, I
couldn't do it just by piping STDERR  Benjamin Goldberg came up with a
module called IO::Capture (see below)  It works amazingly well in standard
Perl  Here is a sample script:



Maybe I'm just crazy but wouldn't this be simpler?

use DBI;
$dbh = DBI-connect (DBI:mysql:test:localhost, username, password, {
RaiseError = 0, PrintError = 0 });

$filename = /tmp/dbi_$$time()rand(1)trace;

DBI-trace( 1, $filename );

$sth = $dbh-prepare (qq{
  CREATE TABLE IF NOT EXISTS test_table
  (
 a CHAR(15) NOT NULL,
 b INT UNSIGNED NOT NULL
  )
  });
$sth-execute ();
$sth-finish ();

$dbh-disconnect ();


print qq{
Output is:
};

open(FILE,$filename);
print while(FILE);
close(FILE);

The problem with the module listed is that it does some filehandle 
munging on what is already a munged filehandler  Meaning, it looks 
like a filehandle, but it's really just a hook into something apache 
is going to use to output stuff to the error log

Hope that helps

Rob

--
When I used a Mac, they laughed because I had no command prompt When 
I used Linux, they laughed because I had no GUI  



RE: Breaks in mod_perl, works in Perl

2002-03-05 Thread Mark Hazen

I'm sorry I didn't explain an important component.  Since I am dealing with
a few hundred requests per minute (this was got me onto mod_perl to begin
with), then using DBI's ability to write to a file would vastly overwhelm my
system.

Thanks
Mark

-Original Message-
From: Robert Landrum [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, March 05, 2002 1:25 PM
To: Mark Hazen; [EMAIL PROTECTED]
Subject: Re: Breaks in mod_perl, works in Perl


At 1:14 PM -0700 3/5/02, Mark Hazen wrote:
I am hoping there is a someone brilliant on this list that can help me.  A
little while ago, I posted to clp.perl asking how I can capture the trace
output from DBI into a variable.  Since DBI is an external process, I
couldn't do it just by piping STDERR.  Benjamin Goldberg came up with a
module called IO::Capture (see below).  It works amazingly well in standard
Perl.  Here is a sample script:



Maybe I'm just crazy but wouldn't this be simpler?

use DBI;
$dbh = DBI-connect (DBI:mysql:test:localhost, username, password, {
RaiseError = 0, PrintError = 0 });

$filename = /tmp/dbi_.$$.time().rand(1)..trace;

DBI-trace( 1, $filename );

$sth = $dbh-prepare (qq{
  CREATE TABLE IF NOT EXISTS test_table
  (
 a CHAR(15) NOT NULL,
 b INT UNSIGNED NOT NULL
  )
  });
$sth-execute ();
$sth-finish ();

$dbh-disconnect ();


print qq{
Output is:
};

open(FILE,$filename);
print while(FILE);
close(FILE);

The problem with the module listed is that it does some filehandle
munging on what is already a munged filehandler.  Meaning, it looks
like a filehandle, but it's really just a hook into something apache
is going to use to output stuff to the error log.

Hope that helps...

Rob

--
When I used a Mac, they laughed because I had no command prompt. When
I used Linux, they laughed because I had no GUI.




Re: Breaks in mod_perl, works in Perl

2002-03-05 Thread Paul Lindner

I'm not sure if this will work, but you might override DBI's notion of
a trace function.  If you look in DBI.pm you'll see this line:

  *trace_msg = \DBD::_::common::trace_msg;

It appears that DBI uses the trace_msg function in the bowels of DBD
to actually do the printing.  Now, you can very likely override this
with something else..  Perhaps something like this:

use DBI;
.
my $output;
my $oldhandle;
sub capture {
  $output .= join('', @_);
}

*DBI::trace_msg = \capture;

$dbh = .
# etc...


In an ideal world you could just subclass DBI and redefine the trace
message, alas DBI uses this construct quite often:

  DBI-trace_msg(...)



On Tue, Mar 05, 2002 at 01:14:11PM -0700, Mark Hazen wrote:
 I am hoping there is a someone brilliant on this list that can help me.  A
 little while ago, I posted to clp.perl asking how I can capture the trace
 output from DBI into a variable.  Since DBI is an external process, I
 couldn't do it just by piping STDERR.  Benjamin Goldberg came up with a
 module called IO::Capture (see below).  It works amazingly well in standard
 Perl.  Here is a sample script:
 
 use IO::Capture;
 $capturer = IO::Capture-new(\*STDERR);
 
 use DBI;
 $dbh = DBI-connect (DBI:mysql:test:localhost, username, password, {
 RaiseError = 0, PrintError = 0 });
 
 DBI-trace( 1 );
 
 $sth = $dbh-prepare (qq{
  CREATE TABLE IF NOT EXISTS test_table
  (
 a CHAR(15) NOT NULL,
 b INT UNSIGNED NOT NULL
  )
  });
 $sth-execute ();
 $sth-finish ();
 
 $dbh-disconnect ();
 
 $text = $capturer-capture;
 
 print qq{
 Output is:
 $text
 };
 
 
 
 The problem is that once I try this script through mod_perl, it hangs the
 child process infinitely.  And then on subsequent requests, it has to create
 a new process.  This eventually results in the whole machine spiraling down
 because hundreds of Apache children are hung.  What I am hoping is that
 someone will spot something that neither Ben nor I have been able to spot.
 The module appears after my name.
 
 Thanks for any help you can provide.
 Mark
 
 
 package IO::Capture;
 use strict;
 use warnings;
 use Symbol qw(gensym);
 
 sub new {
(my ($class, $filehandle) = @_) == 2
or croak(Usage: IO::Capture-new(\$filehandle));
if( ref $filehandle or ref \$filehandle eq GLOB ) {
   $filehandle = \*$filehandle; # this is a sort of typecast.
} else {
   $filehandle = caller() . :: . $filehandle
   unless $filehandle =~ /::/ or
   $filehandle =~ /^STD(?:IN|OUT|ERR)\z/;
   no strict 'refs';
   $filehandle = \*$filehandle;
}
defined(fileno $filehandle)
or croak(Argument to IO::Capture-new has no fileno());
my $save = gensym;
open $save, .fileno($filehandle)
   or die sprintf(Couldn't dup2(%s,%s): $!\n,
  fileno($save),fileno($filehandle));
my  ($getresponse, $sendresponse) = (gensym, gensym);
pipe($getresponse, $sendresponse) or die pipe: $!;
my  ($readnew, $writenew) = (gensym, gensym);
pipe($readnew, $writenew) or die pipe: $!;
open( $filehandle,  . fileno($writenew) )
   or die sprintf(Couldn't dup2(%s,%s): $!\n,
  fileno($filehandle),fileno($writenew));
close($writenew);
defined( my $pid = fork ) or do {
   my $err = $!;
   unless( open $filehandle, .fileno $save ) {
  my $err2 = $!;
  open STDERR, $^O =~ /win/i ? con : /dev/tty
  if $filehandle == \*STDERR;
  die fork: $err, dup2: $err2;
   }
   die fork: $err;
};
# readnew, writenew, and sendresponse are automatically closed
# when we return here in the parent because they go out of scope,
# resulting in their their refcounts going to 0.
return bless [$filehandle, $save, $getresponse, $pid], $class
   if $pid;
close($getresponse); # not used, so close it.
close($writenew); # MUST close this, or deadlock will occur!
# MUST close or re-open $filehandle, or deadlock will occur!
$filehandle == \*STDERR and (
   open STDERR, .fileno $save or
   open STDERR, $^O =~ /win/i ? con : /dev/tty
) or close $filehandle;
close $save; # not used from here on, so close it.
my ($got, $n) = ;
1 while $n = sysread $readnew, $got, 4096, length $got;
die sysread: $! unless defined $n;
print $sendresponse $got or die print: $!;
exit;
 }
 
 sub capture {
my $self = shift;
my ($fh, $saved, $get, $pid) = splice @$self, 0;
unless( open $fh,  . fileno $saved ) {
   open $fh, $^O =~ /win/i ? con : /dev/tty
  if $fh == \*STDERR;
   die Couldn't restore filehandle: $!;
} else { close $saved }
my ($got, $n) = ;
while($n = sysread $get, $got, 4096, length $got) {}
defined($n) or die sysread: $!;
if( waitpid $pid, 0 ) {
   warn sprintf Child exited with code 0x%04X, $? if $?;
} else { warn waitpid: $! } return $got;
 }
 
 # like using autouse.pm but even more lightweight.
 sub croak {
undef croak;
require Carp;

Re: Breaks in mod_perl, works in Perl

2002-03-05 Thread Perrin Harkins

Mark Hazen wrote:
 I'm sorry I didn't explain an important component  Since I am dealing with
 a few hundred requests per minute (this was got me onto mod_perl to begin
 with), then using DBI's ability to write to a file would vastly overwhelm my
 system

Won't capturing that much data in RAM instantly send your system into swap?

Anyway, you can probably get this to work if you can ask DBI to send to 
a filehandle and then use your magic IO::Capture on that filehandle 
You just can't use STDERR because it's already magic

By the way, at one point we used this DBI trace stuff at eToys  It was 
fairly light on a fast file system like ext2fs  The trick to making it 
really light is to fix it so that only one child process per machine had 
tracing turned on, which you can do with a little fussing with a pid 
file and a ChildInitHandler and ChildExitHandler  If you just need to 
see some trace output, you can use this technique  On the other hand, 
your debugging may require seeing trace from every active process in 
which case this won't help

- Perrin




RE: Breaks in mod_perl, works in Perl

2002-03-05 Thread Robert Landrum

At 1:32 PM -0700 3/5/02, Mark Hazen wrote:
I'm sorry I didn't explain an important component  Since I am dealing with
a few hundred requests per minute (this was got me onto mod_perl to begin
with), then using DBI's ability to write to a file would vastly overwhelm my
system


I don't get it You don't mind trying to create tables a few 
hundred times per minute, but creating a file is too much overhead?

And writing to memory is going to really bog the system

Maybe you shouldn't be asking why doesn't my capture work, but how 
can I debug some production code I have

Just a thought,

Rob



--
When I used a Mac, they laughed because I had no command prompt When 
I used Linux, they laughed because I had no GUI  



RE: Breaks in mod_perl, works in Perl

2002-03-05 Thread Mark Hazen

I am sorry for further confusion.  I am not creating tables a few hundred
times per minute.  I simply used a create table call to get some trace
output for my sample script.  Thinking that users may try the sample script,
there was a no way for me to know what tables might exist (that I could
select from).  So I used a CREATE TABLE.  Writing to memory, if done right,
shouldn't be a big deal.  Having the disk seek that often would flood my IO.

Thanks
Mark

-Original Message-
From: Robert Landrum [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, March 05, 2002 2:14 PM
To: Mark Hazen; [EMAIL PROTECTED]
Subject: RE: Breaks in mod_perl, works in Perl


At 1:32 PM -0700 3/5/02, Mark Hazen wrote:
I'm sorry I didn't explain an important component.  Since I am dealing with
a few hundred requests per minute (this was got me onto mod_perl to begin
with), then using DBI's ability to write to a file would vastly overwhelm
my
system.


I don't get it You don't mind trying to create tables a few
hundred times per minute, but creating a file is too much overhead?

And writing to memory is going to really bog the system.

Maybe you shouldn't be asking why doesn't my capture work, but how
can I debug some production code I have...

Just a thought,

Rob



--
When I used a Mac, they laughed because I had no command prompt. When
I used Linux, they laughed because I had no GUI.




RE: Breaks in mod_perl, works in Perl

2002-03-05 Thread Mark Hazen

Paul,

You are onto something here.  I used your method, and was able to get the
following:
DBI - DBI-Apache::DBI::connect(DBI:mysql:db:localhost, username, ) DBI
- connect= Apache::DBI::db=HASH(0x842d608)

into the variable.  But the full trace output is:
- DBI-Apache::DBI::connect(DBI:mysql:db:localhost, username, )
- FETCH= 'mysql' ('Name' from cache) at DBI.pm line 64
- ping= 1 at DBI.pm line 112
- STORE('RaiseError' 0 ...)= 1 at DBI.pm line 451
- STORE('PrintError' 0 ...)= 1 at DBI.pm line 451
- STORE('AutoCommit' 1 ...)= 1 at DBI.pm line 451

It also would disappear between requests.  In other words, as I reloaded the
script, about half the time, the variable would be completely blank, and
another half it would be what I mentioned above.

Thanks
Mark

-Original Message-
From: Paul Lindner [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, March 05, 2002 1:41 PM
To: Mark Hazen
Cc: [EMAIL PROTECTED]
Subject: Re: Breaks in mod_perl, works in Perl


I'm not sure if this will work, but you might override DBI's notion of
a trace function.  If you look in DBI.pm you'll see this line:

  *trace_msg = \DBD::_::common::trace_msg;

It appears that DBI uses the trace_msg function in the bowels of DBD
to actually do the printing.  Now, you can very likely override this
with something else..  Perhaps something like this:

use DBI;
.
my $output;
my $oldhandle;
sub capture {
  $output .= join('', @_);
}

*DBI::trace_msg = \capture;

$dbh = .
# etc...


In an ideal world you could just subclass DBI and redefine the trace
message, alas DBI uses this construct quite often:

  DBI-trace_msg(...)



On Tue, Mar 05, 2002 at 01:14:11PM -0700, Mark Hazen wrote:
 I am hoping there is a someone brilliant on this list that can help me.  A
 little while ago, I posted to clp.perl asking how I can capture the trace
 output from DBI into a variable.  Since DBI is an external process, I
 couldn't do it just by piping STDERR.  Benjamin Goldberg came up with a
 module called IO::Capture (see below).  It works amazingly well in
standard
 Perl.  Here is a sample script:

 use IO::Capture;
 $capturer = IO::Capture-new(\*STDERR);

 use DBI;
 $dbh = DBI-connect (DBI:mysql:test:localhost, username, password, {
 RaiseError = 0, PrintError = 0 });

 DBI-trace( 1 );

 $sth = $dbh-prepare (qq{
  CREATE TABLE IF NOT EXISTS test_table
  (
 a CHAR(15) NOT NULL,
 b INT UNSIGNED NOT NULL
  )
  });
 $sth-execute ();
 $sth-finish ();

 $dbh-disconnect ();

 $text = $capturer-capture;

 print qq{
 Output is:
 $text
 };



 The problem is that once I try this script through mod_perl, it hangs the
 child process infinitely.  And then on subsequent requests, it has to
create
 a new process.  This eventually results in the whole machine spiraling
down
 because hundreds of Apache children are hung.  What I am hoping is that
 someone will spot something that neither Ben nor I have been able to spot.
 The module appears after my name.

 Thanks for any help you can provide.
 Mark


 package IO::Capture;
 use strict;
 use warnings;
 use Symbol qw(gensym);

 sub new {
(my ($class, $filehandle) = @_) == 2
or croak(Usage: IO::Capture-new(\$filehandle));
if( ref $filehandle or ref \$filehandle eq GLOB ) {
   $filehandle = \*$filehandle; # this is a sort of typecast.
} else {
   $filehandle = caller() . :: . $filehandle
   unless $filehandle =~ /::/ or
   $filehandle =~ /^STD(?:IN|OUT|ERR)\z/;
   no strict 'refs';
   $filehandle = \*$filehandle;
}
defined(fileno $filehandle)
or croak(Argument to IO::Capture-new has no fileno());
my $save = gensym;
open $save, .fileno($filehandle)
   or die sprintf(Couldn't dup2(%s,%s): $!\n,
  fileno($save),fileno($filehandle));
my  ($getresponse, $sendresponse) = (gensym, gensym);
pipe($getresponse, $sendresponse) or die pipe: $!;
my  ($readnew, $writenew) = (gensym, gensym);
pipe($readnew, $writenew) or die pipe: $!;
open( $filehandle,  . fileno($writenew) )
   or die sprintf(Couldn't dup2(%s,%s): $!\n,
  fileno($filehandle),fileno($writenew));
close($writenew);
defined( my $pid = fork ) or do {
   my $err = $!;
   unless( open $filehandle, .fileno $save ) {
  my $err2 = $!;
  open STDERR, $^O =~ /win/i ? con : /dev/tty
  if $filehandle == \*STDERR;
  die fork: $err, dup2: $err2;
   }
   die fork: $err;
};
# readnew, writenew, and sendresponse are automatically closed
# when we return here in the parent because they go out of scope,
# resulting in their their refcounts going to 0.
return bless [$filehandle, $save, $getresponse, $pid], $class
   if $pid;
close($getresponse); # not used, so close it.
close($writenew); # MUST close this, or deadlock will occur!
# MUST close or re-open $filehandle, or deadlock will occur!
$filehandle == \*STDERR and (
   open

Re: Breaks in mod_perl, works in Perl

2002-03-05 Thread Stas Bekman

Mark Hazen wrote:
 I am hoping there is a someone brilliant on this list that can help me.  A
 little while ago, I posted to clp.perl asking how I can capture the trace
 output from DBI into a variable.  Since DBI is an external process, I
 couldn't do it just by piping STDERR.  Benjamin Goldberg came up with a
 module called IO::Capture (see below).  It works amazingly well in standard
 Perl.  Here is a sample script:
 
 use IO::Capture;
 $capturer = IO::Capture-new(\*STDERR);

Doesn't IO::Scalar do the same?
http://perl.apache.org/guide/porting.html#Redirecting_STDOUT_into_a_Scalar

_
Stas Bekman JAm_pH  --   Just Another mod_perl Hacker
http://stason.org/  mod_perl Guide   http://perl.apache.org/guide
mailto:[EMAIL PROTECTED]  http://ticketmaster.com http://apacheweek.com
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/