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