Load resque worker without rails environment? - ruby-on-rails

The resque jobs I have do not depend on anything in Rails, but I'm having a hard time starting workers without the rails env. I've seen this post, but it didn't help (ruby resque without loading rails environment)
Here is my current rake file:
require "resque/tasks"
task "resque:setup" do
root_path = "#{File.dirname(__FILE__)}/../.."
require "#{root_path}/app/workers/myworker.rb"
end
#task "resque:setup" => :environment
The commented task would load the Rails env and everything works, but that's not what I want. When running rake resque:work I get this error:
rake aborted!
No such file to load -- application_controller
Tasks: TOP => resque:work => resque:preload

If you've only added a lib/tasks/resque.rake file and haven't modified your Rakefile, you'll still be loading your Rails environment when you call rake resque:work. Try this for Rakefile:
unless ENV['RESQUE_WORKER'] == 'true'
require File.expand_path('../config/application', __FILE__)
My::Application.load_tasks
else
ROOT_PATH = File.expand_path("..", __FILE__)
load File.join(ROOT_PATH, 'lib/tasks/resque.rake')
end
And then this for your resque.rake file:
require "resque/tasks"
task "resque:setup" do
raise "Please set your RESQUE_WORKER variable to true" unless ENV['RESQUE_WORKER'] == "true"
root_path = "#{File.dirname(__FILE__)}/../.."
require "#{root_path}/app/workers/myworker.rb"
end
Then call rake resque:work RESQUE_WORKER=true

I referred the link here It worked perfectly for me:
This error was resolved, by running
$> QUEUE=* rake environment resque:work
a cleaner solution was to define a rake task:
task "resque:setup" => :environment do
ENV['QUEUE'] ||= '*'
#for redistogo on heroku http://stackoverflow.com/questions/2611747/rails-resque-workers-fail-with-pgerror-server-closed-the-connection-unexpectedl
Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection }
end
and now
rake resque:work
Worked perfectly
Thanks.

Related

How to fix "uninitialized constant" in a Rake task

I have a problem when I do:
namespace :xaaron do
task :get_roles do
roles = Xaaron::Role.all
puts roles
end
task :get_role, [:name] do |t, args|
role = Xaaron::Role.find(args[:name].parameterize)
puts role
end
end
The first task will work fine. I can even add binding.pry and run Xaaron::Role and get information about Roles back. But the second task fails with:
NameError: uninitialized constant Xaaron::Role
I run each task in my main app because these tasks are inside an engine, using:
bin/rake xaaron:get_roles` and `bin/rake xaaron:get_role
I can run bin/rails c in the main application that uses the engine and run Xaaron::Role and get information about Roles table.
Why is the second one failing but the first one is not? Is there scoping with arguments?
I'm not sure why either works, but if this is Rails and those are Rails models, your tasks should depend on the environment:
task :get_roles => [ :environment ] do
By depending on the :environment task, it first loads Rails.
Also see: What's the 'environment' task in Rake?.
You can also run a Rake task as
bundle exec rake environment xaaron:get_role
This will load the Rails environment first.
I kept getting uninitialized constant errors for a Rake task, even after depending on :environment and running with bundle exec.
The issue was that I was making a Rake::TestTask and, even though the Rake task had access to all constants, the test files themselves did not have access to constants.
The solution was to add this line to the top of my test file:
require_relative '../config/environment'
This is the Rake task:
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList["test/**/test_*.rb"]
end
To add, as of Ruby 1.9 and above, you can use this hash syntax:
namespace :xaaron do
desc "Rake task to get roles"
task get_roles: :environment do
roles = Xaaron::Role.all
puts roles
end
#####
end
And then you can run the command below to run the Rake task:
rake xaaron:get_roles
or
bundle exec rake xaaron:get_roles

Rails.cache.clear fails with undefined method `clear' for nil:NilClass when running in a rake task

Upon following the instructions to create a rake task to clear the cache, when running that rake task:
namespace :cache do
desc "Clears Rails cache"
task :clear do
Rails.cache.clear
end
end
and running that rake task with:
rake cache:clear
I get an error:
undefined method `clear' for nil:NilClass
When running Rails.cache.clear from the rails console, it successfully clears the cache without an error. Why is cache nil on the Rails object in the rake task, but not in the rails console?
Note: I am using dalli and memcache.
To answer Why is => :environment needed?
:environment is a task defined by rails.
When you need to interact with your application models, perform database queries and so on, your custom task should depend on the environment task, as it will load your rails application code.
Rails.cache will return nil if your application is not loaded.
Hence, the error undefined method 'clear' for nil:NilClass
You need to run environment task before your custom clear task.
namespace :cache do
desc "Clears Rails cache"
task :clear => :environment do ## This will run environment task first and then clear task
Rails.cache.clear
end
end
Figured it out. I was missing => :environment after :clear
The below works:
namespace :cache do
desc "Clears Rails cache"
task :clear => :environment do
Rails.cache.clear
end
end
Why is => :environment needed?

rufus-scheduler fails with rake tasks (Don't know how to build task)

I'm using Rails3 (Windows, Ruby 1.8.7) with rufus-scheduler gem. Gem works fine, but if I'm trying to run some standard rake task, error occurs:
Don't know how to build task 'db:version' # ofc, db:version is just example
Terminal command
rake -T
works
If I'm trying to define own simple rake commands, they works fine too:
# /lib/my_scheduler.rb
require 'rubygems'
require 'rake'
require 'rufus/scheduler'
load File.join( Rails.root, 'lib', 'tasks', 'my_own_tasks.rake')
scheduler = Rufus::Scheduler.start_new
scheduler.every '5s' do
Rake::Task["my_own_namespace:test"].invoke
end
end
# /lib/tasks/my_own_tasks.rb
namespace :my_own_namespace do
task :test do
puts "Some scheduler task"
end
end
... but using standard rake tasks *in my_own_tasks* throws the same error.
Some help would be appreciated
PS. I'm newbie, so sorry, if that was dumb question
Maybe someone will need solution:
system("rake namespace:task")
f.e:
system("rake db:version")

Adding a COUNT option to my resque.rake file

I have an existing resque.rake file that lets me run heroku rake jobs:work to spawn a resque worker. Here is the file:
require 'resque/tasks'
task "resque:setup" => :environment do
ENV['QUEUE'] = '*'
end
desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"
Now I want to add a specified number of workers by adding the COUNT=X option, but I am unsure where and how to add it to my rake file. How should I do this?
I would thing you could just add another ENV[] key/value:
task "resque:setup" => :environment do
ENV['QUEUE'] = '*'
ENV['COUNT'] = 5
end

how to get access ENV variables from within resque jobs

How do I make sure resque has access to all my ENV variables? I'm trying to send an email from within a resque job and it cannot send because the actionmailer smtp username/pass are set via ENV variables. It looks like even ENV['RAILS_ENV'] is not available from within the resque job.
Here's my resque.rake file:
# Run to start:
# rake resque:work QUEUE='*'
require 'resque/tasks'
require 'resque_scheduler/tasks'
task "resque:setup" => :environment do
require 'resque'
require 'resque_scheduler'
require 'resque/scheduler'
Resque.schedule = YAML.load_file("#{Rails.root}/config/resque_schedule.yml")
end
Here's my resque.rb initializer:
require 'resque_scheduler'
Resque.redis = 'localhost:6379'
Dir["#{Rails.root}/app/jobs/*.rb"].each { |file| require file }
Here's my procfile that starts redis/resque/resque worker
mongo: mongod
redis-server: redis-server /usr/local/etc/redis.conf
scheduler: bundle exec rake resque:scheduler
worker: bundle exec rake resque:work QUEUE=images, notifications
Add them to resque.rake
task "resque:setup" => :environment do
# ... other stuff
ENV['RAILS_ENV'] = Rails.env
end
Well I can't tell for sure but if this is UNIX, open /proc/self/environ will work even if there's no language facility to read ENV.
This is, of course, last resort.

Resources