how can I run ruby script for n-occurrences every X-minutes - ruby

I am looking at https://github.com/jmettraux/rufus-scheduler which nicely allows me to schedule and chain events.
But I want the events to stop after, say, the 10th occurrence or after the 24 days.
How do I do this?
My case would be:
run a script which creates the recurring jobs based on intervals and then stops after a given date or occurrence.
This is what I have done.
def run_schedule(url, count, method, interval)
puts "running scheduler"
scheduler = Rufus::Scheduler.new
scheduler.every interval do
binding.pry
attack_loop(url, count, method)
end
end
I am testing my site and want the attack_loop to be scheduled in memory to run against the interval.
But it appears it never hits the binding.pry line.

Normally these schedulers are running via cron jobs. Then the problem with your requirement is cron job doesn't know whether you hit the 10th occurrence or the 24 days as it doesnt keep a track. One possible solution would be to create a separate table to update the cron job details.
I'm thinking a table like,
scheduler_details
- id
- occurrence_count
- created_date
- updated_date
_ scheduler_type
So, now when you run a script, you can create or update the details. (You can search the script by scheduler_type, that way
you can check the number of occurrences
with created date, you can calculate the 24 days
HTH

Good day, you can specify the number of times a job should run:
https://github.com/jmettraux/rufus-scheduler/#times--nb-of-times-before-auto-unscheduling
If you need a more elaborate stop condition, you could do:
scheduler.every interval do |job|
if Time.now > some_max_date
job.unschedule
else
attack_loop(url, count, method)
end
end
But it appears it never hits the binding.pry line.
What has it to do with your issue title? Are you mixing issues?

Related

What is "INTERVAL=0" means in Oracle Schedular?

My Oracle DBA have setup a task with following repeat_interval:
Start Date :"30/JAN/20 08:00AM"
Repeat_interval: "FREQ=DAILY; INTERVAL=0; BYMINUTE=15"
Can I ask what is "Interval=0" means?
Does it means this task will run daily from 8AM, and will repeat every 15 mins until success?
I tried to get the answer from Google, but what I find is what is Interval=1, but nothing for 0.
So would be great if anyone can share me some light here.
Thanks in advance!
INTERVAL is the number of increments of the FREQ value between executions. I believe in this case that a value of 0 or 1 would be the same. The schedule as shown would execute once per day (FREQ=DAILY), at approximately 15 minutes past a random hour (BYMINUTE=15, but BYHOUR and BYSECOND are not set).
Schedule has nothing to do with whether or not the previous execution succeeded or not. Start Date is only the date at which the job was enabled, not when it actually starts processing.
If you want it to run every 15 minutes from the moment you enable it, you should set as follows:
FREQ=MINUTELY; INTERVAL=15
If you want it to run exactly on the quarter hour, then this:
FREQ=MINUTELY; BYMINUTE=0,15,30,45; BYSECOND=0
If you want it to run every day at 8am, then this:
FREQ=DAILY; BYHOUR=8; BYMINUTE=0; BYSECOND=0

Running a cron on start-up using Rufus Scheduler 2.x

I'm trying to run a cron on start-up and then midnight every day from that point.
I'm bound by Dashing to use Rufus Scheduler 2.0.24, in which I can't use 'first_in' with the cron command. The command in 3.x I want to replicate is like so...
scheduler.cron '00 00 * * *', :first_in => '0' do
I'm wondering if there is any way around this?
I found this which describes a similar issue - but this will only run the cron at the first instance of the specified allotted time and not immediately.
a plain way of doing it would be:
job =
proc do
puts "hello"
end
job.call
# run it right now
scheduler.cron('00 00 * * *', &job)
But maybe this one is more readable:
job =
scheduler.cron '00 00 * * *' do
puts 'hello'
end
job.block.call
# run it right now
scheduler.join
Thanks for posting a new question, it made everything clear. The question at Rufus Scheduler :first_in option unknown with cron is a bit different.
I know this is about rufus-scheduler 2.0.24, but I'd like to point to a new feature in 3.3.x: https://github.com/jmettraux/rufus-scheduler/issues/214 where you can do job.trigger_off_schedule and it invokes the job right now if overlap, mutex and other job options allow it.
Back to 2.0.24, the shortcut shown above has no refinement, it will run the block right now. The block might already have an instance running now, imagine you have the schedule set for "midnight every night" and you happen to restart at midnight. Hence, I think the first solution above, is best, because it triggers then schedules.

how do I enable recurring reminders for different users in ruby?

Currently, the users for my app set a specific date and time for a single reminder (using the Chronic gem).
I have a cron job which runs every 10 minutes and checks if the time in the reminder is < Time.now at which point, it sends the reminder and marks that reminder as sent.
However, I want them to be able to specify recurring reminders. The customer should be able to say, "Every other day at 10am".
I can use ice_cube for the recurring part it seems. Then I use Chronic to come up with the start time which will have the day and recurring time.
But I don't have a good way to make it recurring since these are not separate events in the data base.
Here is what I have tried:
```
reminder = response.body['results'] #array of recurring reminders with start_epoch and 'via'
d {reminder}
reminder.count.times do |i|
schedule = IceCube::Schedule.new(now = Time.at(reminder[i]['value']['start_epoch'])) # get the initial start day and time
schedule.add_recurrence_rule(IceCube::Rule.daily) #makes this a daily recurring, but how can I allow this to be customizable?
if schedule.next_occurrence(Chronic.parse('today at 12:01AM')) < Time.now # Check if today's occurence has happened yet
bot_response = BotResponse.get_bot_response(bot_client_id, reminder[i]['value']['bot_input_keyword'])
if reminder[i]['value']['via'] == 'slack'
slack_response = BotMessage.send_slack(reminder[i]['value']['slack_channel'],
bot_response[:bot_response])
d {slack_response}
end #if
end #if
end #do
```
Questions:
Is there a way to tell when a reminder has been sent without writing each specific daily reminder to a database?
Is there a more elegant way for the user in a text string to define the recurrence?
Have you considered trying the whenever gem to implement recurring tasks through cron jobs? I think you should be able to set the schedule times dynamically in the whenever schedule.rb file, see related issue here: Rails - Whenever gem - Dynamic values

Oracle-DBMS jobs scheduler change the start time

I have a DBMS_jobs which is scheduled to run a procedure FINDING_PROCEDURE at 6 am evey day. Can anyone tell me how can i change the start time so that it is scheduled to run at 9 am from tomorrow. Thanks in advance.
As I already mentioned in my comment - your job doesn't run at 6 am every day, it runs every 21 hours.
As a second remark, you should seriously consider switching to DBMS_SCHEDULER - it's so much nicer than DBMS_JOB.
Anyway, to let this job run at 9am every day, this should do the trick:
DBMS_JOB.CHANGE (
job => your_job_id,
interval => 'trunc(sysdate) + 1 + 9/24');
you can use DBMS_JOB.CHANGE() to Alter your job schedule.
Click on this link for complete reference from
Oracle Documentation:DBMS_JOB
and find DBMS_JOB.CHANGE()

Ruby and Rails Async

I need to perform long-running operation in ruby/rails asynchronously.
Googling around one of the options I find is Sidekiq.
class WeeklyReportWorker
include Sidekiq::Worker
def perform(user, product, year = Time.now.year, week = Date.today.cweek)
report = WeeklyReport.build(user, product, year, week)
report.save
end
end
# call WeeklyReportWorker.perform_async('user', 'product')
Everything works great! But there is a problem.
If I keep calling this async method every few seconds, but the actual time heavy operation performs is one minute things won't work.
Let me put it in example.
5.times { WeeklyReportWorker.perform_async('user', 'product') }
Now my heavy operation will be performed 5 times. Optimally it should have performed only once or twice depending on whether execution of first operaton started before 5th async call was made.
Do you have tips how to solve it?
Here's a naive approach. I'm a resque user, maybe sidekiq has something better to offer.
def perform(user, product, year = Time.now.year, week = Date.today.cweek)
# first, make a name for lock key. For example, include all arguments
# there, so that another perform with the same arguments won't do any work
# while the first one is still running
lock_key_name = make_lock_key_name(user, product, year, week)
Sidekiq.redis do |redis| # sidekiq uses redis, let us leverage that
begin
res = redis.incr lock_key_name
return if res != 1 # protection from race condition. Since incr is atomic,
# the very first one will set value to 1. All subsequent
# incrs will return greater values.
# if incr returned not 1, then another copy of this
# operation is already running, so we quit.
# finally, perform your business logic here
report = WeeklyReport.build(user, product, year, week)
report.save
ensure
redis.del lock_key_name # drop lock key, so that operation may run again.
end
end
end
I am not sure I understood your scenario well, but how about looking at this gem:
https://github.com/collectiveidea/delayed_job
So instead of doing:
5.times { WeeklyReportWorker.perform_async('user', 'product') }
You can do:
5.times { WeeklyReportWorker.delay.perform('user', 'product') }
Out of the box, this will make the worker process the second job after the first job, but only if you use the default settings (because by default the worker process is only one).
The gem offers possibilities to:
Put jobs on a queue;
Have different queues for different jobs if that is required;
Have more than one workers to process a queue (for example, you can start 4 workers on a 4-CPU machine for higher efficiency);
Schedule jobs to run at exact times, or after set amount of time after queueing the job. (Or, by default, schedule for immediate background execution).
I hope it can help you as you did to me.

Resources