【问题标题】:How do I discover on what server the app.psgi process is running?如何发现 app.psgi 进程在哪个服务器上运行?
【发布时间】:2014-01-19 11:33:13
【问题描述】:

有没有办法发现app.psgi 在哪个服务器上运行?

例如,我正在寻找一些关于如何解决 app.psgi 中的下一个代码片段的想法:

#app.psgi
use Modern::Perl;
use Plack::Builder;
my $app = sub { ... };

my $server = MyApp::GetServerType(); # <--- I need some idea for how to write this...

given($server) {
    when (/plackup/) { ... do something ... };
    when (/Starman/) { ... do something other ... };
    default { die "Unknown" };
}

$app;

检查PLACK_ENV 环境变量不是解决方案...

【问题讨论】:

    标签: perl plack psgi starman


    【解决方案1】:

    简短回答,检查来电者:

    #app.psgi
    # use Modern::Perl;
    use feature qw(switch say);
    use Carp qw(longmess);
    use Plack::Builder;
    
    my $app = sub {
        return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'Hello World' ] ];
    };
    
    # This hack gets what we need out of the call stack
    my $stack = longmess("Stack:");
    
    # say STDERR $stack;
    
    given($stack) {
        when (/plackup/) { say STDERR "Server: plackup" };
        when (/Starman/) { say STDERR "Server: starman" };
        default { die "Server: Unknown" };
    }
    return $app;
    

    但是,在 app.psgi 中执行此操作会降低您的代码的可移植性。如果您死在未知服务器上,人们将无法在未知位置运行您的代码。

    另外,请注意,此代码可能会运行多次,具体取决于服务器的实现方式,因此任何副作用都可能会多次发生。

    例如,这是plackup 的输出:

    plackup --app /usr/lusers/bburnett/dev/trunk/getserver.psgi
    Server: plackup
    HTTP::Server::PSGI: Accepting connections at http://0:5000/
    

    到目前为止一切顺利。但这里是starman 的输出:

    starman --app /usr/lusers/bburnett/dev/trunk/getserver.psgi
    2014/02/21-16:09:46 Starman::Server (type Net::Server::PreFork) starting! pid(27365)
    Resolved [*]:5000 to [0.0.0.0]:5000, IPv4
    Binding to TCP port 5000 on host 0.0.0.0 with IPv4
    Setting gid to "15 15 0 0 15 20920 20921 20927"
    Server: starman
    Server: starman
    Server: starman
    Server: starman
    Server: starman
    

    这里它为主人运行一次,每个孩子运行一次(默认为四个孩子)。

    如果您真的希望这些不同的服务器发生不同的事情,一种更强大的方法可能是自己对它们进行子类化,并将代码放入每个子类中,根据需要将 -s My::Starman::Wrapper 传递给 plackup 和 starman。

    如果你真的想要一个 switch 语句并将代码放在一个地方,你可以考虑编写一些调用 Plack::Loader 或 Plack::Runner 的代码。查看plackup 的源代码,您会看到它是如何包装Plack::Runner 的。查看 Plack::Loader 的源代码,您将了解它如何让后端运行,然后加载相应的服务器类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-08
      • 2010-12-31
      • 1970-01-01
      • 2017-04-03
      • 2010-12-19
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      相关资源
      最近更新 更多