2016-12-06 110 views
3

我有幾個在Apache hhtpd中的mod_perl下運行的SOAP :: Lite客戶端。 其中一些使用1.1肥皂服務器,其中一些使用1.2服務器。所以,我有這樣的代碼:SOAP :: Lite - 在mod_perl中使用版本1.1和1.2的客戶端

# In client 1: 
my $soap1 = SOAP::Lite->soapversion("1.1"); 
$result1 = $soap1->method1(); 

# In client 2: 
my $soap2 = SOAP::Lite->soapversion("1.2"); 
$result2 = $soap2->method2(); 

這個工作在獨立客戶端,但是當我運行mod_perl下的代碼,我似乎得到由蜇soapversion 方法有副作用:

# From SOAP::Lite.pm 
sub soapversion { 
    my $self = shift; 
    my $version = shift or return $SOAP::Constants::SOAP_VERSION; 

    ($version) = grep { 
     $SOAP::Constants::SOAP_VERSIONS{$_}->{NS_ENV} eq $version 
     } keys %SOAP::Constants::SOAP_VERSIONS 
      unless exists $SOAP::Constants::SOAP_VERSIONS{$version}; 

    die qq!$SOAP::Constants::WRONG_VERSION Supported versions:\[email protected]{[ 
     join "\n", map {" $_ ($SOAP::Constants::SOAP_VERSIONS{$_}->{NS_ENV})"} keys %SOAP::Constants::SOAP_VERSIONS 
     ]}\n! 
     unless defined($version) && defined(my $def = $SOAP::Constants::SOAP_VERSIONS{$version}); 

    foreach (keys %$def) { 
     eval "\$SOAP::Constants::$_ = '$SOAP::Constants::SOAP_VERSIONS{$version}->{$_}'"; 
    } 

    $SOAP::Constants::SOAP_VERSION = $version; 

    return $self; 
} 

這是什麼,我相信會發生:

基本上,soapversion呼叫rededefines在$SOAP::Constants必需的常量。因爲這是mod_perl,所以$SOAP::Constants是全局的,並在每個服務器線程之間共享(我相信,如果我錯了,請糾正我)。這導致了競爭條件:大多數情況下,代碼行按照上述順序或多或少地執行。但是,一旦在一段時間(實際上是調用的約2%)的執行順序是:

Thread1: my $soap1 = SOAP::Lite->soapversion("1.1"); 
Thread2: my $soap2 = SOAP::Lite->soapversion("1.2"); 
Thread1: $result1 = $soap1->method1(); 
Thread2: $result2 = $soap2->method2(); 

因此,在$soap1->method1()被調用$SOAP::Constants集作爲適合1.2版本 - 造成數命名空間是錯誤的,特別是:

xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" 

哪項是錯誤1.1 - 誰喜歡:

xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"             

如果我能以某種方式使$SOAP::Constants定位爲erverthread或類似的東西,我想事情會好的。但任何解決方案將不勝感激。

回答

1

運行Apache與prefork的模型,而不是線程模型(mpm_prefork_module而不是mpm_event_modulempm_worker_module),使每個Apache子都會有自己的Perl解釋器,因此它自己的一套常量。

否則,請查看關於PerlOptions指令的modperl文檔,特別是clone和/或parent值。但是停止使用線程對我來說似乎更簡單,線程和Perl從來都不是朋友。

+0

不幸的是我無法測試它,但它對我來說看起來不錯。 – NoMann