我编写了一个脚本,为rails应用程序执行维护任务。该脚本使用一个使用应用程序中定义的模型的类。举个例子,让我们说应用程序定义模型User,我的类(在脚本中使用)向它发送消息,比如User.find id。
我正在寻找优化此脚本的方法,因为现在它必须加载应用程序环境:require '../config/environment'
。这需要大约15秒。
如果脚本没有使用应用程序代码库来完成它的工作,我可以用原始SQL替换模型抽象。但不幸的是,我不能这样做,因为我必须重复代码库中已经存在的脚本中的代码。这不仅会违反DRY原则并需要大量工作,如果我使用的模型方法发生变化,脚本将无法维护。
我想听听如何解决这个问题的想法。该脚本不是从应用程序本身运行,而是从shell运行(例如,使用Capistrano)。
我希望我已经足够清楚地描述了这个问题。谢谢。
答案 0 :(得分:1)
你能写一个在read
管道上的小守护进程(或者名为fifo,或者是unix域套接字,或者更复杂的是一个tcp端口)接受将要运行的“命令”你的数据库?
#!/usr/bin/ruby
require '../config/environment'
while (true) do
File.open("/tmp/fifo", "r") do |f|
f.each_line do |line|
case line
when "cleanup" then puts "clean!"
when "publish" then puts "published!"
else puts "invalid command, ignoring"
end
end
end
end
你可以用vixie cron的@reboot
说明符开始这个,或者你可以通过capistrano命令运行它,或者用init或init脚本运行它。然后你编写你的capistrano规则(你现在拥有),只需将命令发送到fifo:
首先,
mkfifo /tmp/fifo
在一个终端:
$ ./env.rb
在另一个终端:
$ echo -n "cleanup" > /tmp/fifo
$ echo -n "publish" > /tmp/fifo
$ echo -n "go away" > /tmp/fifo
第一个终端的输出如下所示:
clean!
published!
invalid command, ignoring
您可以将匹配设置为友好(可能允许普通echo
,而不是像我的示例那样需要echo -n
)或者您想要的不友好。运行的命令当然可以调用模型文件来完成它们的工作。
请确保为你的fifo选择一个好位置 - / tmp /可能是一个不好的地方,因为许多发行版在重新启动时清除它。另外,请确保为您的应用程序正确设置fifo所有者和权限(chown和chmod) - 您可能不希望允许Firefox的Flash插件写入此文件并命令您的数据库。