Change default server for Rails - ruby-on-rails

I installed the mongrel gem because I need it on my workstation for rare occasions, and now it's my default Rails (2) server. I know I could specify script/server webrick on the command line, but the fact is that I'd like to have my system (or app) default to webrick, and only use mongrel when specified.
Anybody know how to arrange that?
Specs: WinXP, Rails 2.3.12, Ruby 1.8.7

Ok here are a few options:
Option one - One off: Always add webrick as a command line arg
Open script/server and insert a line between the two requires
#!/usr/bin/env ruby
require File.expand_path('../../config/boot', __FILE__)
ARGV.unshift "webrick"
require 'commands/server'
Option two - Global: Edit the commands/server.rb file that launches rails
gem which railties -> tells you where the startup code is
Open the file at lib/commands/server.rb
Around line 45 edit the logic so that webrick is always launched by default.
server = Rack::Handler.get(ARGV.first) rescue nil
unless server
begin
server = Rack::Handler::WEBrick # was Mongrel
rescue LoadError => e
server = Rack::Handler::WEBrick
end
end
Option 3 - Cleanest but most involved:
Switch to Bundler and manage your dependencies directly. This is more work but positions you for switching to rails 3 at some point which might be nice depending on the life cycle of the application.
There's a tutorial for rails 2.3 here

Related

jruby no such file to load application.rb

I have a project in jRuby that I try to run.
So I'm installling jruby using rvm like this
rvm install jruby-9.1.15.0 (bc thats the version required by the project)
then im making sure that im actually using jruby by typing
ruby -v which shows me that I have jruby
next thing, I want to run the rails server so I'm typing
bundle exec rails server
and unfortunately I get an error:
/Users/foouser/Documents/Projects/fooproject/bin/config/application
LoadError: no such file to load -- /Users/foouser/Documents/Projects/fooproject/bin/config/application
require at org/jruby/RubyKernel.java:955
block in server at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:78
tap at org/jruby/RubyKernel.java:1741
server at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:75
run_command! at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:39
<main> at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands.rb:17
require at org/jruby/RubyKernel.java:955
<main> at bin/rails:5
I've tried googling that but to no avail. People seem to not encounter this issue at all. I'm sure it's got something to do with my setup because other people are successfully using said project.
Any ideas?
rails version - 4.2
jruby version - 9.1.15.0
EDIT:
after some digging, in bin/rails file the line defining the APP_PATH was like that:
APP_PATH = File.expand_path('../config/application', __FILE__)
which somehow made it looking for application.rb inside fooproject/bin/config instead of fooproject/config
but when I changed the line to
APP_PATH = File.expand_path('../../config/application', __FILE__)
it goes to the correct path where application.rb exist but still reports it as not existing.
the error is nearly the same (apart for path)
LoadError: no such file to load -- /Users/foouser/Documents/Projects/fooproject/config/application
require at org/jruby/RubyKernel.java:955
block in server at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:78
tap at org/jruby/RubyKernel.java:1741
server at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:75
run_command! at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands/commands_tasks.rb:39
<main> at /Users/foouser/.rvm/gems/jruby-9.1.15.0-jrubu/gems/railties-4.2.10/lib/rails/commands.rb:17
require at org/jruby/RubyKernel.java:955
<main> at bin/rails:4
EDIT 2:
requested permissions for application.rb:
-rw-r--r-- 1 foouser staff 5818 20 Jun 15:12 config/application.rb
config.ru:
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run Rails.application
environment.rb
# Load the Rails application.
require File.expand_path('../application', __FILE__)
# Initialize the Rails application.
Rails.application.initialize!
So, the solution I have is the "have you tried to turn it off and on again?" type.
I have deleted the whole project and cloned it again from the repo.
Everything is working now, it must have been something with my local env but I can't tell what.
Anyway, if you ever encounter something similar - purge and clone is definitely something you can try.

How to change the default rails server in Rails 3?

I'm new to Rails and I'm wondering if there is an option to change the default rails server, i.e., webrick, for another one such as 'puma' or 'thin'. I know it is possible to specify which server to run with 'rails server' command, however I would like to use this command without specify the name of the server so it can run the default rails server. Is there a way to change the default rails server into a configuration file or something like this? Thanks in advance for your help!
Based on James Hebden's answer:
Add Puma to gemfile
# Gemfile
gem 'puma'
Bundle install it
bundle
Make it default, paste this code into script/rails above require 'rails/commands':
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler.get(:puma)
So script/rails (in Rails 3.2.12) will look like:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler.get(:puma)
require 'rails/commands'
Run server
rails s
=> Booting Puma
Rack (the interface between rails and a web server) has handlers for the default WEBrick, and also for Thin. If you place the following in your Gemfile in the root of your rails project
gem 'thin'
rails server will automatically use Thin. This has been the case since 3.2rc2.
This unfortunately only applies to Thin, as Rack does not have built-in support for Unicorn, and others.
For servers that have Rack handlers (again, sadly Unicorn does not), you can do a bit of a hack to get rails server to use them. In your scripts/rails file in the root of your rails project, you can add the below just above `require 'rails/commands'
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler::<name of handler class>
This essentially resets the handler for WEBrick to point to the handler for the server you would like to use.
To get an understanding of the supported Rack handlers, take a look at the comments in the source: https://github.com/rkh/rack/blob/master/lib/rack/handler.rb
I think rails simply passes on the server option provided to rack. Rack has the following logic to determine what server to run:
https://github.com/rack/rack/blob/master/lib/rack/server.rb#L271-L273
def server
#_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
end
The first case is when a :server option was passed to the rails server command. The second is to determine the default. It looks like:
https://github.com/rack/rack/blob/master/lib/rack/handler.rb#L46-L59
def self.default(options = {})
# Guess.
if ENV.include?("PHP_FCGI_CHILDREN")
# We already speak FastCGI
options.delete :File
options.delete :Port
Rack::Handler::FastCGI
elsif ENV.include?("REQUEST_METHOD")
Rack::Handler::CGI
else
pick ['thin', 'puma', 'webrick']
end
end
Thin and Puma should be automatically picked up. The fallback is Webrick. Of course other web servers could override this behavior to make them the first in the chain.
If your Webserver is not picked up by default you could monkey-patch the default method to work like you want it. Of course this could break in future versions of rack.
Rack will now look at a RACK_HANDLER environment variable file to see if you've specified a default rack handler. You can add a line like this to your .env file to set the default if you're using dotenv, or specify the assignment from the command line.
`RACK_HANDLER=webrick`
This should work as of this pull request:
https://github.com/rack/rack/pull/590
I wouldn't get hung up on specifically using the rails server command. Just install whichever gem you want and alias the command (e.g. rails s Puma) to something simple like rs.
If you want unicorn/thin/etc, just add the gem to your gemfile
i.e. gem 'unicorn', gem 'thin', etc. then run bundle install at the command line.
As far as I can tell, adding either of these gems runs the appropriate server via rails server
UPDATE
Apparently this only works for Thin or Puma.
If you have thin in your Gemfile, you need to do this:
require 'rack/handler'
Rack::Handler::Thin = Rack::Handler.get(:puma)
If you use bash run: export RACK_HANDLER=webrick

While running an application on Rails, which file of our application is executed first of all?

Please answer for this. The first file executed of the application while giving rails s.
I need to know the initiation of the application project.
Thanks in advance.
The first application file executed will typically be config/boot.rb
Then config/environment.rb, which will typically load one of the files in config/environments/ (which file is run, will depend on the environment that's been set.
Then config/application.rb will get executed
Thereafter, config/routes.rb will give the server its key information about how to handle incoming requests
Type which rails will give you the answer.
Then open the file, which is something like:
#!/usr/bin/env ruby1.9.1
#
# This file was generated by RubyGems.
#
# The application 'railties' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0"
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
version = $1
ARGV.shift
end
gem 'railties', version
load Gem.bin_path('railties', 'rails', version)
The flow of application run on Rails is found here.
..]$ rails s
Background process
{
..config/boot.rb
installing the file Gemfile (in root dir of appilcation)
..config/application.rb
}
[Server boots here/ shown in Terminal]
=> Booting WEBrick
=> Rails 3.2.6 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Background process
{
..config.ru
..config/environment.rb
..config/environment/development.rb
..config/initializer/*.*
..config/routes.rb
}
[Server Starts from here/ shown in Terminal]
> INFO WEBrick 1.3.1
> INFO ruby 1.9.3 ('Date') [i686-linux]
> INFO WEBrick::HTTPServer#start: pid=3031 port=3000

Is there a way Rails 3.0.x can default to using Thin?

I run the Thin webserver for basically every app in my dev/test environments. When I used Mongrel with Rails 2.x, all I had to type was script/server to get it to run the webserver I choose. But with Rails 3, I have to specify Thin every time. Is there a way to get Thin running on my Rails apps by just typing rails s instead of rails s thin?
Yeah it's possible to do this.
The way the rails s command works at the end of the day is by falling through to Rack and letting it pick the server. By default the Rack handler will try to use mongrel and if it can't find mongrel it will go with webrick. All we have to do is patch the handler slightly. We'll need to insert our patch into the rails script itself. Here is what you do, crack open your script/rails file. By default it should look like this:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
We insert our patch right before the require 'rails/commands' line. Our new file should look like this:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rack/handler'
Rack::Handler.class_eval do
def self.default(options = {})
# Guess.
if ENV.include?("PHP_FCGI_CHILDREN")
# We already speak FastCGI
options.delete :File
options.delete :Port
Rack::Handler::FastCGI
elsif ENV.include?("REQUEST_METHOD")
Rack::Handler::CGI
else
begin
Rack::Handler::Mongrel
rescue LoadError
begin
Rack::Handler::Thin
rescue LoadError
Rack::Handler::WEBrick
end
end
end
end
end
require 'rails/commands'
Notice that it will now try Mongrel and if there is an error try for Thin and only then go with Webrick. Now when you type rails s we get the behaviour we're after.
As of Rails 3.2rc2, thin is now run by default on invoking rails server when gem 'thin' is in your Gemfile! Thanks to this pull request: https://github.com/rack/rack/commit/b487f02b13f42c5933aa42193ed4e1c0b90382d7
Works great for me.
In script/rails the following works as well:
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rack/handler'
Rack::Handler::WEBrick = Rack::Handler::Thin
require 'rails/commands'
Simply install thin, cd to the directory that your app is in and run thin start. Works perfectly here. :)
You can use http://www.softiesonrails.com/2008/4/27/using-thin-instead-of-mongrel to change as needed. (Its the one I used)

Custom Daemon with Rails 3

I'm trying to create a custom daemon that loads up the Rails environment.
My environment is as follows:
ruby-1.9.2-p180
rails 3.0.5
I did the following:
-Installed the daemons gem
-Installed daemon_generator plugin found here:
https://github.com/dougal/daemon_generator
-Generated a daemon: rails generate daemon listener
All this worked fine. When I run the daemon, it works.
However, as soon as I try to access an active record object like trying to retrieve a user, it blows up.
*** below you find the most recent exception thrown, this will be likely (but not certainly) the exception that made the application exit abnormally ***
#<NameError: method `recognize' not defined in Rack::Mount::RouteSet>
*** below you find all exception objects found in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***
#<NoMemoryError: failed to allocate memory>
#<SystemStackError: stack level too deep>
#<fatal: exception reentered>
#<NoMethodError: undefined method `eq' for nil:NilClass>
#<NameError: method `recognize' not defined in Rack::Mount::RouteSet>
Any thoughts on how to create a Daemon that loads up Rails 3.0.5?
I prefer to roll my own rails daemon controllers. Here is a simple example that works for most cases:
script/daemon
#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
ENV["APP_ROOT"] ||= File.expand_path("#{File.dirname(__FILE__)}/..")
ENV["RAILS_ENV_PATH"] ||= "#{ENV["APP_ROOT"]}/config/environment.rb"
script = "#{ENV["APP_ROOT"]}/daemons/#{ARGV[1]}"
Daemons.run(script, dir_mode: :normal, dir: "#{ENV["APP_ROOT"]}/tmp/pids")
daemons/your_daemon_script.rb
require ENV["RAILS_ENV_PATH"]
loop {
... your code ...
}
You can control your deamons by using the following commands:
script/daemon run your_daemon_script.rb
script/daemon start your_daemon_script.rb
script/daemon stop your_daemon_script.rb
This enables me to easily add new daemons and I can easily load rails in each script if necessary.
I had a lot of problems trying get daemon_generator working. I got my daemon working by skipping the daemon_generator all together and just using the daemons gem (v1.1.3).
in urserver_control.rb (in root ruby app directory):
#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
require 'TweetMsg'
Daemons.run('urserver.rb')
in urserver.rb:
#!/usr/bin/env ruby
require File.expand_path(File.join(File.dirname(__FILE__), 'config', 'environmen
t'))
require "rubygems"
--- insert your code here ---
You can test by running your server directly ruby urserver.rb or ruby urserver_controller run
And then once that is working starting and stopping the controllerruby urserver_control.rb {start | stop | run }
Looking at the code in https://github.com/dougal/daemon_generator/blob/master/lib/generators/daemon/templates/script.rb it appears they load things in the wrong order...
Looking at my delayed_job daemon script and config.ru they load config/environment.rb (which in turn loads application.rb and initializes the app)
So a possible fix would be to edit the generated script and make it only require 'config/environment.rb'
I tried this:
#!/usr/bin/env ruby
# You might want to change this
ENV["RAILS_ENV"] ||= "development"
require File.dirname(__FILE__) + "/../config/environment"
$running = true
Signal.trap("TERM") do
$running = false
end
while($running) do
# Replace this with your code
Rails.logger.auto_flushing = true
o = Order.last
Rails.logger.info "The latest order is #{o.id}"
sleep 10
end
and it yielded no errors... (Tried both Rails 3.0.3 and 3.0.5)
I had problems running daemon as is on my staging server (Rails 3.0.7, ruby 1.8.7, passenger 3.0.0). Neither
require File.dirname(FILE) + "/../../config/application"
Rails.application.require_environment!
nor
require File.dirname(FILE) + "/../config/environment"
Worked.
I fixed it by re-installing the standard config.ru in rails root (which I had de-installed to integrate w passenger... not sure now how I will get daemons & passenger to work together now ...)

Resources