views:

1033

answers:

4

I've set up Rack::Reload according to this thread

# config.ru
require 'rubygems'
require 'sinatra'

set :environment, :development

require 'app'
run Sinatra::Application

# app.rb  
class Sinatra::Reloader < Rack::Reloader
  def safe_load(file, mtime, stderr = $stderr)
    if file == Sinatra::Application.app_file
      ::Sinatra::Application.reset!
      stderr.puts "#{self.class}: reseting routes"
    end
    super
  end
end

configure(:development) { use Sinatra::Reloader }

get '/' do
  'foo'
end

Running with thin via thin start -R config.ru, but it only reloads newly added routes. When I change already existing route, it still runs the old code.

When I add new route, it correctly reloads it, so it is accessible, but it doesn't reload anything else.

For example, if I changed routes to

get '/' do
  'bar'
end

get '/foo' do
  'baz'
end

Than / would still serve foo, even though it has changed, but /foo would correctly reload and serve baz.

Is this normal behavior, or am I missing something? I'd expect whole source file to be reloaded. The only way around I can think of right now is restarting whole webserver when filesystem changes.

I'm running on Windows Vista x64, so I can't use shotgun because of fork().

A: 

Does Shotgun not work on Windows?

From the README:

                                Shotgun

This is an automatic reloading version of the rackup command that's shipped with Rack. It can be used as an alternative to the complex reloading logic provided by web frameworks or in environments that don't support application reloading.

The shotgun command starts one of Rack's supported servers (e.g., mongrel, thin, webrick) and listens for requests but does not load any part of the actual application. Each time a request is received, it forks, loads the application in the child process, processes the request, and exits the child process. The result is clean, application-wide reloading of all source files and templates on each request.

Mike H
Sorry, didn't see your note about Shotgun
Mike H
+4  A: 

You could try sinatra-reloader, which is known to work well on Windows (also, it's faster than shotgun).

Konstantin Haase
What was the down-vote for?
Konstantin Haase
We had this problem ourselves, since two of my team use Windows, and two are on Macs. This is the solution we went with, seems to be working well so far.
Joshua Cheek
not only faster but I find sinatra-reloader easier to use :-)
Radek
A: 

This works:

# config.ru
require 'rubygems'
require 'app'

set :environment, :development
run Sinatra::Application

# app.rb  
require 'sinatra'

class Sinatra::Reloader < Rack::Reloader
  def safe_load(file, mtime, stderr = $stderr)
    if file == File.expand_path(Sinatra::Application.app_file)
      ::Sinatra::Application.reset!
      stderr.puts "#{self.class}: reseting routes"
    end
    super
  end
end

configure(:development) { use Sinatra::Reloader }

get '/' do
  'foo'
end

It matters from where you have the require statement. But I find the following solution more elegant and robust:

# config.ru
require 'rubygems'
require 'sinatra'
require 'rack/reloader'
require 'app'

set :environment, :development

use Rack::Reloader, 0 if development?
run Sinatra::Application

# app.rb  
Sinatra::Application.reset! 
get '/' do
  'foo'
end
Jan Berkel
A: 

You can also try using Trinidad a JRuby Rack container based on Tomcat. In my experience it does change reloading by default without having to modify your source files. Bloody fast too. Obviously no good if you are using native libraries, but if you are deploying on Windows you are probably used to adopting a pure-ruby approach.

Its syntax is just as simple as the thin approach:

jruby -S trinidad -r config.ru

There is no Java specific yak shaving (i.e. creating web.xml or WARing up your Ruby app) and the gem is simple to install.

Richard Conroy