diff options
Diffstat (limited to 'railties/lib')
-rw-r--r-- | railties/lib/commands/server.rb | 2 | ||||
-rw-r--r-- | railties/lib/initializer.rb | 8 | ||||
-rw-r--r-- | railties/lib/rails/rack.rb | 3 | ||||
-rw-r--r-- | railties/lib/rails/rack/cascade.rb | 31 | ||||
-rw-r--r-- | railties/lib/rails/rack/log_tailer.rb | 35 | ||||
-rw-r--r-- | railties/lib/rails/rack/logger.rb | 28 | ||||
-rw-r--r-- | railties/lib/rails/rack/metal.rb | 27 | ||||
-rw-r--r-- | railties/lib/rails_generator/generators/components/metal/USAGE | 8 | ||||
-rw-r--r-- | railties/lib/rails_generator/generators/components/metal/metal_generator.rb | 8 | ||||
-rw-r--r-- | railties/lib/rails_generator/generators/components/metal/templates/metal.rb | 12 | ||||
-rw-r--r-- | railties/lib/tasks/middleware.rake | 2 |
11 files changed, 133 insertions, 31 deletions
diff --git a/railties/lib/commands/server.rb b/railties/lib/commands/server.rb index 7057fcc33f..43b18004c0 100644 --- a/railties/lib/commands/server.rb +++ b/railties/lib/commands/server.rb @@ -84,7 +84,7 @@ else end app = Rack::Builder.new { - use Rails::Rack::Logger + use Rails::Rack::LogTailer unless options[:detach] use Rails::Rack::Static use Rails::Rack::Debugger if options[:debugger] run inner_app diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb index 56e8ce95ab..637fe74313 100644 --- a/railties/lib/initializer.rb +++ b/railties/lib/initializer.rb @@ -155,6 +155,8 @@ module Rails initialize_framework_settings initialize_framework_views + initialize_metal + add_support_load_paths load_gems @@ -533,6 +535,10 @@ Run `rake gems:install` to install the missing gems. end end + def initialize_metal + configuration.middleware.use Rails::Rack::Metal + end + # Initializes framework-specific settings for each of the loaded frameworks # (Configuration#frameworks). The available settings map to the accessors # on each of the corresponding Base classes. @@ -915,6 +921,7 @@ Run `rake gems:install` to install the missing gems. # Followed by the standard includes. paths.concat %w( app + app/metal app/models app/controllers app/helpers @@ -933,6 +940,7 @@ Run `rake gems:install` to install the missing gems. def default_eager_load_paths %w( + app/metal app/models app/controllers app/helpers diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb index 90535674e9..9705f65e52 100644 --- a/railties/lib/rails/rack.rb +++ b/railties/lib/rails/rack.rb @@ -1,7 +1,8 @@ module Rails module Rack autoload :Debugger, "rails/rack/debugger" - autoload :Logger, "rails/rack/logger" + autoload :LogTailer, "rails/rack/log_tailer" + autoload :Metal, "rails/rack/metal" autoload :Static, "rails/rack/static" end end diff --git a/railties/lib/rails/rack/cascade.rb b/railties/lib/rails/rack/cascade.rb new file mode 100644 index 0000000000..d5af7fc77e --- /dev/null +++ b/railties/lib/rails/rack/cascade.rb @@ -0,0 +1,31 @@ +require 'active_support/ordered_hash' + +module Rails + module Rack + # Try a request on several apps; return the first non-404 response. + class Cascade + attr_reader :apps + + def initialize(apps) + @apps = ActiveSupport::OrderedHash.new + apps.each { |app| add app } + end + + def call(env) + @apps.keys.each do |app| + result = app.call(env) + return result unless result[0].to_i == 404 + end + Metal::NotFoundResponse + end + + def add(app) + @apps[app] = true + end + + def include?(app) + @apps.include?(app) + end + end + end +end diff --git a/railties/lib/rails/rack/log_tailer.rb b/railties/lib/rails/rack/log_tailer.rb new file mode 100644 index 0000000000..a237cee6bc --- /dev/null +++ b/railties/lib/rails/rack/log_tailer.rb @@ -0,0 +1,35 @@ +module Rails + module Rack + class LogTailer + EnvironmentLog = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log" + + def initialize(app, log = nil) + @app = app + + path = Pathname.new(log || EnvironmentLog).cleanpath + @cursor = ::File.size(path) + @last_checked = Time.now.to_f + + @file = ::File.open(path, 'r') + end + + def call(env) + response = @app.call(env) + tail_log + response + end + + def tail_log + @file.seek @cursor + + mod = @file.mtime.to_f + if mod > @last_checked + contents = @file.read + @last_checked = mod + @cursor += contents.size + $stdout.print contents + end + end + end + end +end diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb deleted file mode 100644 index 89d02e45a9..0000000000 --- a/railties/lib/rails/rack/logger.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Rails - module Rack - class Logger - EnvironmentLog = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log" - - def initialize(app, log = nil) - @app = app - @path = Pathname.new(log || EnvironmentLog).cleanpath - @cursor = ::File.size(@path) - @last_checked = Time.now - end - - def call(env) - response = @app.call(env) - ::File.open(@path, 'r') do |f| - f.seek @cursor - if f.mtime > @last_checked - contents = f.read - @last_checked = f.mtime - @cursor += contents.length - print contents - end - end - response - end - end - end -end diff --git a/railties/lib/rails/rack/metal.rb b/railties/lib/rails/rack/metal.rb new file mode 100644 index 0000000000..1df31a1594 --- /dev/null +++ b/railties/lib/rails/rack/metal.rb @@ -0,0 +1,27 @@ +require 'rails/rack/cascade' + +module Rails + module Rack + module Metal + NotFoundResponse = [404, {}, []].freeze + NotFound = lambda { NotFoundResponse } + + class << self + def new(app) + Cascade.new(builtins + [app]) + end + + def builtins + base = "#{Rails.root}/app/metal" + matcher = /\A#{Regexp.escape(base)}\/(.*)\.rb\Z/ + + Dir["#{base}/**/*.rb"].sort.map do |file| + file.sub!(matcher, '\1') + require file + file.classify.constantize + end + end + end + end + end +end diff --git a/railties/lib/rails_generator/generators/components/metal/USAGE b/railties/lib/rails_generator/generators/components/metal/USAGE new file mode 100644 index 0000000000..123ec6c03f --- /dev/null +++ b/railties/lib/rails_generator/generators/components/metal/USAGE @@ -0,0 +1,8 @@ +Description: + Cast some metal! + +Examples: + `./script/generate metal poller` + + This will create: + Metal: app/metal/poller.rb diff --git a/railties/lib/rails_generator/generators/components/metal/metal_generator.rb b/railties/lib/rails_generator/generators/components/metal/metal_generator.rb new file mode 100644 index 0000000000..64f49d929d --- /dev/null +++ b/railties/lib/rails_generator/generators/components/metal/metal_generator.rb @@ -0,0 +1,8 @@ +class MetalGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + m.directory 'app/metal' + m.template 'metal.rb', File.join('app/metal', "#{file_name}.rb") + end + end +end diff --git a/railties/lib/rails_generator/generators/components/metal/templates/metal.rb b/railties/lib/rails_generator/generators/components/metal/templates/metal.rb new file mode 100644 index 0000000000..e94982b69a --- /dev/null +++ b/railties/lib/rails_generator/generators/components/metal/templates/metal.rb @@ -0,0 +1,12 @@ +# Allow the metal piece to run in isolation +require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails) + +class <%= class_name %> + def self.call(env) + if env["PATH_INFO"] =~ /^\/<%= file_name %>/ + [200, {"Content-Type" => "text/html"}, ["Hello, World!"]] + else + [404, {"Content-Type" => "text/html"}, ["Not Found"]] + end + end +end diff --git a/railties/lib/tasks/middleware.rake b/railties/lib/tasks/middleware.rake index e0dcf50307..05f159184e 100644 --- a/railties/lib/tasks/middleware.rake +++ b/railties/lib/tasks/middleware.rake @@ -1,6 +1,6 @@ desc 'Prints out your Rack middleware stack' task :middleware => :environment do - ActionController::Dispatcher.middleware.each do |middleware| + ActionController::Dispatcher.middleware.active.each do |middleware| puts "use #{middleware.inspect}" end puts "run ActionController::Dispatcher.new" |