You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Fayland Lam <fa...@gmail.com> on 2009/07/17 05:37:16 UTC

share use vars?

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?

Posted by Michael Peters <mp...@plusthree.com>.
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


Re: share use vars?

Posted by Michael Peters <mp...@plusthree.com>.
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