我有这个:
use Plack::Builder;
my $config_app = sub {...};
my $app = sub {...}
builder {
mount "/admin" => $config_app;
mount "/" => $app;
};
Run Code Online (Sandbox Code Playgroud)
将$config_app配置值保存到文件中app.cfg并将其$app加载为config-file.不需要在每个请求中读取配置文件.需要在应用程序开始时阅读它,并在更改时重新读取它.
实现这一目标的最佳方式是什么?
我唯一的想法是:应用程序将记住最后一个config_read_time,并在每个请求中将检查修改时间app.cfg.如果文件被修改,将重新读取它.
这里有更好的解决方案吗?(表示$ config_app和$ app之间的一些消息传递,例如当$ config_app保存新配置时will send some message to $app: re-read the config.
虽然在$app内部调用(有点像内部重定向)并非不可能$config_app,但我个人会建议反对它.
如果你创建一个单独的普通的Perl类(MyApp :: ConfigFile或其他)并且从单个对象调用$app和$config_app反对该方法,应该会容易得多.请注意,该技术仅适用于单进程Web服务器环境.如果检查修改时间并重新读取,则可以在分叉环境(如Starman Web服务器)中使用.
有很多方法可以监视配置文件.
编写如下的配置检查例程:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您需要注意的主要事情是,您不会在文件更改的第二天重复加载.
现在在你可能想要加载新一轮配置的地方调用`load_config().因为它总是成功,所以你不必测试或做任何更聪明的事情,而不是把它洒在方便的地方.就像你的app处理程序的顶部一样.
这对于执行诸如打开正在运行的进程的日志记录或强制重新加载某些模块等操作非常有用.没有很多用途,缩放不会咬你.
你知道,如果你有一堆机器服务于它,它将无法扩展.您必须对文件更改文件进行rsync,或者更糟糕的是将它们放在NFS挂载上.
这是一个激进的概念:为什么不使用数据库?
我听说很酷的孩子们现在正在尝试基于数据库的网络应用程序,而且他们实际上工作得很好.
严肃地说,编程和构建系统的有趣之处在于在设计权衡之间进行选择.可能存在一些边缘情况,其中传递已更改的文件是非常成功的,并且我的snarky数据库注释显示为完全愚蠢.不确定该用例是什么,但它可能存在. 你知道你的用例. 尝试一下.不要害怕有点傻.有时,看似真正愚蠢的解决方案竟然是出人意料的优雅.然而,如果这个想法变得愚蠢,那么请从经验中学习并继续前进.