Initialize object permanently
am 19.05.2008 19:50:09 von KeenlearnerHello, I just know that I can't have a startup script, but how can I
create an object in the startup script and then used that variable
object in child modperl script ? Thanks.
Hello, I just know that I can't have a startup script, but how can I
create an object in the startup script and then used that variable
object in child modperl script ? Thanks.
On 5/20/08, william
> Hello, I just know that I can't have a startup script, but how can I
> create an object in the startup script and then used that variable
> object in child modperl script ? Thanks.
>
Sorry I mean I CAN have a startup script.
william wrote:
> On 5/20/08, william
>> Hello, I just know that I can't have a startup script, but how can I
>> create an object in the startup script and then used that variable
>> object in child modperl script ? Thanks.
>>
>
> Sorry I mean I CAN have a startup script.
>
Hi.
Take this as a not really qualified answer, but until one of the gurus
here jumps in, it may be a start.
The simple question you are asking above is in fact very complicated.
If the idea of your question is to create some variable once at the
server start, and then be able to share that variable through multiple
invocations of a script or module, then you will probably not be able to
do that, or at least not in a simple way.
The first thing that happens, is that there are multiple Apache children
processes started and running at the same time, and that you never know
which one is going to execute your script. And each one of these
children processes, will have its own independent copy (or instance) of
your "common" variable (or object). So the variable will not really be
common.
There are some ways around that, involving shared memory. But it is
probably anyway more complicated that what your simple question above
seems to indicate of what you expect.
Let me make a prediction : I can see a quite long and interesting thread
starting here..
André
william wrote:
> Hello, I just know that I can't have a startup script, but how can I
> create an object in the startup script and then used that variable
> object in child modperl script ? Thanks.
It depends on your needs. If you need a read-only object that won't change
during the whole time the server is running (like a configuration object) then
it's pretty straight forward. You just need to use a namespaced object that you
access in your application.
# in startup.pl
My::Object->create();
# in your application
My::Object->get();
# in My/Object.pl
my $obj;
sub create {
$obj = ...; # do something to initialize
}
sub get {
return $obj;
}
If your needs are more complicated then it does become more complicated :)
--
Michael Peters
Plus Three, LP
On 5/20/08, Andr=E9 Warnier
>
>
> william wrote:
>
> > On 5/20/08, william
> >
> > > Hello, I just know that I can't have a startup script, but how can I
> > > create an object in the startup script and then used that variable
> > > object in child modperl script ? Thanks.
> > >
> > >
> >
> > Sorry I mean I CAN have a startup script.
> >
> >
>
> Hi.
>
> Take this as a not really qualified answer, but until one of the gurus h=
ere
> jumps in, it may be a start.
>
> The simple question you are asking above is in fact very complicated.
> If the idea of your question is to create some variable once at the serv=
er
> start, and then be able to share that variable through multiple invocatio=
ns
> of a script or module, then you will probably not be able to do that, or =
at
> least not in a simple way.
> The first thing that happens, is that there are multiple Apache children
> processes started and running at the same time, and that you never know
> which one is going to execute your script. And each one of these childre=
n
> processes, will have its own independent copy (or instance) of your "comm=
on"
> variable (or object). So the variable will not really be common.
>
> There are some ways around that, involving shared memory. But it is
> probably anyway more complicated that what your simple question above see=
ms
> to indicate of what you expect.
>
> Let me make a prediction : I can see a quite long and interesting thread
> starting here..
>
> Andr=E9
>
>
Thanks for the prompt reply, you said that every child process have a
copy of the common object variable. I think that shouldn't be a
problem in my case, because it's an object that only gives data, in
contrast we would not modify anything about the object. Specifically,
I want to achieve this because the problem of this module
WordNet::QueryData
http://search.cpan.org/~jrennie/WordNet-QueryData-1.47/Query Data.pm .
This initialization step is slow (appx. 10-15 seconds), but queries
are very fast thereafter---thousands of queries can be completed every
second. In my hardware it only takes 2 seconds, but that still quite a
lot of time to wait if every child process need to take 2 seconds.
Unless I can have a permanent in startup script and used by the child
process. Thanks
On 5/20/08, Andr=E9 Warnier
> If you never modify this object after creation, then the answer given by
> Michael Peters is the one you are looking for.
>
> But make sure that the object is indeed never modified (or that what is
> modified does not matter). I have not looked at the QueryData.pm module =
you
> mention, but it might be that it modifies it's internal state at each que=
ry.
> This may or may not be important in your case.
>
> Andr=E9
>
>
>
> william wrote:
>
> > On 5/20/08, Andr=E9 Warnier
> >
> > >
> > > william wrote:
> > >
> > >
> > > > On 5/20/08, william
> > > >
> > > >
> > > > > Hello, I just know that I can't have a startup script, but how ca=
n I
> > > > > create an object in the startup script and then used that variab=
le
> > > > > object in child modperl script ? Thanks.
> > > > >
> > > > >
> > > > >
> > > > Sorry I mean I CAN have a startup script.
> > > >
> > > >
> > > >
> > > Hi.
> > >
> > > Take this as a not really qualified answer, but until one of the gur=
us
> here
> > > jumps in, it may be a start.
> > >
> > > The simple question you are asking above is in fact very complicated=
..
> > > If the idea of your question is to create some variable once at the
> server
> > > start, and then be able to share that variable through multiple
> invocations
> > > of a script or module, then you will probably not be able to do that,=
or
> at
> > > least not in a simple way.
> > > The first thing that happens, is that there are multiple Apache
> children
> > > processes started and running at the same time, and that you never kn=
ow
> > > which one is going to execute your script. And each one of these
> children
> > > processes, will have its own independent copy (or instance) of your
> "common"
> > > variable (or object). So the variable will not really be common.
> > >
> > > There are some ways around that, involving shared memory. But it is
> > > probably anyway more complicated that what your simple question above
> seems
> > > to indicate of what you expect.
> > >
> > > Let me make a prediction : I can see a quite long and interesting
> thread
> > > starting here..
> > >
> > > Andr=E9
> > >
> > >
> > >
> >
> > Thanks for the prompt reply, you said that every child process have a
> > copy of the common object variable. I think that shouldn't be a
> > problem in my case, because it's an object that only gives data, in
> > contrast we would not modify anything about the object. Specifically,
> > I want to achieve this because the problem of this module
> > WordNet::QueryData
> >
> http://search.cpan.org/~jrennie/WordNet-QueryData-1.47/Query Data.pm
> .
> > This initialization step is slow (appx. 10-15 seconds), but queries
> > are very fast thereafter---thousands of queries can be completed every
> > second. In my hardware it only takes 2 seconds, but that still quite a
> > lot of time to wait if every child process need to take 2 seconds.
> > Unless I can have a permanent in startup script and used by the child
> > process. Thanks
> >
> >
>
Then I would need to modify the QueryData module then, by modifying
the standard module would it make my future maintenance more
complicated ? Do you have any tips for me ?
Btw, I love to know the potential solution for object that would be
modified by the child process ? The child that obtain the object must
have the property of the object that last modified. Because I guess I
am going to face the problem quite soon.
Thanks.
william wrote:
> Then I would need to modify the QueryData module then,
No don't do that.
> by modifying
> the standard module would it make my future maintenance more
> complicated ?
Absolutely.
> Do you have any tips for me ?
Wrap the object in your own package. Let's call it My::QueryData.
package My::QueryData;
use QueryData;
my $query_data;
sub create {
$query_data = QueryData->new(...);
}
sub get {
return $query_data;
}
> Btw, I love to know the potential solution for object that would be
> modified by the child process ? The child that obtain the object must
> have the property of the object that last modified. Because I guess I
> am going to face the problem quite soon.
> Thanks.
It's the same basic idea for sharing something between any processes (it's not
specific to mod_perl). And that's to put the serialized object into some sort of
3rd party data store. Whether this is a database (which scales to multiple
machines) or a DBM file (which is quick and easy but doesn't handle multiple
machines) depends on your needs.
--
Michael Peters
Plus Three, LP
2008/5/19 Michael Peters
> william wrote:
>
>> Then I would need to modify the QueryData module then,
>
> No don't do that.
>
>> by modifying
>> the standard module would it make my future maintenance more
>> complicated ?
>
> Absolutely.
>
>> Do you have any tips for me ?
>
> Wrap the object in your own package. Let's call it My::QueryData.
>
> package My::QueryData;
> use QueryData;
>
> my $query_data;
> sub create {
> $query_data = QueryData->new(...);
> }
>
> sub get {
> return $query_data;
> }
>
For extra syntactic sugar, you could always just do it singlet style.
package My::QueryData;
use base QueryData;
our $singlet;
sub new {
return $singlet if $singlet;
return $singlet = QueryData->new(@_);
}
Of course, if you want to allow different ones for different
invocations (i.e. Pkg->new(foo => 1) and Pkg->new(foo => 2), you can
make $singlet a hashref keyed by those options, instead, and check for
the appropriate one
On 5/20/08, Dodger
> 2008/5/19 Michael Peters
>
> > william wrote:
> >
> >> Then I would need to modify the QueryData module then,
> >
> > No don't do that.
> >
> >> by modifying
> >> the standard module would it make my future maintenance more
> >> complicated ?
> >
> > Absolutely.
> >
> >> Do you have any tips for me ?
> >
> > Wrap the object in your own package. Let's call it My::QueryData.
> >
> > package My::QueryData;
> > use QueryData;
> >
> > my $query_data;
> > sub create {
> > $query_data = QueryData->new(...);
> > }
> >
> > sub get {
> > return $query_data;
> > }
> >
>
>
> For extra syntactic sugar, you could always just do it singlet style.
>
> package My::QueryData;
> use base QueryData;
> our $singlet;
>
> sub new {
> return $singlet if $singlet;
> return $singlet = QueryData->new(@_);
> }
>
>
> Of course, if you want to allow different ones for different
> invocations (i.e. Pkg->new(foo => 1) and Pkg->new(foo => 2), you can
> make $singlet a hashref keyed by those options, instead, and check for
> the appropriate one
>
Thanks, those solutions are nice.
On 5/20/08, william
> On 5/20/08, Dodger
> > 2008/5/19 Michael Peters
> >
> > > william wrote:
> > >
> > >> Then I would need to modify the QueryData module then,
> > >
> > > No don't do that.
> > >
> > >> by modifying
> > >> the standard module would it make my future maintenance more
> > >> complicated ?
> > >
> > > Absolutely.
> > >
> > >> Do you have any tips for me ?
> > >
> > > Wrap the object in your own package. Let's call it My::QueryData.
> > >
> > > package My::QueryData;
> > > use QueryData;
> > >
> > > my $query_data;
> > > sub create {
> > > $query_data = QueryData->new(...);
> > > }
> > >
> > > sub get {
> > > return $query_data;
> > > }
> > >
> >
> >
> > For extra syntactic sugar, you could always just do it singlet style.
> >
> > package My::QueryData;
> > use base QueryData;
> > our $singlet;
> >
> > sub new {
> > return $singlet if $singlet;
> > return $singlet = QueryData->new(@_);
> > }
> >
> >
> > Of course, if you want to allow different ones for different
> > invocations (i.e. Pkg->new(foo => 1) and Pkg->new(foo => 2), you can
> > make $singlet a hashref keyed by those options, instead, and check for
> > the appropriate one
> >
>
>
> Thanks, those solutions are nice.
>
Btw, I just try out that solution, it is awsome, it only takes time
while server startup. But subsequent request. it is so fast. I am new
to mod_perl, now I am in love with it. lol
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
André Warnier wrote:
| The first thing that happens, is that there are multiple Apache children
| processes started and running at the same time, and that you never know
| which one is going to execute your script. And each one of these
| children processes, will have its own independent copy (or instance) of
| your "common" variable (or object). So the variable will not really be
| common.
FWIW, things created before the PerlChildInit (before the httpd children are
spawned) in the parent httpd process are shared via COW (copy-on-write).
Now if you are talking about worker, event or other threaded mpm's instead of
prefork, this is different.
- --
- ------------------------------------------------------------ ------------
Philip M. Gollucci (philip@ridecharge.com)
o:703.549.2050x206
Senior System Admin - Riderway, Inc.
http://riderway.com / http://ridecharge.com
1024D/DB9B8C1C B90B FBC3 A3A1 C71A 8E70 3F8C 75B8 8FFB DB9B 8C1C
Work like you don't need the money,
love like you'll never get hurt,
and dance like nobody's watching.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.8 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFIM2/UdbiP+9ubjBwRAuvXAJ4t8kxvkl1FcmX/ckdf6GHjA3n+BgCf YCeG
J3lfKvZptduBfnZYQg0tKog=
=vr3A
-----END PGP SIGNATURE-----