3

我有这个:

use Plack::Builder;
my $config_app = sub {...};
my $app = sub {...}

builder {
    mount "/admin" => $config_app;
    mount "/"   => $app;
};

$config_app配置值保存到文件app.cfg中并将其$app加载为配置文件。不需要在每个请求中读取配置文件。需要在应用程序开始时阅读它,并在更改时重新阅读。

实现这一目标的最佳方法是什么?

我唯一的想法是:应用程序会记住最后的 config_read_time,并且在每个请求中都会检查app.cfg. 如果文件被修改,将重新读取它。

这里有更好的解决方案吗?(意味着 $config_app 和 $app 之间的一些消息传递,例如当 $config_app 保存新配置时will send some message to $app: re-read the config

4

2 回答 2

6

虽然在内部调用$app(有点像内部重定向)并非不可能$config_app,但我个人建议不要这样做。

$app如果您创建一个单独的普通 Perl 类(MyApp::ConfigFile 或其他)并从单例对象和$config_app针对单例对象调用该方法,这应该会容易得多。请注意,无论如何,该技术仅适用于单进程 Web 服务器环境。如果您检查修改时间并重新阅读,则可以在 Starman Web 服务器等分叉环境中工作。

于 2011-05-20T01:09:29.237 回答
5

有很多方法可以监控配置文件。

像这样编写一个配置检查例程:

use constant MIN_CHECK_DELAY => 5;  #SECONDS
use constant CONFIG_FILE => '/etc/wtf.conf';

{
    my $last_changed = 0;
    my $last_check   = 0;

    sub load_config {

        return if $last_check + MIN_CHECK_DELAY <= time;

        return if (stat(CONFIG_FILE))[9] <= $last_check;

        # Do stuff here.

        return;
    }

}

您需要注意的主要事情是,您不会在文件更改的那一秒内一遍又一遍地重新加载。

现在在您可能需要加载新一轮配置的任何地方调用`load_config()。由于它总是成功,因此您无需进行测试或做任何比将其洒在方便的地方更聪明的事情。就像在您的应用程序处理程序的顶部一样。

这对于执行诸如打开正在运行的进程的日志记录或强制重新加载某些模块之类的操作非常有用。缩放不会咬你的用途并不多。

你知道,如果你有一堆机器为这个服务,它就不会扩展。您必须 rsync 更改文件的文件,或者更糟的是将它们放在 NFS 挂载上。

这是一个激进的概念:为什么不使用数据库?

我听说这些天很酷的孩子们正在试验基于数据库的 Web 应用程序,而且它们实际上工作得很好。

严肃地说,编程和构建系统的有趣之处在于在设计权衡之间进行选择。在某些极端情况下,传递更改的文件会取得巨大的成功,而我尖刻的数据库评论被显示为完全愚蠢。不确定该用例是什么,但它可能存在。 你知道你的用例。 试一试。不要害怕变得有点愚蠢。有时,看似非常愚蠢的解决方案却出奇地优雅。但是,如果这个想法被证明是愚蠢的,那就从经验中学习并继续前进。

于 2011-05-20T01:16:02.650 回答