2013-08-02 62 views
2

我想在不同的perl模塊之間共享一個變量。所以,我創建了一個名爲MyCache.pm Perl模塊節省了變量(在我的情況的哈希變量):在mod_perl處理程序的不同模塊中使用方法

package PerlModules::MyCache; 
my %cache =(); 
sub set { 
    my ($key, $value) = @_; 
    $cache{$key} = $value; 
} 
sub get { 
    my ($key) = @_; 
    return $cache{$key}; 
} 

現在我有兩個處理程序。一個處理程序將調用set方法,另一個處理程序將調用get方法來訪問信息。

package PerlModules::MyCacheSetter; 
use Apache2::RequestRec(); 
use Apache2::RequestIO(); 
use Apache2::Const -compile => qw(OK); 
use PerlModules::MyCache; 
sub handler { 
    my $r = shift; 
    PerlModules::MyCache::set('test1', "true"); 
    PerlModules::MyCache::set('test2', "false"); 
    PerlModules::MyCache::set('test3', "true"); 
    return Apache2::Const::OK; 
} 

這裏是吸氣處理程序:

package PerlModules::MyCacheGetter; 
use Apache2::RequestRec(); 
use Apache2::RequestIO(); 
use Apache2::Const -compile => qw(OK); 
use PerlModules::MyCache; 
sub handler { 
    my $r = shift; 
    $r->print(PerlModules::MyCache::get('test1')); 
    $r->print(PerlModules::MyCache::get('test2')); 
    $r->print(PerlModules::MyCache::get('test3')); 
    return Apache2::Const::OK; 
} 

現在,我已經配置了Apache(通過http.conf中)來訪問這些Perl模塊。我運行setter處理程序,然後運行getter,但沒有輸出。

在error.log中有現在有些條目:

Use of uninitialized value in subroutine entry at ../MyCacheGetter.pm line 14. 
Use of uninitialized value in subroutine entry at ../MyCacheGetter.pm line 15. 
Use of uninitialized value in subroutine entry at ../MyCacheGetter.pm line 16. 

此行是get方法的三個調用。那麼我做錯了什麼?我如何解決這個問題並在不同的處理程序之間共享我的緩存變量?

+0

你在同一個請求中運行setter處理程序和getter處理程序嗎?如果你顯示你如何稱呼處理程序,也許它會有所幫助。 – mob

+0

嗨,我使用下面的httpd.conf配置來訪問處理程序。在這之後,我通過web瀏覽器調用處理程序(localhost/mcsetter):PerlModule PerlModules :: MyCacheGetter SetHandler modperl PerlResponseHandler PerlModules :: MyCacheGetter和setter相同。 – atticus3000

+0

你正在做兩個單獨的HTTP請求(1設置,然後另一個獲取)?如果是這樣,你可能會得到兩個不同的Apache子進程。你做了什麼將你的緩存狀態傳遞給其他子進程? –

回答

0

您的緩存將只存在於給定的Apache子進程的生命週期中。如果你想讓其他進程看到它,你需要將它存儲在一個他們都可以得到的地方。

這是未經測試的,但你可以得到一般想法: (現在測試)。 編輯:好的,好像你可以通過Storable得到一些問題,這取決於你正在運行的perl版本和Storable版本。在我的例子中,我用Data::Serialize代替了Storable。我還爲get/set方法添加了一行,以便可以使用->::語法。

package PerlModules::MyCache; 

use IPC::ShareLite qw/:lock/; 
use Data::Serializer; 
use 5.10.0; 

my $key = 1234; # Your shared memory key (you set this!) 

my $ipc = IPC::ShareLite->new(
    -key  => $key, 
    -create => 'yes', 
    -destroy => 'no' 
); 

my $ser = Data::Serializer->new(
    serializer => 'Data::Dumper' 
); 

sub set { 
    shift @_ if $_[0] eq __PACKAGE__; 
    my ($key, $value) = @_; 
    $ipc->lock(LOCK_EX); 
    my $frozen; eval { $frozen = $ipc->fetch; }; 
    my $cache = defined($frozen) ? $ser->thaw($frozen) : {}; 
    $cache->{$key} = $value; 
    $ipc->store($ser->freeze($cache)); 
    $ipc->unlock; 
    return $value; 
} 

sub get { 
    shift @_ if $_[0] eq __PACKAGE__; 
    my ($key) = @_; 
    my $frozen; eval { $frozen = $ipc->fetch; }; 
    my $cache = defined($frozen) ? $ser->thaw($frozen) : {}; 
    return $cache->{$key}; 
} 

sub clear { 
    shift @_ if $_[0] eq __PACKAGE__; 
    $ipc->store($ser->freeze({})); 
    return {}; 
} 

1; 

您可能希望測試以確保緩存存儲的正確結構之前運行PerlModules::MyCache->clear一次。

相關問題