Solved

Problem Calling Embedded Function within OO Perl - Namespace Issue??

Posted on 2004-04-03
9
291 Views
Last Modified: 2012-06-21
I am obviously missing something in this simplified example.  I have a 'custom module' for the function I have written over time.
This module uses function from other modules.  For this example - I am using a function from the Date::Manip module.

I am trying to use these functions from an instance of the Net::Server class.  When I call my custom function from a normal perl program or from another module - I have no problem.  When I call my custom from within the child_init_hook sub of the Net::Server module - the ParseDateString function causes the subroutine to end.  Note that no error message occurs and Net::Server continues to run - the sub routine (child_init_hook) just stops executing.

What makes this problem even more bizzare is that if I call my test function 'pdate' before I start the run method (note: i have this line commented out in the text below)- everything works fine.  I am obviously missing something obvious about object oriented perl.


************ Sample Code - Main Program

#!/export/opt/perl/5.8.0/bin/perl

package MyPackage;
 
  use mod
  use vars qw(@ISA);
  use Net::Server::PreFork  qw(:DEFAULT /^/);
  @ISA = qw(Net::Server::PreFork);

#$a=pdate("20020101"); # If this line is not commented out - pdate in child_init_hook works!!

  MyPackage->run();
  exit;

  sub child_init_hook
  {

    print "initializing process id $$\n";
    $a=pdate("20020101");

    print "f $a\n";

  }

1;

********** Sample Module

#!/export/opt/perl/5.8.0/bin/perl

package mod;

require Exporter;
use base qw(Exporter);
use vars qw(@EXPORT @EXPORT_OK @INC);
@EXPORT = qw(&pdate);
use Date::Manip;
sub pdate
{
  my ($y) = @_;
 
  print "bef\n";
  $a=ParseDateString($y);
  print "after $a\n";
}
1;


0
Comment
Question by:rmgould
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
9 Comments
 
LVL 5

Expert Comment

by:crazycomputers
ID: 10752483
Try declaring $a first:

  sub child_init_hook
  {

    print "initializing process id $$\n";
    my $a=pdate("20020101");

    print "f $a\n";

  }

Also, if you are writing a module *** put "use strict;" at the top! ***  There are very good reasons to force variable declaration, and it just might solve this problem.
0
 

Author Comment

by:rmgould
ID: 10752662
I do use strict in my actual code.  I did not include it when making this simple example.  Just to check - I did declare my variables first.  There was no effect.  To show the output I included it below.  You can see that the function 'pdate' does not go further than the ParseDateString call.  

*************

2004/04/04-13:41:45 MyPackage (type Net::Server::PreFork) starting! pid(16543)
Port Not Defined.  Defaulting to '20203'
Binding to TCP port 20203 on host *
Group Not Defined.  Defaulting to EGID '201 601 201'
User Not Defined.  Defaulting to EUID '60128'
initializing process id 16544
bef
initializing process id 16545
bef
initializing process id 16546
bef
initializing process id 16548
bef
initializing process id 16547
bef

*****************

If I take out the comment from
  #$a=pdate("20020101"); # If this line is not commented out - pdate in child_init_hook works!!

in the original post I get this output which is correct... i just don't get it...

**********

2004/04/04-13:46:45 MyPackage (type Net::Server::PreFork) starting! pid(16798)
Port Not Defined.  Defaulting to '20203'
Binding to TCP port 20203 on host *
Group Not Defined.  Defaulting to EGID '201 601 201'
User Not Defined.  Defaulting to EUID '60128'
initializing process id 16802
bef
initializing process id 16803
bef
after 2002010100:00:00
f 1
after 2002010100:00:00
f 1
initializing process id 16804
bef
initializing process id 16805
bef
after 2002010100:00:00
f 1
after 2002010100:00:00
f 1
initializing process id 16806
bef
after 2002010100:00:00
f 1




0
 
LVL 5

Expert Comment

by:crazycomputers
ID: 10753043
Try turning on warnings ("use warnings;" or append -w to shebang) and run it again.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:rmgould
ID: 10753070
My current version has 'use warnings' added in addition to properly declaring all variables.  The output above is from that code.  No warnings are currently given.
0
 
LVL 5

Assisted Solution

by:crazycomputers
crazycomputers earned 125 total points
ID: 10753654
Try changing

$a=pdate("20020101");

to

pdate("20020101");

and see what happens.  (This is the one outside of child_init_hook.)
0
 

Author Comment

by:rmgould
ID: 10753734
does not change anything.  Remember if the pdate call outside of the child_init_hook is called (ie that line is not commented out in the original post) - the whole thing works fine to begin with.  I think the problem has to lie in the namespace of the module.  If I had to guess - somehow the custom module had its namespace overridden by the namespace of the net server class.  

Perhaps you can try saving my 2 examples into 2 files test.pl and mod.pm and see if you replicate the output I am seeing.
0
 
LVL 20

Accepted Solution

by:
jmcg earned 125 total points
ID: 10754786
I don't have a complete answer for you, but maybe what I say can be helpful....

The symptoms you describe look like a sort of dynamic loading problem, but I cannot see just now where it arises. The Date::Manip module itself does not use dynamic loading, but one of the modules it uses may.

The documentation for the Net::Server::PreForkSimple module mentions this:
=======================
$self->child_init_hook()

This hook takes place immeditately after the child process forks from the parent and before the child begins accepting connections. It is intended for any addiotional chrooting or other security measures. It is suggested that all perl modules be used by this point, so that the most shared memory possible is used.
=======================

By calling pdate( ) once before run( ), you are following this advice. This ensures that the Date::Manip::Date_Init function is called in the context of the parent process, before any forks, and Date_Init is called only once -- in the children, the Date_Init call is avoided because it is flagged as already having run.

But in looking through the source of Date_Init, I still don't see any outstanding culprits for why it would work any differently when run in your child processes. They should all start with the Date::Manip module in the same state it was in before the fork. It does not appear to use any file locking while attempting to access its configuration file. Unless your OS is holding things up because of the near-simultaneous attempts to read the config file, I'm baffled as to why you see the symptoms that you do.

The good news is that you avoid the problem by following the module designer's advice.
0
 

Author Comment

by:rmgould
ID: 10771550
I found the answer on from a google newsgroup search.  The answer seems to be a problem (feature) with the 'Prefork' component of Net::Server.  If I use 'Fork' vs. 'PreFork' all is well.  The other post had no explanation - but as I don't really need to prefork given my anticipated volume - I am happy with only a forking server.  tkx to all.  splitting the points for the effort given...
0
 
LVL 20

Expert Comment

by:jmcg
ID: 10771686
You must have excellent Google skills -- I could not find anything helpful on the web.

Using the Fork instead of Prefork version means that you are much less likely to get into the startup situation of having all of several children simultaneously tring to run Date_Init. You'd still be well advised to call pdate in the parent before any forks, since having to run Date_Init anew on every transaction is a waste and may slow your response time just a wee bit.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question