Ignore:
Timestamp:
Jan 7, 2010, 12:32:45 AM (15 years ago)
Author:
mitchb
Message:
Make Rails autoinstalls pick up code changes automatically
Ordinarily, a Rails app in production mode running as an fcgi
will continue to use old code, necessitating being killed on
all of our servers that have an instance of it hanging around.
This patch causes the fcgi to notice application changes and
reload itself automatically, providing functionality similar
to the enhancement we made for Django in r1278.  However, unlike
Django, the Rails fcgi is able to reload without needing to be
killed with fire in order to avoid fcgi renegotiation issues.

This code was developed and contributed by Greg Brockman <gdb@mit.edu>.
I've just tested and incorporated it into the scripts autoinstaller.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/locker-dev/locker/deploy/bin/rails

    r1407 r1408  
    114114untie @railswelcome;
    115115
     116tie my @railsfcgi, 'Tie::File', 'public/dispatch.fcgi';
     117for (@railsfcgi) {
     118    s/^[^#]*RailsFCGIHandler/## Commented out by scripts.mit.edu autoinstaller\n## RailsFCGIHandler/;
     119}
     120untie @railsfcgi;
     121open RAILSFCGI, ">>public/dispatch.fcgi";
     122print RAILSFCGI <<EOF;
     123
     124## Added by scripts.mit.edu autoinstaller to reload when app code changes
     125Thread.abort_on_exception = true
     126
     127t1 = Thread.new do
     128   RailsFCGIHandler.process!
     129end
     130
     131t2 = Thread.new do
     132   # List of directories to watch for changes before reload
     133   Thread.current[:watched_dirs] = ['app', 'config', 'db', 'lib', 'public']
     134   # Sample filter: /(\.rb|\.erb)\$/.  Default filter: watch all files
     135   Thread.current[:watched_extensions] = //
     136
     137   def modified(file)
     138     mtime = File.stat(file).mtime
     139     Thread.current[:modifications][file] ||= mtime
     140     Thread.current[:modifications][file] != mtime
     141   end
     142
     143   # Don't symlink yourself into a loop.  Please.
     144   def modified_dir(dir)
     145     Dir.new(dir).each do |file|
     146       absfile = File.join(dir, file)
     147       if FileTest.directory? absfile
     148         next if file == '.' or file == '..'
     149         return true if modified_dir(absfile)
     150       else
     151         return true if Thread.current[:watched_extensions] =~ absfile &&
     152           modified(absfile)
     153       end
     154     end
     155     false
     156   end
     157
     158   def reload
     159     Thread.current[:modifications] = {}
     160     RailsFCGIHandler.reload!
     161   end
     162
     163   Thread.current[:modifications] = {}
     164   # Wait until the modify time changes, then reload.
     165   while true
     166     reload if Thread.current[:watched_dirs].inject(false) {|z, dir| z ||
     167       modified_dir(File.join(File.dirname(__FILE__), '..', dir))}
     168     sleep 1
     169   end
     170end
     171
     172t1.join
     173t2.join
     174## End of scripts.mit.edu autoinstaller additions
     175EOF
     176
    116177print "Your application is located in:\n";
    117178print "  /mit/$USER/web_scripts/$addrend/\n";
Note: See TracChangeset for help on using the changeset viewer.