I'm using whenever for schedule of job with sidekiq. Also, use sidekiq-client-cli gem, that is a command line client for sidekiq and allows the cron jobs to interact with sidekiq.
This my active job file :
# jobs/clone_record_job.rb
class CloneRecordJob < ActiveJob::Base
queue_as :myapps
def perform(*args)
Core::Block.where(release_date: Date.today - 30.days).each do |block|
new_block = Core::Block.new(block.attributes)
new_block._id = BSON::ObjectId.new
new_block.save
end
end
end
schedule file :
# config/schedule.rb
job_type :sidekiq, "cd :path && :environment_variable=:environment bundle exec sidekiq-client -q myapps push :task :output"
every 1.minute, :roles => [:app] do
sidekiq "CloneRecordJob"
end
Sidekiq log :
2016-08-09T10:13:41.138Z 23668 TID-xvshg WARN: {"class":"CloneRecordJob","queue":"myapps","args":[],"retry":true,"jid":"98cb26a0dd7410a9be0f0200","created_at":1470737621.1380692,"enqueued_at":1470737621.1382036}
2016-08-09T10:13:41.141Z 23668 TID-xvshg WARN: NoMethodError: undefined method `jid=' for #<CloneRecordJob:0x0000000715cc30>
Note :
I'm sure that job is work when to call from controller.
# example method
def my_action
CloneRecordJob.perform_now
end
CloneRecordJob is an ActiveJob, not a Sidekiq::Worker. You can't use sidekiq-client-cli with ActiveJobs.
Related
I have defined a rake task and a worker job using sidekiq as below. The rake task is not calling the worker job. Please help me find my problem.
Office.rake
namespace :office do
desc "send reminder emails"
task send_reminder: :environment do
Office.all.each do |office|
(office.issues.includes(:billings).where("issues.api_accounts_receivable > 0").select { |issue| (issue.billings.last.date < Message.last.date) if issue.billings.present? }).each do |issue|
puts "Issue ID is #{issue["id"]}"
ReminderWorker.perform_async("#{issue["id"]}")
end
end
end
end
reminder_worker.rb
class ReminderWorker
include Sidekiq::Worker
def perform(issue_id)
puts issue_id
end
end
puts don't show output for issue_id in the terminal for the worker but does show output for "Issue ID is #{issue["id"]}" mentioned in the rake task when I call the rake office:send_reminder from the terminal.
I found my mistake. I didn't turn on the sidekiq server.
The project uses the task scheduler - gem 'clockwork'. Capistrano executes the hook:
after :'deploy:finished', :'clockwork:restart'
The scheduler is triggered once (after this hook), runs all rake tasks, then tasks are not started. No matter how much I put an interval, in a day or 5 minutes, the task does not start anymore. Gem 'daemons' is installed. I will be glad to any help!
UPDATE
require 'clockwork'
require_relative './boot'
require_relative './environment'
module Clockwork
handler do |job|
puts "Running job: #{job}"
end
every(1.minute, 'job:some_task') do
rake_task('job:some_task')
end
def rake_task(task_name)
AppName::Application.load_tasks
Rake::Task[task_name].invoke
end
configure do |config|
config[:sleep_timeout] = 3600 # 1 hour
config[:logger] = Logger.new("#{Rails.root}/log/clockwork.log")
config[:tz] = 'UTC'
config[:max_threads] = 15
config[:thread] = true
end
end
My guess is you're not running clockwork as a daemon, hence why it runs only once. Have a look at this gist
desc "Start clockwork"
task :start, :roles => clockwork_roles, :on_no_matching_servers => :continue do
run "daemon --inherit --name=clockwork --env='#{rails_env}' --output=#{log_file} --pidfile=#{pid_file} -D #{current_path} -- bundle exec clockwork config/clockwork.rb"
end
You could always SSH into your deployment and either check the list of PID or check in your rails application the temporal file that stores clockwork's PID:
.../tmp/pids/clockwork.pid
Alternatively check clockwork's logs:
.../log/clockwork.log
I have a job like this :
class LdapSyncJob < ApplicationJob
queue_as :default
require 'pp'
def perform
users = User.all
users.each do |user|
user.update("Do something")
end
end
end
and I use delayed job for the job processing .
My question is how and where to define my job to be run every night at a specific time ?
Should I call my job in an action or not ? if so how can I do that ?
The delayed job mainly used for processing tasks in queue and in background. It's usually not preferred for scheduling of tasks.
For your use case you should check out whenever a ruby gem, which works with cron jobs to schedule tasks repeatedly.
I would suggest you to move logic or method call LdapSyncJob.perform() to rake task.
In config/schedule.rb, you can do something this way
ENV['RAILS_ENV'] = "#{#pre_set_variables[:environment]}"
env :PATH, ENV['PATH']
require File.expand_path(File.dirname(__FILE__) + "/environment")
set :output, "/logs/cron_log_#{ENV['RAILS_ENV']}.log"
every 1.day, :at => '02:30 am' do
command "cd #{Rails.root}/lib/tasks && rake task_calls_peform_code"
end
Note : Don't forget to update and restart crontab using belong commands.
whenever --update-crontab app --set 'environment=production' #update crontab
service crond restart #restart crontab
I want to use 'whenever' this gem to check my all projects are still not out of deadline. I wrote this code but it didn't work and change status in the database. Can somebody give me some advises. Thank you for helping!
config/schedule.rb
set :environment, :development
every 1.day, at: '11:3 am' do
rake 'project:close_project'
end
app/models/project.rb
def self.close_project(dt)
# 締切日が過ぎているプロジェクトを抽出
Project.where(deadline > dt).each do |project|
# 対象プロジェクトを終了状態に
project.update!(status: 'closed')
end
end
product.rake
namespace :product do
task :close_project => :environment do
Project.close_project(Date.today)
end
end
Whenever creates jobs based on CronJob format. So to run your jobs periodically, you should run whenever command and copy and pasting the results to crontab by running crontab -e or do this task automatically just by running whenever -w.
I have a problem with sidekiq/activejob integration. I have a controller that calls a perform_later method from a MyJob class. This works with the perform method, but when I change to perfom_later, the job is scheduled in my development log. However, when I see the sidekiq dashboard, at the retries section, I can see NameError: uninitialized constant (look below image)
These are my files:
# app/jobs/crime_job.rb
class CrimeJob < ActiveJob::Base
queue_as :default
def perform(crime)
puts "Perform #{crime}"
end
def self.job_name(crime)
"RadarCrime:#{crime.id}"
end
end
Crime Controller
# app/controllers/crime_controller.rb
def show
# [...]
CrimeJob.perform_later(#crime)
end
Sidekiq initializer
# config/initializers/active_job.rb
Rails.application.config.active_job.queue_adapter = :sidekiq
Well, I also open an issue in Sidekiq repository, and the solution is easier than I've think.
Just restart the sidekiq process and it's works fine.
Issue link: https://github.com/mperham/sidekiq/issues/2207