Multithreading Lite—使用mod_perl中线程化的版本1.1和1.2的客户端

Multithreading Lite—使用mod_perl中线程化的版本1.1和1.2的客户端,multithreading,perl,soap,mod-perl,soaplite,Multithreading,Perl,Soap,Mod Perl,Soaplite,我有几个SOAP::Lite客户端在ApacheHhtpd中的mod_perl下运行。 其中一些使用1.1 soap服务器,一些使用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

我有几个SOAP::Lite客户端在ApacheHhtpd中的mod_perl下运行。 其中一些使用1.1 soap服务器,一些使用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:\n@{[
        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
调用在
$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
本地化为serverthread或类似的东西,我想一切都会好起来。但是任何解决方案都会受到欢迎。

使用预工作模型而不是线程模型来运行Apache(
mpm\u预工作模块
而不是
mpm\u事件模块
mpm\u工作者模块
),这样每个Apache子级都将有自己的Perl解释器,从而有自己的常量集


另外,请查看有关
PerlOptions
指令的modperl文档,特别是
clone
和/或
parent
值。但是停止使用线程对我来说似乎更简单,线程和Perl从来都不是朋友。

不幸的是,我无法测试它,但它对我来说很好。