Why are my shared variables getting cleared out between PerlChildInitHandler and PerlResponseHandler in mod_perl? - perl

I am trying to load a configuration file into a hash during my PerlChildInitHandler and then access the values from PerlResponseHandler. However, even though the process number is the same, it seems that variables changed during the child_init() call revert back to their default values when handler() gets called.
The basic scenario is:
package StartupLog;
# the variable I'm testing
my $sticky = 0;
sub child_init {
$sticky = 1;
return 0;
}
sub handler {
warn __PACKAGE__ . " sticky = $sticky\n"; ### always says "0" but should say "1"
return 0;
}
1;

This was never answered, so eventually I moved on to using the PerlPostConfigHandler, which seemed to work acceptably. I can only assume it's something about the forking that happens in the PerlChildInitiHandler but, sorry to say, I gave up. Hope this helps someone in the future.

Generally, if you want to load something at childinit time, and access it in the response phase, you'd stuff it into a package global (like $My::variable = 'lols'). I've never tried to do it the way you are here. Did you try using our instead of my maybe?.

Related

Why am I getting this perl Net::Async::HTTP warning?

In this oversimplified script I'm doing a GET request with Net::Async::HTTP using IO::Async::Loop::EV:
use Modern::Perl '2017';
use IO::Async::Loop::EV;
use Net::Async::HTTP;
use Future;
my $loop = IO::Async::Loop::EV->new;
my $http = Net::Async::HTTP->new(max_redirects => 0);
$loop->add($http);
my $f = $http->GET('https://www.perl.org')
->then(sub {
my $response = shift;
printf STDERR "got resp code %d\n", $response->code;
return Future->done;
});
$http->adopt_future($f->else_done);
$loop->run;
I get this warning a couple of times:
EV: error in callback (ignoring): Can't call method "sysread" on an undefined value at .../IO/Async/Stream.pm line 974
I get this warning when using IO::Async::Loop::Event too (again in IO::Async::Stream, at line 974).
For non-secure (http) links, however, all looks good. So something's probably wrong with IO::Async::SSL. (I tried this on different machines, with different OS - still getting those warnings)
Why am I getting this warning multiple times? Does it occur on your machines too?
It seems this warning is specific to the IO::Async::Loop::EV implementation. If you just
use IO::Async::Loop;
my $loop = IO::Async::Loop->new;
then it appears to work just fine. Unless you're picking that for a specific purpose it's best to avoid it and just let the IO::Async::Loop->new magic constructor find a good one.
Additionally, rather than ending the script with
$loop->run
You could instead use
$f->get
so it performs a blocking wait until that Future is complete but then exits cleanly afterwards, so as not to have to <Ctrl-C> it to abort.
I've raised this as a bug against IO::Async::Loop::EV at https://rt.cpan.org/Ticket/Display.html?id=124030

How can I suppress this superflous debugger output in Eclipse/EPIC?

I have a strange problem with the Perl Debugger in EPIC. When I started using it, all worked fine as expected. I would set breakpoints, run a program in debug mode, step through it ... Then, something must have changed but I have no idea what. Now, the debugger or EPIC or Eclipse, I don't know who, sends tons of output to the console window that have nothing to do with my program but with the - seemingly to me - internals of EPIC or the Perl debugger. Here's a little cutout from this output, there is an endless amount of this and the things my program wants to output just get lost.
What is the problem here? I did not find any setting I could change in the preferences, I don't know what to search for, I couldn't find anything in the EPIC docs.
Edit: one thing I remember is I used "use diagnostics;" in another program that belongs to the project, but that is not run or used by the program that is producing this debug output. Maybe it has something to do with that? Can it "get stuck" and be remembered by the debugger later? I know it sounds silly, but that's all I got.
DB<396> ;{
do 'dumpvar_epic.pm' unless defined &dumpvar_epic::dump_lexical_vars;
my $offset = 0;
my $savout = CORE::select($DB::OUT);
dumpvar_epic::dump_lexical_vars($offset);
CORE::select($savout);
};
12|$forceingest|1|1|17|SCALAR(0x40fb5a4)|3|'0'|1|3
4|$lll|1|2|14|REF(0x2739ff4)|37|Log::Log4perl::Logger=HASH(0x41bbe64)|3|...|1|3
9|$reingest|1|1|17|SCALAR(0x40fbf14)|3|'1'|1|3
13|$secondsPause|1|1|17|SCALAR(0x40fb774)|5|'300'|1|5
4|$tdh|1|2|14|REF(0x40ff0dc)|15|GLOB(0x42e7484)|3|...|1|3
12|$transferDir|1|1|17|SCALAR(0x40f9f24)|31|'c:/temp/xml/transfer/probleme'|2|31
8|$usedata|1|1|17|SCALAR(0x40fbf84)|3|'1'|1|3
6|%datah|1|1|15|HASH(0x40f2f8c)|3|...|1|3
5|#data|1|1|16|ARRAY(0x41002ec)|3|...|1|3
13|#transactions|1|1|16|ARRAY(0x40ff07c)|3|...|1|3
14|#transferFiles|1|1|16|ARRAY(0x40ff04c)|3|...|1|3
7|#tx_ref|1|1|16|ARRAY(0x40feffc)|3|...|1|3
DB<397> ;{
do 'dumpvar_epic.pm' unless defined &dumpvar_epic::dump_lexical_vars;
my $offset = 0;
my $varexpr = <<'EOT';
${$h->{'$lll'}}
EOT
my $subref = \&dumpvar_epic::dump_hash_expr;
my $savout = CORE::select($DB::OUT);
my $savbuf = $|;
$| = 0;
$subref->($offset, $varexpr);
$| = $savbuf;
print "";
CORE::select($savout);
};
3|ALL|1|2|14|REF(0x41d9f64)|15|CODE(0x41dbee4)|3|...|1|3
5|DEBUG|1|2|14|REF(0x41d9ba4)|15|CODE(0x41dbee4)|3|...|1|3
5|ERROR|1|2|14|REF(0x41d737c)|15|CODE(0x41d9b34)|3|...|1|3
5|FATAL|1|2|14|REF(0x41d735c)|15|CODE(0x41d9b34)|3|...|1|3
4|INFO|1|2|14|REF(0x41d748c)|15|CODE(0x41d9b34)|3|...|1|3
3|OFF|1|2|14|REF(0x41d9fe4)|15|CODE(0x41d9b34)|3|...|1|3
5|TRACE|1|2|14|REF(0x41d9ee4)|15|CODE(0x41dbee4)|3|...|1|3
4|WARN|1|2|14|REF(0x41d717c)|15|CODE(0x41d9b34)|3|...|1|3
10|additivity|1|1|17|SCALAR(0x41d52bc)|3|'1'|1|3
Never mind. There is indeed a setting for that under Preferences/Perl EPIC/Enable Debugger Console. I enabled that setting previously because of another weird problem with the debugger (threads wouldn't terminate any more and hang there until Eclipse was restarted), which seemed to work. Disabling it stops the unwanted output. Maybe there's something really weird going on with Perl/EPIC on my computer...

SIG error during global destruction

I have an issue with a script I created. This is the first time I use signal as I would like my script to run like a daemon, so I set several signal Handler to properly end my script :
local $SIG{HUP} = \&StopSuperviser;
local $SIG{INT} = \&StopSuperviser;
local $SIG{QUIT} = \&StopSuperviser;
local $SIG{ILL} = \&StopSuperviser;
local $SIG{ABRT} = \&StopSuperviser;
local $SIG{TERM} = \&StopSuperviser;
This is working properly but when I send one of those signal to my script (Crt-C, kill -15, kill -1 ...) the StopSuperviser function is correctly called but I always receive the following error in my script's output:
Argument "HUP" isn't numeric in null operation during global destruction.
I have searched on google but I didn't find anything dealing with this behavior.
May someone put some light in this?
Thanks you very much for your help
Best Regards
Florent
#
Thanks four your replies, here is the StopSuperviser Function:
sub StopSuperviser
{
print "On quite\n";
$StopAlarm = 1;
&DeleteThreadOrder($AllProcess);
foreach my $Subprocess (#$AllProcess) {
foreach my $thread (#{$Subprocess->{Thread}}) {
$thread->kill('USR1');
$thread->join();
}
}
exit;
}
I also use the following package :
use Alarm::Concurrent;
This may important to know, or may not :)
Hope this help :)
Thanks again for your response and help
Best Regards
Florent
I had this problem earlier this year, and ended up finding the solution on PerlMonks, but I can't find the link now. I'll update if I come across it. Their explanation was much more detailed than what I present here.
It's an expression of a feature described in perlsub:
If a subroutine is called using the & form, the argument list is
optional, and if omitted, no #_ array is set up for the subroutine:
the #_ array at the time of the call is visible to subroutine instead.
If memory serves, you should be able to fix it by changing:
local $SIG{HUP} = \&StopSuperviser;
to
local $SIG{HUP} = sub { StopSuperviser() };

Should I re-use a single HTML::SimpleLinkExtor object for memory efficiency?

So this may seem like a silly question, but I'm building an application where memory is a very limited resource so I need to be as cautious about memory usage as I can. So my question is, which of the following is more memory efficient?
while(<LINKS_FILE>) {
my $extor = HTML::SimpleLinkExtor->new($resp->base); #$resp from above somewhere
$extor->parse($_);
my #links = $extor->links;
for my $link (#links) { print "$link\n" }
}
or
my $extor = HTML::SimpleLinkExtor->new($resp->base); #$resp from above somewhere
while(<LINKS_FILE>) {
$extor->parse($_);
my #links = $extor->links;
for my $link (#links) { print "$link\n" }
$extor->clear_links;
}
So in the first it creates a new HTML::SimleLinkExtor object every time, whereas in the second it just kind of resets the same one for use again. So it seems to me like the second one would be more memory efficient, but to be honest I don't really know how good perl is about releasing memory back to the os, or if it's gonna hold on to the memory for some of the HTML::SimpleLinkExtor objects even after they're out of scope. Thanks for the help!
I am not inclined to spend time profiling, but if I were in your situation, I would try HTML::LinkExtor first. If you provide a callback, it will not save the links it finds internally, reducing the footprint of your application. You can then decide whether to store the links, or maybe write to an external file, to keep memory use to a minimum:
use HTML::LinkExtor;
my $parser = HTML::LinkExtor->new(sub {
my($tag, %links) = #_;
print "$tag #{[%links]}\n";
});
$parser->parse_file("index.html");

How to ignore some subroutine calls in NYTProf reporting

I'm trying to profile a Perl script, but CORE::sleep gobble all the space (and time) of my report.
How can i tell NYTProf to ignore sleep calls ?
Assuming we have the following script :
sub BrandNewSubroutine {
sleep 10;
print "Odelay\n";
}
BrandNewSubroutine();
I want to get rid of the following line of the report :
Exclusive Time;Inclusive Time;Subroutine
10.0s;10.0s;main::::CORE:sleepmain::CORE:sleep
(opcode)
Edit: Using DB::disable_profile() and DB::enable_profile() won't do the trick, as it add sleep time to BrandNewSubroutine Inclusive time.
Thanks in advance.
I'd suggest either wrapping the calls to sleep (possibly by use of method mentioned in perlsub) with DB::disable_profile() and DB::enable_profile() calls (RUN-TIME CONTROL OF PROFILING in NYTProf documentation), or post processing the report to remove the offending calls.
CORE::accept is already ignored in the way you'd like CORE::sleep to be, so the mechanism is already in place. See this code in NYTProf.xs:
/* XXX make configurable eg for wait(), and maybe even subs like FCGI::Accept
* so perhaps use $hide_sub_calls->{$package}{$subname} to make it general.
* Then the logic would have to move out of this block.
*/
if (OP_ACCEPT == op_type)
subr_entry->hide_subr_call_time = 1;
So with a little hacking (OP_SLEEP==op_type || OP_ACCEPT == op_type) you'd be able to ignore CORE::sleep in the same way.
I'd accept a patch to enable that as an option.