Mailing List Archive

RE: use module in Embperl (was: problem solved, but still weird!)
>
> Standard workaround here is now "apachectl restart" after the change of
> modules :-/ weird but it really works!
>

Nothing weird here. Everything is well defined. Just let us try to
understand how Perl, mod_perl and Embperl works together:

"perldoc -f use" tells us:

Imports some semantics into the current package from the named module,
generally by aliasing certain subroutine or variable names into your
package. It is exactly equivalent to

BEGIN { require Module; import Module LIST; }

except that Module must be a bareword.

So what's important here for us is, that use executes a require and this is
always done before any other code is executed.

"perldoc -f require" says (among other things):

..., demands that a library file be included if it hasn't already
been included.

and

Note that the file will not be included twice under the same specified
name.

So now we know (or should know) that mod_perl starts the Perl interpreter
once when Apache is started and the Perl interpreter is only terminated when
Apache is terminated. Out of these two things follows, that a module that is
loaded via use or require is only loaded once and will never be reloaded,
regardless if the source changes or not.

So far this is just standard Perl. Things get's a little bit more difficult
when running under mod_perl (only Unix), because Apache forks a set of child
processes as neccessary and from the moment they are forked, they run on
their own and don't know of each other. So if a module is loaded at server
startup time (before the fork), it is loaded in all childs (this can be used
to save memory, because the code will actually only reside once in memory),
but when the modul is loaded inside the child and the source changes, it
could be happen, that one child has loaded an ealier version and another
child has loaded a later version of that module, depending on the time the
module is actualy loaded by the child.

That explains, why sometimes it works and sometimes it doesn't, simply
because different childs has loaded different versions of the same module
and when you reload your page you hit different childs of Apache!

Now there is one point that is special to Embperl to add. Since Embperl
compiles every page in a different namespace, a module that doesn't contains
a "package foo" statement is compiled in the namespace of the page where it
is first loaded. Because Perl will not load the module a second time, every
other page will not see subs and vars that are defined in the loaded module.
This could be simply avoided by giving every module that should be loaded
via use/require an explicit namespace via the package statement.

So what can we do?
- If a module change, simply restart Apache. That's works always.
- use Apache::StatInc. This will do a stat on every loaded module and
compare the modification time. If the source has changed the module is
reloaded. This works most times (but not all modules can be cleanly
reloaded) and as the number of loaded modules increase, your sever will slow
down, because of the stat it has to do for every module.
- Use "do" instead of "require". do will execute your file everytime it is
used. This also adds overhead, but this may be accpetable for small files or
in a debugging environement. (NOTE: Be sure to check $@ after a do, because
do works like eval)

I hope now it's seem a little bit less weird..

Gerald


-------------------------------------------------------------
Gerald Richter ecos electronic communication services gmbh
Internetconnect * Webserver/-design/-datenbanken * Consulting

Post: Tulpenstrasse 5 D-55276 Dienheim b. Mainz
E-Mail: richter@ecos.de Voice: +49 6133 925151
WWW: http://www.ecos.de Fax: +49 6133 925152
-------------------------------------------------------------
Re: use module in Embperl (was: problem solved, but still weird!) [ In reply to ]
Thanks Gerald for the clearing up things. Additionally:

I've found an excellent tutorial on Modules under mod_perl
(and therefore with embperl as well) which explains many
of the issues which have bugged me and many others:

http://www.perlmonth.com/columns/perl_apache/perl_apache.html?issue=11

--
Frerk Meyer mailto:fm@channel-one.de
Channel.One http://www.channel-one.de