ruby sidekiq `require': cannot load such file -- pg (LoadError) - ruby

I try to build a microservice on pure ruby with some additional features. I use sidekiq for jobs and pg for DB connection.
To start the Sidekiq server I use default settings and code:
# ./config/sidekiq.rb
require 'sidekiq'
require 'pg' # This doesn't work with "`require': cannot load such file -- pg (LoadError)"
require_relative '../jobs/location_jobs/collect_job' # here is my job locates
# If your client is single-threaded, we just need a single connection in our Redis connection pool
Sidekiq.configure_client do |config|
config.redis = { url: 'redis://localhost:6379/0', namespace: 'analytic_serv', size: 5 }
end
# Sidekiq server is multi-threaded so our Redis connection pool size defaults to concurrency (-c)
Sidekiq.configure_server do |config|
config.redis = { url: 'redis://localhost:6379/0', namespace: 'analytic_serv' }
end
As you can see I try require PG gem in sidekiq.rb. Actually I use it in another file and use it here only for example.
So, when I try to run my sidekiq-server it raises an exception
bundle exec sidekiq -r ./config/sidekiq.rb -C ./config/sidekiq.yml
analytic_serv/config/sidekiq.rb:2:in require': cannot load such file -- pg (LoadError)`
it works for the simple ruby script that I use for creating job, but it doesn't work when I run sidekiq-server.
Please, help. What am I doing wrong?
How can I include a gem in this case?

Always use Bundler to make sure your gems are set up correctly: bundle exec ruby script.rb and bundle exec sidekiq

Try adding gem 'pg' to your Gemfile, and install bundle via bundle install.

Cannot load such a file means, the specific file is not available.
Search for path bundle show pg.
Sometimes even if the gem is not there it is shown because of the gemspec. So, remove the gemspec as well and do bundle install.

Related

Bundler and wrong binstubs?

I run rails s or bundle exec rails s and I get this warning:
Bundler is using a binstub that was created for a different gem.
This is deprecated, in future versions you may need to `bundle binstub rails` to work around a system/bundle conflict.
What does this mean? From looking around the bundler site, my understanding of binstubs is that you can set executables to them, so instead of running bundle exec blabla you can just do bin/blabla. So this error is saying my bundler isn't set to the right binstub?
When I run the bundle binstub rails I get this output
rails has no executables, but you may want one from a gem it depends on.
railties has: rails
bundler has: bundle, bundler
I do not understand what my system is trying to tell me, and it's not breaking anything, but I have a hunch this could turn into a bigger issue if I don't fix it
ruby 2.0.0p247
which ruby
/Users/evan/.rvm/rubies/ruby-2.0.0-p247/bin/ruby
which bundler
/Users/evan/.rvm/gems/ruby-2.0.0-p247/bin/bundler
Rails 4.0.2
Edit:
So, if I run the commands in the nag message:
bundle config --delete bin # Turn off Bundler's stub generator
rake rails:update:bin # Use the new Rails 4 executables
I end up getting uninitialized constant Bundler errors with bundle exec commands and the only way I've found to fix that is to rerun bundle install --binstubs which brings back the nag message at the start of this post.
What worked for me was
rm -rf bin/*
Then open a new terminal session and
bundle exec rake app:update:bin
Solution in my case: - Other solutions didn't work for me.
In your Rails directory:
mv /usr/bin/rails /usr/bin/rails.old
bundle config --delete bin
rm -rf bin
# for rails 4.x:
rake rails:update:bin
# for rails 3.x:
bundle install --binstubs
# if you're using rbenv
rbenv rehash
rm -rf ~/.rbenv/plugins/{rbenv-bundle-exec,rbenv-gemset,bundler}
Also be sure that bin/rails is added to the path like:
PATH=./bin:$PATH
Good luck.
This error may raise when you update your ruby but not the related gems.
To check if this is your case, try to make a new rails app in a new empty directory (to be sure RVM is not autoloading any gemset)
make /tmp/test && cd test && rails new test
If this fails stating that it cannot find a suitable 'rails', then simply run
gem update
and overwrite any conflicting rails.
gem uninstall bundler
gem install bundler
Uninstalling all my versions of Bundler, and then installing the latest version fixed it for me. I had multiple versions of bundler installed, so when I ran bundle exec rails s I think the wrong Bundler was used, giving me the warning message.
You may need to generate new stubs after reinstalling Bundler, but I didn't have to.
I was able to fix this by looking at the commit history for bin/rails using git log -p bin/rails
The current, error producing content is:
#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'rails' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path('railties', 'rails')
The original, non-error content was:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
When I restored the original bin/rails content, the warning message disappeared. Previous attempts had returned uninitialized constant Bundler errors on all bundle exec commands, but now they work. It's worth noting that the original content appears to be exactly what rails new blabla generates in rails 4.0.x.
Still, I would like to know why the first code block causes issues because it's exactly what bundle install --binstubs generates.
Edit: turns out this solution does not work. Pushed this fix to a heroku staging server and heroku errors on startup: all bin/rails commands throw uninitialized constant Bundler and heroku starts up with bin/rails server ..... so this is a not really a fix.
Edit2:
If I add these two lines to the second block (the original bin/rails content), all bin/rails commands are working again:
require 'rubygems'
require 'bundler/setup'
My guess is that the second line is what fixes the bundler errors I was having.
Interestingly, when I tried to edit the first block of code in this post to try and debug which line was throwing the warning, any change I made caused all rails commands to failure, with no information except for the nag note in the OP. weird.
Final bin/rails that fixed my issue:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rubygems'
require 'bundler/setup'
require 'rails/commands'
Any additional insight from people who find this would be welcome!

Why do I need bundle exec to require this rubygem?

I have a Rails app with some non-Rails-dependent files under `lib/services'. One of these files uses the Domainatrix gem.
require "domainatrix"
class SuggestionParser
# various suggestion parsing methods
end
I have an empty spec for this file under spec/lib.
require "services/suggestion_parser"
describe SuggestionParser do
end
Unfortunately, when I try to run that spec without bundle exec I hit an error:
$: rspec spec/lib/services/suggestion_parser_spec.rb
-> /Users/davidtuite/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:55:in `require': cannot load such file -- domainatrix (LoadError)
Every other spec and gem in my project will run without using bundle exec. Why do I need to prefix this one in order to get it to run?
For convenience, here's a link to the Domainatrix gemspec.
My guess would be that domainatrix is declared using the :path or :git options in the Gemfile, neither of which install the gem in a way that makes it accessible to rubygems.
This could be confirmed if you post the line for domainatrix from the Gemfile.
try running the following commands:
$ rvm get head && rvm reload
$ chmod +x $rvm_path/hooks/after_cd_bundler
$ bundle install --without production --binstubs=./bundler_stubs
This won't solve the specific problem with your gem, but it will take away the necessity to type in bundle exec every time you run your tests if you're using rvm.

Sinatra + Heroku + Datamapper deploy issues with dm-sqlite-adapter

For some reason, heroku tries to require dm-sqlite-adapter, even though it should use Postgres here. Note, that this happens when I open any URL - not during the git push itself.
I built a default facebook app.
The Gemfile:
source :gemcutter
gem "foreman"
gem "sinatra"
gem "mogli"
gem "json"
gem "httparty"
gem "thin"
gem "data_mapper"
gem "heroku"
group :production do
gem "pg"
gem "dm-postgres-adapter"
end
group :development, :test do
gem "sqlite3"
gem "dm-sqlite-adapter"
end
Datamapper setup:
# Setting up the database
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/data/mydatabase.db")
Relevant log fragment, when any URL is opened:
Starting process with command `bundle exec thin -R config.ru start -p 34984`
2012-01-18T15:11:55+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/dm-core-1.2.0/lib/dm-core/adapters.rb:163:in `require': no such file to load -- dm-sqlite-adapter (LoadError)
2012-01-18T15:11:55+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/dm-core-1.2.0/lib/dm-core/adapters.rb:163:in `load_adapter'
Tried related solutions, but with no help so far.
BTW: bundle install says Using do_postgres and Using dm-postgres-adapter. Am I missing something about Datamapper setup?
Well, too many Rails apps on Heroku, I took the shared db presence for granted. heroku config showed neither DATABASE_URL or SHARED_DATABASE_URL set.
Issuing heroku addons:add shared-database:5mb solved the problem.
Strange, that the db wasn't automatically added, despite having 'pg' gem in Gemfile.
Quote from http://devcenter.heroku.com/articles/cedar:
A Heroku shared PostgreSQL database (shared-database:5mb) will be
automatically added to your app in any of the following cases:
The app is a Rails application
The pg gem is specified in the Gemfile
Try doing DataMapper.setup(:default, ENV['DATABASE_URL'] || 'postgres://user:password#hostname/data/mydatabase.db') instead. Heroku is probably looking at the protocol, and therefore requiring SQLite’s dependencies.

Can I do Sinatra program without restart server?

When I modify the code and have to restart server to see results. Have any way out?
There are a few options, detailed in the Sinatra FAQ. The simplest appears to be to use shotgun, which you can install and invoke as follows:
$ sudo gem install shotgun
$ shotgun myapp.rb
or if you use define your app by inheriting from Sinatra::Base and use a config.ru file:
$ shotgun config.ru -p 4567
If you use Phusion Passenger, you can put this file in the application’s root folder
tmp/always_restart.txt
and it will restart on every request.
http://www.modrails.com/documentation/Users%20guide%20Apache.html ( section 8.7 )
Better way is to use reloader from sinatra-contrib gem (also from Sinatra FAQ): First install sinatra-contrib gem, then ensure your application .rb file starts with these lines:
require 'sinatra'
require 'sinatra/reloader' if development?
And then any modified config files will be reloaded (no need to restart server!)

How to get Sinatra to auto-reload the file after each change?

I am using
# my_app.rb
load 'index.rb'
and start the sever like this
ruby my_app.rb
but it never reload any changes I made in index page.
Did I miss anything here?
See the Sinatra FAQ,
"How do I make my Sinatra app reload on changes?"
First off, in-process code reloading in Ruby is hard and having a
solution that works for every scenario is technically impossible.
Which is why we recommend you to do out-of-process reloading.
First you need to install rerun if you haven’t already:
$ gem install rerun
Now if you start your Sinatra app like this:
$ ruby app.rb
All you have to do for reloading is instead do this:
$ rerun 'ruby app.rb'
If you are for instance using rackup, instead do
the following:
$ rerun 'rackup'
You get the idea.
If you still want in-process reloading, check out Sinatra::Reloader.
gem install sinatra-reloader
require 'sinatra'
require 'sinatra/reloader'
Note: it will reload only sinatra handlers (and, maybe some sinatra server configuration commands), but not custom files, which you have to reload manually.
UPD after 9 years: seems like it is already possible to reload other files using also_reload, dont_reload and after_reload -- https://github.com/sinatra/sinatra/pull/1150
You can use the rerun gem.
gem install rerun
rerun 'ruby app.rb'
OR if you are using rackup
rerun 'rackup'
gem install sinatra-reloader
require 'sinatra/base'
require "sinatra/reloader"
class MyApp < Sinatra::Base
register Sinatra::Reloader
get '/' do
"Hello Testing1!"
end
end
You may want to set environment variable to development and conditionally load the gem.
When you run the application with Passenger Standalone, just create a tmp/always_restart file:
$ touch tmp/always_restart.txt
See Passenger documentation for more info.
I like the Shotgun gem. If you're using a modular Sinatra app and have a config.ru file it's easy to run.
shotgun config.ru
Check the gem out here. It's fairly straight forward and no configuration needed.
On Windows, I am using my restart gem for this:
restart ruby my_app.rb
or, with rackup:
restart rackup
See here for more info, hope you find it useful.
You could use guard-rack. Lifted from an article at dblock.org:
Add this to your Gemfile:
group :development do
gem "guard"
gem "guard-bundler"
gem "guard-rack"
end
Then, create a Guardfile at the root of your project with this content:
guard 'bundler' do
watch('Gemfile')
end
guard 'rack' do
watch('Gemfile.lock')
watch(%r{^(config|app|api)/.*})
end
Lastly, run Guard, like so: bundle exec guard, and rackup will reload every time.
If you only change your templates sinatra will always rerender them if you set your environment to development:
ruby app.rb -e development

Resources