I have a delayed job which is implemented as a model method (see below). If I use delayed_job daemon it ran and died silently. Not one job got complete and no logged message was found. But if I use RAILS_ENV=production rake jobs:work everything works OK.
I don't know why, even if an exception is thrown it should appear in the log, but there is none. And if there's something wrong with the logic then why the rake job succeeded?
def recalc(params)
last_known = self
t = nil # target(self)
target_date = self.as_on.yesterday
success = true
saved = -1
# cater for the first one
TimeSlot.where(employee_id:self.employee_id).where('incurred_on >= ?', self.as_on).order('incurred_on ASC').each do |ts|
# loop
if (ts.incurred_on >= target_date) then
if !t.nil? && target_date.day <=7 # roll over to a new month
t.bal_sick += 4 # add 4 days
if t.bal_sick > 40
overflow = t.bal_sick-40
t.bal_sick = 40
t.bal_sick2 += overflow
t.bal_sick2 = 120 if t.bal_sick2 > 120 # overflow again
end
end
unless saved<0
success = t.save
last_known = t
end
if success
saved += 1
t = target(last_known)
target_date = t.as_on
else
logger.warn("Recalc cannot saved a record for #{t.errors.first}")
logger.warn(t.inspect)
return
end
end
if ts.types.include? 'overtime'
t.bal_ot += ts.hours.to_i
t.bal_ot = 100 if t.bal_ot >100
elsif ts.types.include? 'toil'
t.bal_ot -= ts.hours.to_i
elsif ts.types.include? 'vacation'
t.bal_vacation -= ts.hours
elsif ts.types.include? 'sick1'
t.bal_sick -= ts.hours
end
end
logger.info("Recalc saved %d records"% saved)
end
After reading https://github.com/collectiveidea/delayed_job/wiki/Common-problems I found that I've missed out "specify your rails environment", i.e. RAILS_ENV=production bin/delayed_job start, the default environment appears to be development.
But why the default environment is development? It should be production. If I am in development I'd rather do rake jobs:work
Related
Hi I have a rake task which when executed via console work, but doesn't work when rake task is called. Actually it confirms that save occurred, while values aren't updated. Seems like some active record commit is missing, because the only difference in logs I see is begin commit dumps if run (via console), while there isn't such sections in Redmine's debug.log when run as rake task...
Here is it's content:
namespace :redmine do
namespace :myplugin do
desc 'Updates custom field for idle tickets.'
task :update_idle => :environment do
Issue.open.each do |issue|
begin
days = DateTime.now.to_time - DateTime.parse(issue.updated_on.to_s).to_time
days = days/86400
if days > 0
cfv = issue.custom_field_values.detect {|cfv| cfv.custom_field_id == 19 }
cfv.value = days.ceil
if issue.save
puts "#{issue.id} saved"
else
puts "#{issue.id} not saved"
end
end
end
end
end
end
end
The problem with above code is, that it works in Redmine 3.4 both in console, and as Rake task, but in Redmine 4, it only works in console.
Eventually I was able to perform change on issue's custom field on Redmine 4 via Rake task in the following way:
namespace :redmine do
namespace :myplugin do
desc 'Updates custom field for idle tickets.'
task :update_idle => :environment do
Issue.open.each do |issue|
begin
days = DateTime.now.to_time - DateTime.parse(issue.updated_on.to_s).to_time
days = days/86400
if days > 0
issue.custom_values.each do |x|
if x.custom_field_id == 19
x.value = days.ceil
x.save
end
end
issue.save
true
end
end
end
end
end
end
I am trying to set up a custom rake task for a Rails app that checks to see if your location is within a certain area with street cleaning restrictions. If it is, you can click a button "Remind Me" that will save the user id and restriction id to a reminder table.
I have the Rufus gem running the rake task every 15 minutes.
What I then want is the rake task to check the current time and day with the day and start time that corresponds with the restriction id, and if it is within 30 minutes, it should email the user to move their car.
When I run my current code below, I get this error:
rake aborted!
undefined method `reminders' for # <ActiveRecord::Relation::ActiveRecord_Relation_Day:0x007fb38c3274f8>
/Users/m/WDI/park_pointer/lib/tasks/reminder.rake:11:in `block (2 levels) in <top (required)>'
Tasks: TOP => reminder:mail_users
Here's my entire project: https://github.com/mnicole/park_pointer
But the code for the rake task is:
namespace :reminder do
desc "REMINDER"
task :mail_users => :environment do
time = Time.new
t = Time.now
today = Day.where(:id => time.wday + 1) #returns 0 for sunday, etc
#reminders = today.reminders
#reminders.each do |reminder|
#reminder = reminder
reminder_time_in_mins = restriction.start_time.hour * 60
current_time_in_mins = (Time.now.hour * 60) + Time.now.min
# last_time_in_mins = record.last.hour * 60 + record.last.min
if current_time_in_mins > (reminder_time_in_mins - 30)
#user = User.find(reminder.user_id.last)
UserMailer.reminder_email(user_id).deliver!
end
end
end
end
I THINK I'm almost there, but I've been working on this for a few months and am kind of at a loss about the next step.
Thanks in advance!!
-Michele
The problem is with this line:
today = Day.where(:id => time.wday + 1)
This isn't returning records, it's returning an ActiveRecord::Relation, which just means that the query hasn't been evaluated yet. (It does this so you can chain together filters and it only gets evaluated to SQL when you iterate over it.
Without knowing what your Day model looks like, I think what you want is this:
today = Day.where(:id => time.wday + 1).first
This will return the first result, or nil if there were no results. Then if today is non nil, it will have the reminders method.
I am writing a Ruby on Rails application which has a Rake task that can parse a CSV file.
Here is the code:
desc "Import Channels into DB\n Usage: rake channel_import"
task :import_channels, :path_to_channel_list do |t, args|
require "#{Rails.root}/app/models/channel"
require "csv"
filePath = args.path_to_channel_list
puts "Filepath received = #{filePath}"
csv = CSV.read("#{filePath}", :encoding => 'windows-1251:utf-8')
csv.each_with_index do |row, i|
if [0].include?(i)
puts "Skipping over row #{i}"
next
end
if(row.nil?)
puts "row[#{i}] was nil"
else
channelName = nil
classif = nil
owner = nil
channelName = row[0].force_encoding('UTF-8')
classif = row[1].force_encoding('UTF-8')
owner = row[2].force_encoding('UTF-8')
if (channelName.nil?)
puts "Channel name for row #{i} was nil"
#add entry to Log file or errors database
next #skip this row of the csv file and go to next row
else
channel_hash = Hash.new("name" =>"#{channelName}", "classification" => "#{classif}", "owner" => "#{owner}" )
end
puts "\nChannel Name = #{channelName}\nClassification = #{classif}\n Ownership = #{owner}"
#If channel name exists in the Database, update it
xisting_channel = nil
xisting_channel = Channel.find_by channel_name: '#{channelName}'
if(xisting_channel.nil?)
#create a new channel
#new_channel = Channel.create(channel_hash)
puts "Inserted....#{#new_channel.inspect}"
else
#update existing channel
Channel.update(xisting_channel.id, :classification => "#{classif}", :ownership => "#{owner}" )
puts "Updated...."
puts "channel_hash = #{channel_hash.inspect} "
end#end if/else
end#end if/else
end #end CSV.each
end
When I run this code I get the following error message:
MRMIOMP0903:am AM$ rake import_channels[/XXXXXXXX/Channellist.csv]
Filepath received = /XXXXXXX/Channellist.csv
Skipping over row 0
Channel Name = APTN HD+
Classification = Specialty
Ownership = Aboriginal Peoples Television Network
rake aborted!
ActiveRecord::ConnectionNotEstablished
I tried to create a Channel object using IRB and it worked just fine. The DB is created and I'm seeing it using MySQL WorkBench. All tables are there, however, I am unable to create the Channel object from the Rake task.
My hypothesis is, perhaps outside of a certain folder/hierarchy the app cannot access the ActiveRecord::Base class or something like this.
Any suggestions on how to make this work?
UPDATE:
BAsed on the answer by Phillip Hallstrom
I changed the top line to load the environment
task :import_channels => :environment do|t, args|
Then tried rake import_channels and got this error:
rake aborted!
undefined method `safe_constantize' for #<Hash:0x007fbeacd89920>
You need to load the environment prior to running your Rake task. I'm not familiar with your multiple task name options there, but for a simple example, you'd want this:
task : import_channels => :environment do
Can you call a class method from a rakefile (scheduler.rake)?
I am using the Heroku Scheduler add-on and wrote a task that calls a class method but I receive an error when I run 'heroku run rake auto_start_games'
Connecting to database specified by DATABASE_URL
rake aborted!
compared with non class/module
Here is my task code:
task :auto_start_games => :environment do
all_Active_Games = Game.where(:game_active => 1)
not_flag = all_Active_Games > 0
started_games = []
unless all_Active_Games.length == 0
all_Active_Games.each do |x|
if x.players >= 2
x.winning_structure = 1 if x.players < 3
Comments.gameStartComment(x.id)
Game.gameHasStartedPush(x)
x.game_initialized = 1
x.was_recently_initiated = 1
started_games << x.id
else
Game.addDaytoStartandEnd(x.id)
Comment.gamePostponedComment(x.id)
end
end
end
puts "started games #{started_games}"
end
When you invoke Rake, you can pass the --trace flag to it. This should give you a backtrace, which I suspect is going to tell you the error is on the line not_flag = all_Active_Games > 0, because all_Active_Games is an ActiveRecord relation, but you're trying to compare it to the integer 0. Bascially, you have a type error. In a static language, this wouldn't even compile.
It would also be good to also fix your indentation, choose more descriptive variable names (x -> game)
I just acquired the paid version of Heroku's cron, in order to run some tasks every hour. What I would like to know is the syntax I should use to actually get it to run every hour. So far I have this, Could you please tell me if it's correct:
desc "Tasks called by the Heroku cron add-on"
task :cron => :environment do
if Time.now.hour % 1 == 0 # run every sixty minutes?
puts "Updating view counts...."
Video.update_view_counts
puts "Finished....."
puts "Updating video scores...."
VideoPost.update_score_caches
puts "Finished....."
puts "Erasing videos....."
Video.erase_videos!
puts "Finished....."
end
if Time.now.hour == 0 # run at midnight
end
end
I need to know if this line with the 1 in it is the way to go...
if Time.now.hour % 1 == 0
Thanks in advance for your help,
Best Regards.
If you want to run every hour, don't bother checking. Heroku will run it hourly.
Since %1 will always return 0, better to just have:
desc "Tasks called by the Heroku cron add-on"
task :cron => :environment do
puts "Updating view counts...."
Video.update_view_counts
puts "Finished....."
#...
if Time.now.hour == 1 #1am
#...
end
end
Also, if you want to be able to run Video.update_view_counts when you need to, you could instead (after creating the rake task):
Rake::Task["video:update_view_counts"].invoke
That way you can run it inside of cron, and manually if needed
Since, you already have an hourly cron, you don't have to check for the time to run the code.
task :cron => :environment do
#<--- hourly cron begins
puts "Updating view counts...."
Video.update_view_counts
puts "Finished....."
puts "Updating video scores...."
VideoPost.update_score_caches
puts "Finished....."
puts "Erasing videos....."
Video.erase_videos!
puts "Finished....."
#hourly cron ends --->
if Time.now.hour == 0 # run at midnight
end
end