开发者

Optimizing Rails loading for maintenance scripts

开发者 https://www.devze.com 2023-01-06 13:52 出处:网络
I wrote a script that does maintenance tasks for a rails application. The script uses a class that uses models defined in the application. Just an example, let\'s say application defines model User, a

I wrote a script that does maintenance tasks for a rails application. The script uses a class that uses models defined in the application. Just an example, let's say application defines model User, and my class (used within the script), sends messages to it, like User.find id.

I am looking for ways to optimize this script, because right now it has to load the application environment: require '../config/environment'. This takes ~15 seconds.

Had the script not use application codebase to do its job, I could have replaced model abstractions with raw SQL. But unfortunatly I can't do that because I would have to repeat the code in the script that is already present in t开发者_高级运维he codebase. Not only would this violate DRY principle and require alot of work, the script would not be very maintainable, in case the model methods that I am using change.

I would like to hear ideas how to approach this problem. The script is not run from the application itself, but from the shell (with Capistrano for instance).

I hope I've described the problem clear enough. Thank you.


Could you write a little daemon that is in a read on a pipe (or named fifo, or unix domain socket, or, with more complexity, a tcp port) that accepts 'commands' that would be run on your database?

#!/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

You could start this thing up with vixie cron's @reboot specifier, or you could run it via capistrano commands, or run it out of init or init scripts. Then you write your capistrano rules (that you have now) to simply echo commands into the fifo:

First,

mkfifo /tmp/fifo

In one terminal:

$ ./env.rb

In another terminal:

$ echo -n "cleanup" > /tmp/fifo
$ echo -n "publish" > /tmp/fifo
$ echo -n "go away" > /tmp/fifo

The output in the first terminal looks like this:

clean!
published!
invalid command, ignoring

You could make the matching as friendly (perhaps allow plain echo, rather than require echo -n as my example does) or unfriendly as you want. And the commands that get run can of course call into your model files to do their work.

Please make sure you choose a good location for your fifo -- /tmp/ is probably a bad place, as many distributions clear it on reboot. Also make sure you set the fifo owner and permission (chown and chmod) appropriately for your application -- you might not want to allow your Firefox's flash plugin to write to this file and command your database.

0

精彩评论

暂无评论...
验证码 换一张
取 消