I want to execute a cron after creation of some entity every 2 minutes and I should be able to stop it through code only. Is it possible ?
For the simplest way that I can think of right now that you can do what #tlehman said and add a "checking flag" in the code. (maybe just a simple variable inside a filename)
so before the cron started, it should check for a file with X variable with value true/false.
if true then it should run the code, if false then exit.
(you could then write another code to modify that "check file" to enable/disable the cron)
That sounds like a job for the whenever gem, you can use it's simple DSL like so:
every 2.minutes do
runner "SomeRubyCommand.do_work"
end
Related
Of course it is unusual for rake tasks to be triggered by a controller (and kind of kludgey) but very common for them to be triggered by cron. I would like to detect from within a rake task whether it was started manually on the command line, or not.
How can I do that? This is a pretty standard thing to do in a shell script, but I'm unable to find any documentation about how to do it with a rake task.
Why the hate? People are downgrading this simply because they don't know the answer? 🤦🏼♂️
Here's a stab I took.
I tested this in both CL and Rails Console. I also tacked an invocation at the end of Application.rb to double check. But I haven't tested it in all the many other ways one might, so people should use this only with caution.
Likewise, I'm not certain that index 7 will be universal.
But I'm pretty sure it's accomplishable if you really want it.
task who_called: :environment do
puts case caller_locations[7].label
when "<main>" then :rails
when "invoke_task" then :cli
else
raise "unknown caller: #{location}"
end
end
Another suggestion is to always invoke the task with an ENV variable or an argument. You can assume that nil defaults to the command line, so people don't have to type unnecessary arguments.
Try this:
if defined?(Rails::Console)
....
end
Or you can check what caller[0] returns when you call from the cmd and use that in the if instead.
I am creating an automatic raffling system. I have a draw button that will run a draw function to select a winner or winners and it sends an email to the admin.
I want this to be a completely automated system so that the admin only has to create the raffles and they receive an email with who won after the draw date has passed. My raffles have a draw date associated with them and once that passes, I need the function to be called.
How do I tell the application to check the time/date to see if any of the raffle draw times have passed? I have looked everywhere and cannot seem to find a way to do it.
You could use the whenever gem to define a job that runs hourly (or however often you want), checks the draw dates, and runs the draw for any that have passed.
I use Clockwork in my rails apps whenever I need to schedule things. Simply set it up to run a job when you want and do your logic within that job to see which raffles need to be processed. Example:
Clockwork config
every(1.day, 'Raffle::CheckJob', at: '01:00')
Job
Raffle.not_complete.find_each(batch_size: 10) do |raffle|
if raffle.has_ended?
// logic
end
end
You should write a rake task and add it's execution to your crontab on server. You can use whenever gem to simplify crontab scripting and auto update on each deploy (whenever-capistrano/whenever-mina). Example of your rake task:
namespace :raffle do
task :check do
Raffle.get_winners.each do |w|
Mailer.send_win_mail(w).deliver_later
end
end
end
deliver_later is background execution in queue by the queue driver you use (DelayedJob/Rescue/Backburner etc)
I have a process which I am monitoring using Monit. If process dies for some reason, I want to send a Slack notification using a shell script and also restart it. This behaviour though does not work with "does not exist" directive. The last one is executed and previous one ignored. For example code below:
check process xyz with pidfile /var/run/xyz.pid
start program = "/etc/init.d/xyz start" with timeout 60 seconds
stop program = "/etc/init.d/xyz stop"
if does not exist then restart
if does not exist then exec "/opt/somescript.sh"
It executes script but does not restart. it also looks like from documentation that this is how it will behave. Any other way to get this working. Documentation reference (Not exactly clear but resembles the actual behaviour):
If not defined, it defaults to a restart action.
You can override the default action with the following statement:
I believe monit doesn't allow you to have the same statements twice. You would have to write your script on restarting the process in your somescript.sh.
My guess is the default action is already to restart the process, as per the documentation, and you are overriding that with an exec action
Cleaner way is to add the restart script inside your somescript.sh.
If you don't want to do that, you can also combine the two actions in one, like this:
if does not exist then exec "/etc/init.d/xyz restart && /opt/somescript.sh"
I'm testing whenever to figure out how to use it and am running into trouble even after reading the Github documentation.
I simply want to update the attributes of my model like this (config/schedule.rb)
set :output "/log/today.log"
every 10.seconds do
runner "Example.update_all(sample: Time.now)"
end
I am neither seeing a log file nor seeing the model attributes updated.
Is there anything I am not doing correctly?
First you need to add your cron job in the cron tab.
If you do not want to add because you are just testing it, you can try the code given below(which i did for my rails application).
cd /home/your_home/your_project && script/your_script -e <environment> "method_call"
In your case:
environment = development
method_call = Example.update_all(sample: Time.now)
It might help you.
I'm very new to rails and I have a script that I run from the console like this
$ ruby axml2xml.rb ExamPaper.apk
Now, how do I call this script from within my controller method and pass the same parameter as ExamPaper.apk?
I tried require 'axml2xml.rb' but got some error pointing to this line of code Zip::ZipFile.foreach(ARGV[0]) do |f|. So basically, how do I make something like axml2xml.rb 'ExamPaper.apk' in my controller?
You have at least 3 options:
exec(command)
%x{ command }
system(command)
They have different behaviors, so make sure to read this quicktip and/or the answer of this question to learn more about these commands.
In your case, the backticks or %x command is probably the best option.
value = `ruby axml2xml.rb ExamPaper.apk`
You can try using system or popen, but only for short tasks, for more information about that, please see here.
If your task is more time consuming you definitely should have a look at something like delayed_job and use a background job or some sort of queue to run your job. This way your server doesn't get blocked and your users do not have to wait til your job completes.
If you want to execute it as a shell command, use:
exec 'ruby axml2xml.rb ExamPaper.apk'
In ruby there are several ways to run shell commands.
system("ls")
%x("ls")
`ls` #nice they are back ticks
exec "ls"
But I'm not sure about the permissions necessary for running commands like that via rails.