I've read Richard Schneeman's article, and a bunch of other ones. ;-)
I'm still struggling with this.
Here's few gems I've added in my Gemfile to benchmark my app:
gem 'airbrake'
gem 'newrelic_rpm'
gem 'stackprof'
gem 'derailed', group: :development
gem 'rack-mini-profiler'
gem 'flamegraph'
gem 'memory_profiler'
gem "skylight"
After a lots of benchmarks in development and in staging env, I know where my app is not fast enough but there's not memory leak (some small mem bloats sometimes maybe).
newapp-staging app is the new version (aka: new frontend, upgraded gems, optimized queries, ...) of oldapp-production app.
Please have a look at the screenshots (oldapp-production use webrick, newapp-staging use puma)
So here comes 2 simple questions:
question #1
newapp-staging app is using ruby '2.2.0' & rails '3.2.22.2' and I can't ensure that it is threadsafe because of my code and the associated gems, so... I must use 1 thread at a time. Is puma an advantage here? Metrics are telling me not.
OR... my configuration is not good. (missing preload_app! maybe, or other things?) Here's my Procfile:
web: bundle exec puma -t 1:1 -p ${PORT:-3000} -e ${RACK_ENV:-development}
worker: bundle exec rake jobs:work
question #2
Unicorn could be used as a replacement?
Thank you for your time and your advices.
Cheers
Using unicorn is the best move here. Here's my configuration if that could help anyone.
Gemfile:
gem 'unicorn'
gem 'unicorn-rails'
group :production, :staging do
gem 'unicorn-worker-killer'
end
Procfile:
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
worker: bundle exec rake jobs:work
config/unicorn.rb
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 2)
timeout 15
preload_app true
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
config.ru
if ENV['RAILS_ENV'] == 'production' || ENV['RAILS_ENV'] == 'staging'
require 'unicorn/worker_killer'
use Unicorn::WorkerKiller::MaxRequests, 768, 1024, true
use Unicorn::WorkerKiller::Oom, (450*(1024**2)), (490*(1024**2)), 16, true
end
require ::File.expand_path('../config/environment', __FILE__)
use Rack::Deflater
run MyApp::Application
On Heroku:
2 x `Standard 2X dynos` for web
1 x `Standard 1X dyno` for worker
Heroku config vars:
SENSIBLE_DEFAULTS: enabled (just in case) & WEB_CONCURRENCY: 2
Cheers
I want to use guard to run my bacon tests, my Gemfile looks like:
source 'https://rubygems.org'
gem 'sinatra'
gem 'sidekiq'
gem 'slim'
gem 'puma'
gem 'nokogiri'
gem 'httparty'
group :test, :development do
gem 'guard'
gem 'bacon'
gem 'guard-bacon'
gem 'libnotify'
gem 'rb-inotify'
end
My Guardfile looks like
# parameters:
# output => the formatted to use
# backtrace => number of lines, nil = everything
guard 'bacon', :output => "BetterOutput", :backtrace => 4 do
watch(%r{^lib/(.+)\.rb$}) { |m| "specs/lib/#{m[1]}_spec.rb" }
watch(%r{specs/.+\.rb$})
end
When I run guard the following happens
$ guard
Bacon: Using output BetterOutput.
Bacon: Limiting backtrace to 4 lines.
09:02:05 - INFO - Guard uses Libnotify to send notifications.
09:02:05 - INFO - Guard uses TerminalTitle to send notifications.
09:02:05 - INFO - Guard is now watching at '/home/martin/code/jse-api'
Guard::Bacon started.
[1] guard(main)> %
$
It seems to load everything, get to the guard prompt and exit.
I have no idea why?
The issue seems to the version of guard required by guard-bacon 1.1.0
If you force it to the latest version of guard
gem 'guard', '>= 1.8.0'
It falls back to a older version of guard-bacon 1.0.5 and everything works.
I am using WickedPDF, and I have basically two gems that include the binaries:
gem "wkhtmltopdf-heroku", "1.0.0"
gem "wkhtmltopdf-binary", "0.9.5.3"
The first one is supposed to be just for production, and the second one for development. The deployment to Heroku doesn't work if I have my Gemfile like:
group :development do
gem "wkhtmltopdf-binary", "0.9.5.3"
end
group :production do
gem "wkhtmltopdf-heroku", "1.0.0"
end
And it doesn't work either if I have it like:
group :production do
gem "wkhtmltopdf-heroku", "1.0.0"
end
It just works if I have it without groups. Just like:
gem "wkhtmltopdf-heroku", "1.0.0"
The error that I get is:
RuntimeError: Location of wkhtmltopdf unknown
Why would this happen? Why Heroku is not using the production group?
WickedPdf tries to figure out where the wkhtmltopdf binary lives, but can have a hard time on some systems (particularly shared servers).
You probably have to set it manually in an initializer something like this:
bin_location = case Rails.env
when 'production' then "/wherever/your/binary/is/bin/wkhtmltopdf"
when 'development' then "/local/path/to/wkthmltopdf"
else `which wkhtmltopdf`
end
WickedPdf.config = { :exe_path => bin_location }
I am trying to do a simple test for my model Course, I have wrote this factory:
FactoryGirl.define do
factory :course do
name 'How to be happy ?'
end
end
the course_spec.rb:
require "rspec"
require 'factory_girl_rails'
describe "When a course is created" do
it "can't be deleted if any student is enrolled to it" do
FactoryGirl.find_definitions
course = FactoryGirl.build(:course)
student= Student.create!
course.students << student
course.destroy
course.name.should !=nil
end
end
but, I reach this line
course = FactoryGirl.build(:course)
I get the error:
FactoryGirl::DuplicateDefinitionError: Factory already registered: course
if I comment the :course definition in the factory, I get:
NameError: uninitialized constant Course
Any idea please ?
here is my Gem Envioronment:
RubyGems Environment:
RUBYGEMS VERSION: 1.8.10
RUBY VERSION: 1.9.3 (2011-10-30 patchlevel 0) [i686-linux]
INSTALLATION DIRECTORY: /home/sam/.rvm/gems/ruby-1.9.3-p0
RUBY EXECUTABLE: /home/sam/.rvm/rubies/ruby-1.9.3-p0/bin/ruby
EXECUTABLE DIRECTORY: /home/sam/.rvm/gems/ruby-1.9.3-p0/bin
RUBYGEMS PLATFORMS:
ruby
x86-linux
GEM PATHS:
/home/sam/.rvm/gems/ruby-1.9.3-p0
/home/sam/.rvm/gems/ruby-1.9.3-p0#global
GEM CONFIGURATION:
:update_sources => true
:verbose => true
:benchmark => false
:backtrace => false
:bulk_threshold => 1000
REMOTE SOURCES:
http://rubygems.org/
----------------------
IDE: JetBrains RubyMine (EAP) RM-112.291, build #RM-112.291
OS: Linux 3.0.0-12-generic[i386]
Java: 1.6.0_23-b23
RubyMine SDK Environment:
Sdk: RVM: ruby-1.9.3-p0
Sdk Version: ver.1.9.3p0 ( revision 33570) p0
Ruby Interpreter: /home/sam/.rvm/rubies/ruby-1.9.3-p0/bin/ruby
RVM Sdk: yes, gemset:[default]
RVM Home: /home/sam/.rvm
Sdk Language Level: 1.9
Sdk Load Path:
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby/1.9.1
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby/1.9.1/i686-linux
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/vendor_ruby/1.9.1
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/vendor_ruby/1.9.1/i686-linux
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/vendor_ruby
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1
/home/sam/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/i686-linux
/home/sam/rubyMine4beta/rubystubs19
Sdk Gem paths:
file:///home/sam/.rvm/gems/ruby-1.9.3-p0/bundler/gems
file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems
file:///home/sam/.rvm/gems/ruby-1.9.3-p0#global/gems
Gems used for 'hope':
ffi (1.0.11, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/ffi-1.0.11)
sass (3.1.12, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/sass-3.1.12)
coffee-script-source (1.2.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/coffee-script-source-1.2.0)
mail (2.3.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/mail-2.3.0)
activesupport (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/activesupport-3.1.0)
i18n (0.6.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/i18n-0.6.0)
uglifier (1.2.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/uglifier-1.2.1)
sprockets (2.0.3, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/sprockets-2.0.3)
foreigner (1.1.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/foreigner-1.1.1)
treetop (1.4.10, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/treetop-1.4.10)
haml (3.1.4, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/haml-3.1.4)
ansi (1.4.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/ansi-1.4.1)
mime-types (1.17.2, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/mime-types-1.17.2)
rack (1.3.6, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rack-1.3.6)
devise (1.5.2, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/devise-1.5.2)
warden (1.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/warden-1.1.0)
diff-lcs (1.1.3, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/diff-lcs-1.1.3)
activeresource (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/activeresource-3.1.0)
sass-rails (3.1.5, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/sass-rails-3.1.5)
therubyracer (0.9.9, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/therubyracer-0.9.9)
rspec-expectations (2.7.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rspec-expectations-2.7.0)
coffee-rails (3.1.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/coffee-rails-3.1.1)
activemodel (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/activemodel-3.1.0)
simple_form (1.5.2, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/simple_form-1.5.2)
bundler (1.0.21, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/bundler-1.0.21)
thor (0.14.6, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/thor-0.14.6)
activerecord (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.1.0)
json (1.6.4, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/json-1.6.4)
coffee-script (2.2.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/coffee-script-2.2.0)
execjs (1.2.13, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/execjs-1.2.13)
turn (0.8.3, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/turn-0.8.3)
rake (0.9.2.2, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rake-0.9.2.2)
kaminari (0.13.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/kaminari-0.13.0)
rdoc (3.12, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rdoc-3.12)
rspec (2.7.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rspec-2.7.0)
actionpack (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/actionpack-3.1.0)
rspec-rails (2.7.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rspec-rails-2.7.0)
guard (0.10.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/guard-0.10.0)
cocoon (1.0.15, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/cocoon-1.0.15)
libv8 (3.3.10.4, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/libv8-3.3.10.4-x86-linux)
rspec-core (2.7.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rspec-core-2.7.1)
jquery-rails (1.0.19, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/jquery-rails-1.0.19)
rails (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rails-3.1.0)
rack-ssl (1.3.2, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rack-ssl-1.3.2)
arel (2.2.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/arel-2.2.1)
erubis (2.7.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/erubis-2.7.0)
rb-fsevent (0.4.3.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rb-fsevent-0.4.3.1)
builder (3.0.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/builder-3.0.0)
orm_adapter (0.0.5, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/orm_adapter-0.0.5)
rack-cache (1.0.3, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rack-cache-1.0.3)
multi_json (1.0.4, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/multi_json-1.0.4)
spork (0.9.0.rc9, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/spork-0.9.0.rc9)
tilt (1.3.3, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/tilt-1.3.3)
rack-mount (0.8.3, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rack-mount-0.8.3)
tzinfo (0.3.31, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/tzinfo-0.3.31)
validate_url (0.2.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/validate_url-0.2.0)
sqlite3 (1.3.5, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/sqlite3-1.3.5)
rspec-mocks (2.7.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rspec-mocks-2.7.0)
polyglot (0.3.3, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/polyglot-0.3.3)
railties (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.1.0)
hike (1.2.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/hike-1.2.1)
guard-spork (0.5.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/guard-spork-0.5.0)
factory_girl_rails (1.4.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/factory_girl_rails-1.4.0)
factory_girl (2.3.2, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/factory_girl-2.3.2)
will_paginate (3.0.2, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/will_paginate-3.0.2)
rack-test (0.6.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/rack-test-0.6.1)
client_side_validations (3.1.4, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/client_side_validations-3.1.4)
actionmailer (3.1.0, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.1.0)
bcrypt-ruby (3.0.1, file:///home/sam/.rvm/gems/ruby-1.9.3-p0/gems/bcrypt-ruby-3.0.1)
EDIT
The spec_helper.rb file:
require 'rubygems'
require 'spork'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
end
end
Spork.each_run do
# This code will be run each time you run your specs.
FactoryGirl.factories.clear
# either this if you have multiple files under 'spec/factories',
# or just load the single file, such as 'spec/factories.rb'
Dir.glob("#{::Rails.root}/spec/factories/*.rb").each do |file|
load "#{file}"
end
end
Did you try to remove this line ?
FactoryGirl.find_definitions
I am using Factory Girl (with the factory_girl_rails gem) & Shoulda with a 3.1 project and didn't have to explicitly load definitions.
All you should need to do is require 'rspec_factory_girl' and then the definitions.
Generally if you put it into the spec_helper.rb, it will require all the files in the spec/ directory, which means if you have your factories defined for example in spec/factories.rb, they will get loaded automatically.
That however requires you to add require 'spec_helper' at the top of your spec file, which seems you're not doing.
If you don't want to use the spec_helper.rb file this way, then just manually require the definition, such as require 'factories'.
One little trick if you're using something like spork and need to reload your factories manually before each run
FactoryGirl.factories.clear
# either this if you have multiple files under 'spec/factories',
# or just load the single file, such as 'spec/factories.rb'
Dir.glob("#{::Rails.root}/spec/factories/*.rb").each do |file|
load "#{file}"
end
edit: complete example of Spork
Spork.each_run do
require 'factory_girl_rails'
# reload all the models
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
load model
end
# reload all factories
FactoryGirl.factories.clear
Dir.glob("#{::Rails.root}/spec/factories/*.rb").each do |file|
load "#{file}"
end
# reload routes
YourAppName::Application.reload_routes!
end
I also encountered this error:
FactoryGirl::DuplicateDefinitionError: Factory already registered: factory_name
And I fixed the issue by adding :require => false in my Gemfile like this one:
gem 'factory_girl_rails', :require => false
Then require it in the test_helper.rb only once by having this line:
require 'factory_girl_rails'
Here is what worked for me in Rails 4.2.6
In rails_helper.rb add these librarys
require 'factory_girl'
require 'factory_girl_rails'
Add these to the config part
config.include FactoryGirl::Syntax::Methods
In my case, It happened when I accidentally put two factory files which contain same key as follows:
Rails.root/spec/factories/book.rb
Rails.root/spec/factories/books.rb
This is obvious, but this situation happened when I developed under no-git environment(!) and put source files by rsync(1). When I rename book.rb to books.rb from my local PC and rsync to dev-env, both book.rb and books.rb exist and this caused the situation here;-(
When i run my features i get this error:
undefined method `visit' for #<Cucumber::Rails::World:0x81b17ac0> (NoMethodError)
This is the relevant part of my Gemfile.
group :development, :test do
gem "rspec-rails", ">= 2.0.0.beta.19"
gem "cucumber"
gem "cucumber-rails", ">= 0.3.2"
gem 'webrat', ">= 0.7.2.beta.1"
end
The relating step_definition (though i don't think it's important)
When /^I create a movie Caddyshack in the Comendy genre$/ do
visit movies_path
click_link "Add Movie"
fill_in "Title", :with => "Caddyshack"
check "Comedy"
click_button "Save"
end
In the env.rb i have the following Webrat configuration:
# […]
require 'webrat'
require 'webrat/core/matchers'
Webrat.configure do |config|
config.mode = :rails
config.open_error_files = false # Set to true if you want error pages to pop up in the browser
end
# […]
Anything i am missing here?
I had to set config.mode to :rack instead of :rails:
# […]
require 'webrat'
require 'webrat/core/matchers'
Webrat.configure do |config|
config.mode = :rack
config.open_error_files = false # Set to true if you want error pages to pop up in the browser
end
# […]
now works as expected.
Paul Nelligan try adding this to env.rb to fix the error : "no such file to load -- action_controller/integration"
World(Webrat::Methods)
World(Webrat::Matchers)
I also encountered this error on two separate occasions: the first instance the adjustment to confg.mode solved the problem; the second time, however, after a lot of frustration I found a link that suggested a buggy version of bundler could be the culprit. Updating it solved the problem.