share use vars?

share use vars?

am 17.07.2009 05:37:16 von Fayland

see we are using Catalyst and it run under mod_perl2. we're planning to
use Geo::IP in our Controller.
I'm wondering which code is better as following.

1)
use vars qw/$geo_ip/;
sub ip_to_location {
my ( $ip ) = @_;

$geo_ip ||= Geo::IP->open("/usr/local/share/GeoIP/GeoLiteCity.dat",
GEOIP_STANDARD);
my $record = $geo_ip->record_by_addr($ip);
return unless $record;
return ( $record->country_code, $record->city,
$record->country_name, $record->region_name );
}

2)
use vars qw/$geo_ip/;
$geo_ip = Geo::IP->open("/usr/local/share/GeoIP/GeoLiteCity.dat",
GEOIP_STANDARD);
sub ip_to_location {
my ( $ip ) = @_;

my $record = $geo_ip->record_by_addr($ip);
return unless $record;
return ( $record->country_code, $record->city,
$record->country_name, $record->region_name );
}

I'm wondering in which way the $geo_ip is sharable through the threads.
we are using "server/mpm/prefork"

Thanks.

--
Fayland Lam // http://www.fayland.org/
Foorum based on Catalyst // http://www.foorumbbs.com/

Re: share use vars?

am 17.07.2009 16:40:28 von mpeters

Fayland Lam wrote:

> I'm wondering in which way the $geo_ip is sharable through the threads.
> we are using "server/mpm/prefork"

Neither. Prefork doesn't use threads it uses separate processes. And processes
cannot share Perl variables like that. Both of the examples you showed would
only have a single Geo::IP object per-process (although you probably don't want
to use a global like that. A local (my) or package visible (our) variable is
probably better.

Why do you want to share it between your processes?

--
Michael Peters
Plus Three, LP

Re: share use vars?

am 17.07.2009 20:53:48 von mpeters

Brad Van Sickle wrote:
> I'm also wondering why this needs to be shared between processes... but
> if it is required, you can share variables between mod_perl processes by
> caching them on server startup, assuming that they are read only.

Calling this variable "shared" is a little misleading. If you're using a system
with copy-on-write memory, then yes the physical memory is shared by the
processes, but that's invisible to the users and the variable is not logically
shared. Also, there are lots of things that could happen to make that page in
memory "dirty" which would cause the physical RAM to become unshared. You don't
have to actually change the variable for this to happen.

But the sentiment is right and this is a great way to fake the sharing of a lot
of read only data.

I didn't recommend this technique because there is a big caveat: file handles. I
don't know the implementation details of Geo::IP but it does pull it's data from
data files. If it slurps it all at once into memory and then just uses that data
afterwards then you're ok. Or if it opens a new filehandle every time it wants
data and then closes it you're also ok. But if it opens a filehandle and then
keeps it around you can't share it. All sorts of bad and weird things can and
will happen in very unpredictable ways when inherited filehandles are used by
forked children.

--
Michael Peters
Plus Three, LP