Where do I enqueue jobs into ActiveJob in Rails 4.2? - ruby-on-rails

I am a beginner when it comes to Rails. I am trying to follow this example:
http://ryanselk.com/2014/09/25/using-background-jobs-in-rails-42-with-active-job/
It says:
"Jobs can be added to the job queue from anywhere. We can add a job to the queue by: ResizeImage.perform_later 'http://example.com/ex.png' "
[UPDATE] Sorry, I am stupid. I came up with this task:
namespace :simple do
# call from command line:
# rake simple:resize_images
desc "Resize images"
task resize_images: :environment do
Dir.foreach('storage') do |next_image|
puts next_image
next if next_image == '.' or next_image == '..'
ResizeImage.perform_later next_image
end
end
end
but now I do:
rake simple:resize_images
and I get:
zacek2_phpP9JGif.jpg
rake aborted!
NameError: uninitialized constant ResizeImage
I've tried:
require ResizeImage
but that did not fix the problem.
I am afraid I don't understand how loading works in Rails. How do I load ResizeImage?

Do I set it up as a cron job?
No.
From the rails guides:
Active Job is a framework for declaring jobs and making them run on a variety of queueing backends.
Active Job is an interface to queueing backends such as sidekiq, delayed_job or resque. It's simply a way for you to write background jobs where you don't have to care about which of the queueing backends will be used.
How do I start ActiveJob?
So ActiveJob doesn't run background jobs on it's own. You're still missing one of the backends. Say you have decided to use delayed_job: Get it installed and then start it via:
script/delayed_job start
I don't understand where "anywhere" is.
That means anywhere in your code, you could write something like:
user.rb
def send_registration_email
UserRegistraionMailJob.perform_later self
end

Related

NoMethodError: undefined method `within' for main:Object

I'm trying to make Capistrano deploy script.
In my Capfile I make sure all rake tasks are included
# Load tasks
Dir.glob('config/capistrano_tasks/*.rake').each { |r| import r }
Next I have a 'migrations.rake' containing:
namespace :fileservice do
task :migrate do
within release_path do
info 'Doing migrations'
execute :php, fetch(:symfony_console_path), 'doctrine:migrations:migrate', '--no-interaction', fetch(:symfony_console_flags)
end
end
end
In my deploy.rb I call the task at the very end with:
after 'deploy:publishing', 'fileservice:migrate'
For some reason I keep getting an error saying:
NoMethodError: undefined method `within' for main:Object
I have no idea where to look or what might be wrong... When googling I get a lot of "NoMethodError" hits but none about the 'within' method and most are general Ruby errors.
Where should "within" be defined? I dat a ruby on rails thing? Or capistrano?
Hopefully someone knows where to start looking or which library / script to include!
UPDATE: I just discovered that none of the methods work. When removing lines I got the same error for "info" and "execute".... So I guess somewhere, something is missing.....
You need to tell Capistrano where (i.e. on what servers) to run your SSH commands. Do this using an on block, as follows:
namespace :fileservice do
task :migrate do
on roles(:db) do
within release_path do
info 'Doing migrations'
execute :php, fetch(:symfony_console_path), 'doctrine:migrations:migrate', '--no-interaction', fetch(:symfony_console_flags)
end
end
end
end
Replace roles(:db) as appropriate for your task, depending on where you want the commands to be run. The expression on roles(:all) do ... end, for example, will run the commands on all servers.
You can also follow the official documentation at http://capistranorb.com, or the Capistrano README, both of which show examples of the task/on/execute syntax.
As you already got the answer but Let me put the bulb from basic.
SSHKit was actually developed and released with Capistrano 3, and it’s basically a lower-level tool that provides methods for connecting and interacting with remote servers; it does all the heavy lifting for Capistrano, in other words.
There are four main methods you need to know about.
on(): specifies the server to run on
within(): specifies the directory path to run in
as(): specifies the user to run as
with(): specifies the environment variables to run with
Typically, you’ll start a task by using an on() method to specify the server on which you want your commands to run. Then you can use any combination of as(), within(), and with() methods, which are repeatable and stackable in any order.
Hope this help you

How to catch errors and send them to Bugsnag when using `rails runner`?

We're running several cron tasks in our server, and we start them all using rails runner, like this:
rails runner 'MyTask.run'
where MyTask is a class in the project. The thing is, we use Bugsnag to handle errors in case anything fails. When we run a rake task, Bugsnag saves the errors and lists them in their website. But this does not happen when using rails runner. How can I configure rails to send errors to Bugsnag when this happens?
Rails runner is very difficult to configure or to customize. That is because all it really is, is a script with this main body:
if code_or_file.nil?
$stderr.puts "Run '#{$0} -h' for help."
exit 1
elsif File.exist?(code_or_file)
$0 = code_or_file
Kernel.load code_or_file
else
eval(code_or_file, binding, __FILE__, __LINE__)
end
As you can see, it just does an eval of the code you sent, so there's no wrapper, no class you can extend, and basically nothing you can configure. It is better to create a rake task to perform things the same way as runner, but this time in an environment that will be controlled by Rake, therefore allowing you to configure everything you need:
desc 'Wraps a runner command with rake'
task :runner, [:command] => :environment do |t, args|
eval(args[:command])
end
Then, you call it using
rake 'runner["MyTask.run"]'
This will run the tasks in a very similar way to using rails runner, but in the context of rake (which will include using Bugsnag).

Resque workers failing silently with no logs or no debug information

I have a piece of code code which runs some method and I have put that method inside the self.perform as below
class StartWorker
#queue = :worker
def self.perform
puts "hello"
Parser.find_all_by_class_name("Parser").first.sites.each do |s|
site = Site.find(s.id)
parser = Parser.new(site)
parser.run
end
end
end
If I comment the def self.perform and end of this and run the file it is correctly showing the desired results but when I try to put this as a background task by uncommenting the same It is failing silently into the resque panel showing nothing .and also with no outputs in the command prompt
I am queuing this from resque-scheduler, inside my resque_schedule.yml
start_worker:
cron: "55 6 * * *"
class: StartWorker
queue: worker
args:
description: "This job starts all the worker jobs"
I tried putting some simple puts statements inside the the def self.perform method to check whether the control is passing inside the method or not but it seems the control is not even passing inside the self.perform method
also I tried to load the rails environment and required resque inside it but of no use
I have runned the bundle exec rake resque:work QUEUE='*' script for all the above before making any changes
I tried Resque.info inside the rails console it is showing like this ,
{:working=>0, :queues=>1, :failed=>1, :environment=>"development", :servers=>["redis://localhost:6379/0"], :pending=>0, :processed=>1, :workers=>1}
Any Ideas how to overcome this?
Have you checked the resque-web panel to see what that failed job is?
Make sure you restart workers after any changes.
If you're not seeing 'hello' in your logs anywhere (specifically log/worker.log or where ever yours log to) then the function simply isn't happening.
bundle exec rake resque:work QUEUE='*' should be bundle exec rake resque:work QUEUE=*
, just incase you really did quote the wildcard.
Worked for me:
Resque::Scheduler.configure do |c|
c.verbose = Rails.env.development? # or just true
end
Ruby: 3.0.3,
Resque: 2.2.0,
Resque-Scheduler 4.5.0,
Rails: 6.1.4.4

Rails how to create a delayed job for a rake taks?

How do I create a delayed job for a rake task that should run every 15 minutes?
You can give it a try: https://github.com/defunkt/resque
I am using Resque + Redis with Heroku. Delayed job is also very much supported on their cloud service.
In lib/tasks/cron.rb
desc "This task is called by the Heroku cron add-on"
task :cron => :environment do
def resubmit_pending_jobs
Resque.enqueue(SomeJob, job.id)
end
end
One way I can think of is by using the cron addon offered by Heroku which does it every hour (not 15 mins). Perhaps the above code block can assist you in finding a similar implementation for Delayed Job.
In the case you are interested in getting Resque setup with RedisToGo and Heroku, please consult this guide.
Hope that helps!
Take a look at SimpleWorker. It's a cloud-based background processing / worker queue for Ruby apps. It's an add-on for Heroku.
You create worker classes in your code and the queue up jobs to run right away or run later -- one time or on a recurring schedule.
worker = SomeWorker.new
# Set attributes for worker to use here
worker.schedule(:start_at => 1.minute, :run_every => 900)

Vlad the Deployer - Usage Patterns?

I'm starting to use vlad for new deployments and am wondering what's the best way to set it up so I can use the same tasks for my local development and remote production servers?
I thought about defining everything as remote tasks then having dev/prod methods which set the domain variable, then I can just call rake dev/prod vlad:do_something, but this just feels totally wrong.
Many of my tasks are useful to run on my local server and on my production server and I want to avoid repeating myself by having one 'task' for local and one 'remote_task' for remote. e.g.
def do_something
run "echo something"
end
task :do_something_dev
do_something
end
remote_task do_something_prod
do_something
end
Am I missing something or are these really the only options for using the same rake tasks on both the local and remote machine?
How about this:
[:development, :test, :production].each do |environment|
namespace environment do
task :do_something do
echo "do something on #{environment}"
end
end
end
This will give you:
rake vlad:development:do_something
rake vlad:test:do_something
rake vlad:production:do_something
With just one method it is probably less verbose to do it your way. But as soon as you have 2 or three methods, the overhead can be neglected.

Resources