How do I use Rails clockwork gem to run rake tasks? - ruby-on-rails

What is the syntax for calling rake tasks from clockwork? I've tried all kinds of syntax, and nothing seems to work. (I'm specifically interested in clockwork because Heroku's supporting it.)
Here's my clock.rb, using the same syntax that the whenever gem uses:
module Clockwork
puts "testing clockwork!"
every(30.seconds, 'Send Messages') {
rake 'scheduler:send_messages'
}
end
And here's my rake task in scheduler.rake:
task :send_messages => :environment do
puts "rake task run successfully!"
end
And here's what happens when I start a clockwork process:
$ clockwork lib/clock.rb
testing clockwork!
I, [2012-07-16T14:42:58.107245 #46427] INFO -- : Starting clock for 1 events: [ Send Messages ]
I, [2012-07-16T14:42:58.107364 #46427] INFO -- : Triggering 'Send Messages'
attempting to run rake task!
E, [2012-07-16T14:42:58.107437 #46427] ERROR -- : undefined method `rake' for Clockwork:Module (NoMethodError)
This runs every 30 seconds. As you can see, the clock.rb is executed successfully. But I can't for the life of me figure out the syntax to run a rake task. The clockwork readme is no help, unfortunately:
https://github.com/tomykaira/clockwork

rake is not a method, so you can't invoke it like that here.
You can either shell out and invoke it, something like
every(30.seconds, 'Send Messages') {
`rake scheduler:send_messages`
}
or rather invoke a new detached process using the heroku API. This is my preferred method right now:
Heroku::API.new.post_ps('your-app', 'rake scheduler:send_messages')
Heroku::API is available from heroku.rb: https://github.com/heroku/heroku.rb

You can add the following method to your clock.rb file:
def execute_rake(file,task)
require 'rake'
rake = Rake::Application.new
Rake.application = rake
Rake::Task.define_task(:environment)
load "#{Rails.root}/lib/tasks/#{file}"
rake[task].invoke
end
and then call
execute_rake("your_rake_file.rake","your:rake:task")
in your handler

You can pass in a block to every that executes your rake task:
every(1.day, "namespace:task") do
ApplicationName::Application.load_tasks
Rake::Task['namespace:task'].invoke
end

Invoking the task using Rake::Task['...'].invoke works well the first time, but the task need to be reenabled to be invoked again later.
ApplicationName::Application.load_tasks
module Clockwork do
every(10.minutes, "namespace:task") do
Rake::Task['namespace:task'].invoke
Rake::Task['namespace:task'].reenable
end
end
Otherwise the task will be invoked the first time, but no more after that until the clockwork process is restarted.

Related

Rails 5 - Resque not processing enqueued job

I'm trying to do enqueue a simple job using Resque 1.26.0 (and Redis-rb 3.3.1). The job doesn't seem to be processing the perform function because resque-web is processing each job and shows 0 failures. The jobs also are being processed instantly.
The jobs are enqueued from a controller action with
Resque.enqueue(TestJob, url)
The job itself looks like
class TestJob < ApplicationJob
#queue = :tags_queue
Logger.new("log/resque_worker_QUEUE.log").fatal("thing")
def self.perform(url)
Logger.new("log/resque_worker_QUEUE.log").fatal("other thing")
logger.fatal("more errors please")
myDivideByZeroVar= 1/0
raise "error"
Logger.new("log/resque_worker_QUEUE.log").fatal("other thing")
logger.fatal("more errors please")
end
end
A rake task is also set up:
require 'resque/tasks'
task "resque:setup" => :environment
The redis-server is running.
The worker is started with rake resque:work QUEUE=*. Using verbose logging doesn't show anything useful.
The log file only shows the first fatal error string "thing". None of the other errors are logged that are inside perform.
What am I doing wrong here?
Solved this. The job needed to be called using ActiveJob instead of using Resque.enqueue. TestJob.perform_later(url) worked just fine.

rake aborted! Don't know how to build task 'sandbox'

I'm trying to add the sandbox to my rails spree application and have run into this error
(using windows 8/powershell with Rails 4.1.6). I'm going by this manual: https://github.com/spree/spree/issues/411
This link Use older version of Rake
seems to have a similar issue but I am not sure how to take the necessary steps to achieve it.
When I try:
C:\Ruby193\openUpShop> bundle exec rake sandbox
I get:
rake aborted!
Don't know how to build task 'sandbox'
I'm am new to rails and am still not sure how everything works so a throughout explanation
with step by step instructions would be greatly appreciated! Thanks.
you can use a file sandbox.rb
# use example: rake task:sub_task -- --sandbox
if ARGV.any? {|arg| arg == '--sandbox' }
puts "** << USING SANDBOX!! >> **"
# beginning
$sandbox = -> do
ActiveRecord::Base.connection.begin_transaction
end
# end
at_exit do
ActiveRecord::Base.connection.rollback_transaction
end
end
then only you need add at the beginning of your task.rake file
require_relative 'path_to_your/sandbox.rb'
..and add at the beggining of your task code
desc "description task"
task example_task: :environment do
$sandbox.call if $sandbox.present?
...

Rake task working on local machine, not on heroku

Here is my simple rake task :
desc 'Create objects from csv'
task :add_missing_information_from_url, [:url] => [:environment] do |t, args|
url = args[:url]
puts "STARTED"
CSV.new(open(url), :headers => :first_row).to_enum.with_index(1).each do |line, i|
user = User.find(line['id'])
next if user.nil?
user.flag = true
user.save
puts "#{i} - #{user.firstname}"
end
end
For starters doesn't do anything smart. But for some reason this doesn't work on Heroku. This is how I execute the task (my namespace is dbs):
heroku run rake dbs:add_missing_information_from_url['http://lvh.me/file.csv']
Or on dev machine :
bundle exec rake dbs:add_missing_information_from_url['http://lvh.me/file.csv']
This is the only output I get from the console when running heroku task :
Running `rake dbs:add_missing_information_from_url[http://lvh.me/file.csv]` attached to terminal... up, run.7246
And returns to my shell after it has executed with nothing printed, nor the user objects get saved.
However when I run it on my dev machine, all works fine, starting by printing STARTED onwards.
What am I doing wrong here?
Is it me or does your log actually outputs this :
Running `rake dbs:add_missing_information_from_url[http://lvh.me/file.csv]` attached to terminal... up, run.7246
If you take a closer look at the argument in the [http://lvh.me/file.csv], it appears not to be a string. You would want your log to output ['http://lvh.me/file.csv'].
So I suggest you try running your task like this :
heroku run rake dbs:add_missing_information_from_url['"http://lvh.me/file.csv"']

Custom Rails rake task to work with database

I need to make a custom Rails 4 rake task to delete all records in database using ip:
task :delete_records, [:ip] => :environment do |t, args|
User.destroy_all(ip: args.ip)
end
I try to execute it using the following command:
bundle exec rake delete_records["127.0.0.1"] but I've the error:
no matches found: delete_records["127.0.0.1"]
How can I fix it? Thank in advance!
I'm guessing you used this answer for help - although we've done rake tasks before, we've never used one with arguments like this
--
Test
We've created custom rake tasks before - they reside in lib/tasks
I would test out yours by doing the following:
#lib/tasks/your_task.rake
desc "Remove all records for particular IP"
task :delete_records, [:id] => :environment do
args.with_defaults(:ip => "127.0.0.1")
User.destroy_all ip: args.ip
end
If this does not work, it will mean there's something wrong with the definition of your task (it's not in the correct folder or something)
The above should determine if your argument definition is the issue; if it isn't you should let me know so we can work to fix it

How do I pass environmental variables to a Rake task invoked from another Rake task?

I have three Rake tasks invoked from another Rake task. The first Rake task requires that an environmental variable is set before it is executed.
The following works, however it means that I lose all the output from the task which is critical:
namespace :deploy do
task :staging => :environment do
`EXAMPLE=something rake db:rebuild`
Rake::Task["rake envs:push:staging"].invoke
Rake::Task["rake app:push:staging"].invoke
end
end
How can I invoke the first task with the environmental variable AND display its output to the terminal?
ENV['EXAMPLE'] = 'something'
Rake::Task['db:rebuild'].invoke
Use system instead of back-ticks:
system("EXAMPLE=something rake db:rebuild")

Resources