EzDevInfo.com

rufus-scheduler

scheduler for Ruby (at, in, cron and every jobs)

How to run schedular at background along with rails app?

I am using Rufus Scheduler to send mail alerts daily at specific time. I have created task_scheduler.rb inside config/initializers.my code is :-

scheduler = Rufus::Scheduler.start_new

 scheduler.cron("0 09 * * *") do
   UserMailer.leave_reminder_email().deliver
 end
end

it works fine when i run "rails s" command. but when i use, "rails server thin -d", it do not work. can anyone please tell me what else is required to make it work? thnks


Source: (StackOverflow)

Best way to not run rufus-scheduler when starting a rails console

I use rufus-scheduler to run some periodic tasks, but they are extremely annoying to have in the rails console when I just want to test things. Is there an easy way to stop all rufus-scheduler tasks when starting a console automatically?

In the code that starts the scheduler if i can check that i am just in a rails console I can not run them, or if there is a way to run some callbacks when the console starts I can also shut them down there.

Thanks


Source: (StackOverflow)

Advertisements

How to get rufus-scheduler working with a Rails app deployed to Heroku?

In ./config/initializers I've created a file called task_scheduler.rb and it contains the following code:

require 'rufus-scheduler'
require 'mechanize'

scheduler = Rufus::Scheduler.new

scheduler.every("1h") do
    puts "Starting Rufus Scheduler - Task 1 - Checking exampleShop for new orders"

    a = Mechanize.new

    a.get('http://exampleshop.nl/admin/') do |page|

        # Select the login form
        login_form = page.forms.first

        # Insert the username and password
        login_form.username = 'username'
        login_form.password = 'password'

        # Submit the login information
        dashboard_page = a.submit(login_form, login_form.buttons.first)

        # Check if the login was successfull
        puts check_1 = dashboard_page.title == 'Dashboard' ?  "CHECK 1 DASHBOARD SUCCESS" : "CHECK 1 DASHBOARD FAIL"

        # Visit the orders index page to scrape some standard information
        orders_page = a.click(dashboard_page.link_with(:text => /Bestellingen/))

        # pp orders_page # => http://pastebin.com/L3zASer6

        # Check if the visit is successful
        puts check_2 = orders_page.title == 'Bestellingen' ?  "CHECK 2 ORDERS SUCCESS" : "CHECK 2 ORDERS FAIL"

        # Search for all #singleOrder table row's and put them in variable all_single_orders
        all_single_orders = orders_page.search("#singleOrder") 

        # Scrape the needed information (the actual save to database is omitted)
        all_single_orders.each do |order|
            # Set links for each order
            order_link = order.at_css("a")['href']  #Assuming first link in row

            @order_id = order.search("#orderId").text                   
            @order_status = order.search("#orderStatus").text       
            @order_revenue = order.search("#orderAmount").text      

            # Visit a single order page to fetch more detailed information
            single_order_page = orders_page.link_with(:href => order_link).click

            @first_name = single_order_page.search(".firstName").text
            @last_name = single_order_page.search(".lastName").text
            @city = single_order_page.search(".city").text
            @postal_code = single_order_page.search(".postalCode").text
            @address = single_order_page.search(".address").text
            @email = single_order_page.search(".email").text
            @order_quantity = single_order_page.search(".orderQuantity").text

            order = Order.create(   order_id: @order_id, first_name: @first_name, last_name: @last_name, city: @city,
                                                        email: @email, postal_code: @postal_code, address: @address, order_quantity: @order_quantity,
                                                        order_revenue: @order_revenue, order_status: @order_status)
        end
    end

    puts "Ending Rufus Scheduler - Task 1 - Checking exampleShop for new orders"
end

The rufus-scheduler works when testing in an development environment. But it stops working when I deploy the app to Heroku (free).

I'm using Phusion Passenger 4.0.27 as the application server.

My Gemfile looks like this:

source 'https://rubygems.org'
ruby '2.0.0'
gem 'rails', '4.0.1'
gem 'rufus-scheduler', '3.0.2'
gem 'pg'
gem 'mechanize'
gem 'bcrypt-ruby', '3.1.2'
gem 'sass-rails', '~> 4.0.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'
gem 'newrelic_rpm'

group :doc do
  gem 'sdoc', require: false
end

group :development do
    gem 'sqlite3'
end

group :production do
    gem 'rails_12factor'
    gem 'passenger'
    gem 'pg'
end

The Procfile required by Phusion Passenger contains the following:

web: bundle exec passenger start -p $PORT --max-pool-size 3

I have no workers running. I'm using one free standard web Dyno.

Any idea why rufus-scheduler is not working while deployed to Heroku?

UPDATE

I know I could create a customer .rake file and use the free Heroku Scheduler add-on to execute the task. But I'm wondering if there's a way to get the rufus-scheduler and free heroku dyno combination to work.


Source: (StackOverflow)

Rufus scheduler in Sinatra

I'm using Rufus scheduler in a Sinatra app. Can I access helper methods from within "scheduler do" block? I didn't manage to do it (I get an "undefined method `check' for main:Object" error) so now I have to define the method inside helpers block (to use it in "post '/' do" block also) and then copy the method's body to scheduler block. It does not make sense:( Is there a way to avoid repetition? Can I define a method somewhere else and call it in scheduler?


Source: (StackOverflow)

Rufus scheduler tasks on heroku running more often than scheduled

I have a Rails app running on heroku with Rufus Scheduler added on.

A 'once a day' task in the scheduler is running more often than once a day.

My guess would be something to do with the heroku app running on different dynos during the day, but I'm at a loss on how to confirm/fix the problem.

Has anyone else seen this/know of a solution?

Edit: I couldn't resolve the problem with the gem and have moved my app over to the heroku scheduler add on which does not experience this problem.


Source: (StackOverflow)

How to implement rufus-scheduler in Rails?

The schedule is running but errors "undefined method 'do_something'". What is not right?

Using rails 3.

In config/initializers/task_scheduler.rb:

require 'rubygems'
require 'rufus/scheduler'  
scheduler = Rufus::Scheduler.start_new
scheduler.every("10s") do
    JobThing.do_something
end

models/job_thing.rb:

class JobThing < ActiveRecord::Base
    def do_something
        puts "something"
    end 
end
Thanks


Source: (StackOverflow)

rufus-scheduler and delayed_job on Heroku: why use a worker dyno?

I'm developing a Rails 3.2.16 app and deploying to a Heroku dev account with one free web dyno and no worker dynos. I'm trying to determine if a (paid) worker dyno is really needed.

The app sends various emails. I use delayed_job_active_record to queue those and send them out.

I also need to check a notification count every minute. For that I'm using rufus-scheduler.

rufus-scheduler seems able to run a background task/thread within a Heroku web dyno.

On the other hand, everything I can find on delayed_job indicates that it requires a separate worker process. Why? If rufus-scheduler can run a daemon within a web dyno, why can't delayed_job do the same?

I've tested the following for running my every-minute task and working off delayed_jobs, and it seems to work within the single Heroku web dyno:

config/initializers/rufus-scheduler.rb

require 'rufus-scheduler'
require 'delayed/command'

s = Rufus::Scheduler.singleton
s.every '1m', :overlap => false do # Every minute
  Rails.logger.info ">> #{Time.now}:  rufus-scheduler task started"
  # Check for pending notifications and queue to delayed_job
  User.send_pending_notifications
  # work off delayed_jobs without a separate worker process
  Delayed::Worker.new.work_off  
end

This seems so obvious that I'm wondering if I'm missing something? Is this an acceptable way to handle the delayed_job queue without the added complexity and expense of a separate worker process?

Update

As @jmettraux points out, Heroku will idle an inactive web dyno after an hour. I haven't set it up yet, but let's assume I'm using one of the various keep-alive methods to keep it from sleeping: Easy way to prevent Heroku idling?.


Source: (StackOverflow)

rufus scheduler run multiple times with unicorn, fixed with :filelock, but how to eliminate the error msg?

scheduler = Rufus::Scheduler.new :lockfile => ".rufus-scheduler.lock"

scheduler.every("60") do
...
end

Environment: Ubuntu, rails 4, rufus, unicorn, nginx

For unicorn has multiple workers, so the above 'every' task will be executed multiple times every 60 seconds.

According to the answer of this one: rufus scheduler running twice each time , I add :lockfile option, it works!

However, from the log, seems the 'every' task will still trying to be called, resulting a lot of error messages:

E, [2014-05-09T01:59:47.496840 #2747] ERROR -- : cannot schedule, scheduler is down or shutting down (Rufus::Scheduler::NotRunningError)
/home/sohmobile/shared/bundle/ruby/2.1.0/gems/rufus-scheduler-3.0.7/lib/rufus/scheduler.rb:605:in `do_schedule'
/home/sohmobile/shared/bundle/ruby/2.1.0/gems/rufus-scheduler-3.0.7/lib/rufus/scheduler.rb:209:in `every'
/home/sohmobile/releases/20140509014407/config/initializers/task_scheduler.rb:3:in `<top (required)>'

How can I solve this issue?

Thanks in advance.


Source: (StackOverflow)

Connection pool issue with ActiveRecord objects in rufus-scheduler

I'm using rufus-scheduler to run a number of frequent jobs that do some various tasks with ActiveRecord objects. If there is any sort of network or postgresql hiccup, even after recovery, all the threads will throw the following error until the process is restarted:

ActiveRecord::ConnectionTimeoutError (could not obtain a database connection within 5 seconds (waited 5.000122687 seconds). The max pool size is currently 5; consider increasing it.

The error can easily be reproduced by restarting postgres. I've tried playing (up to 15) with the pool size, but no luck there.

That leads me to believe the connections are just in a stale state, which I thought would be fixed with the call to clear_stale_cached_connections!.

Is there a more reliable pattern to do this?

The block that is passed is a simple select and update active record call, and happens to matter what the AR object is.

The rufus job:

scheduler.every '5s' do
  db do
    DataFeed.update  #standard AR select/update
  end
end

wrapper:

  def db(&block)
    begin
      ActiveRecord::Base.connection_pool.clear_stale_cached_connections!
      #ActiveRecord::Base.establish_connection    # this didn't help either way
      yield block
    rescue Exception => e
      raise e
    ensure
      ActiveRecord::Base.connection.close if ActiveRecord::Base.connection
      ActiveRecord::Base.clear_active_connections!
    end
  end

Source: (StackOverflow)

Rufus scheduler implementation in rails 3

I have an app running with apache + passenger in production. Currently I initialize the rufus scheduler in a initializer and register jobs reading from a db in that initializer. Way apache/passenger works is that it creates multiple process/instance of the app which causes the scheduler to get initialized multiple times and will schedule duplicate jobs.

What is the correct of implementing this so that the scheduler is a singleton object?


Source: (StackOverflow)

RoR: How to check for a running process with Ruby?

I use a scheduler (Rufus scheduler) to launch a process called "ar_sendmail" (from ARmailer), every minute, like shown below.

The process should NOT be launched when there is already such a process running (in order not to eat up memory...).

Question: How do you check if this process is already running? What goes after the "unless" below?

scheduler = Rufus::Scheduler.start_new

  scheduler.every '1m' do

    unless #[what goes here?]
      fork { exec "ar_sendmail -o" }
      Process.wait
    end

  end

end

Thanks for any solutions for this!

Tom


Source: (StackOverflow)

Simple task scheduling inside of a Rails app

Is there anyway to setup simple task scheduling inside of a rails app? There are pieces of code that I want to run every hour, or every day or every week. I don't want to break them out into separate scripts that I then have to schedule via cron jobs. If I did that, then I'd have to remember to backup the scripts, and if I rebuild a server, I have to go and add back all the cron jobs, it just seems a little bit messy for what I need.

I wish I could just schedule a the jobs somewhere in my rails app and have them magically run when I want them to! Any ideas?


Source: (StackOverflow)

Rake tasks and rails initializers

Kinda new to Rails, so please cope with me. What i'm doing now is background processing some Ruby code use Resque. To get the Rescque rake task started, I've been using (on heroku), I have a resque.rake file with that recommended code to attach into heroku's magical(or strange) threading architecture:

require "resque/tasks"
require 'resque_scheduler/tasks'

task "resque:setup" => :environment do
  ENV['QUEUE'] = '*'
end


desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"

Since I need access to the Rails code, I reference :environment. If I set at least 1 worker dyno in the background on heroku, my Resque does great, gets cleared, everything is happy. Until i try to automate stuff...

So I wanted to evolve the code and automatically fill the queue with relevant tasks every minute or so. Do that (without using cron, because heroku is not adequate with cron), I declare an initializer named task_scheduler.rb that uses Rufus scheduler to run tasks:

scheduler = Rufus::Scheduler.start_new

scheduler.in '5s' do
  autoprocessor_method
end

scheduler.every '1m' do
  autoprocessor_method
end

Things appear to work awesome for a while....then the rake process just stops picking up from the queue unexplainably. The queue just gets larger and larger. Even if i have multiple worker dynos running, they all eventually get tired and stop processing the queue. I'm not sure what I am doing wrong, but I suspect the referencing of the Rails environment in my rake task is causing the task_scheduler.rb code to run again, causing duplicate scheduling. I'm wondering how to solve that problem if someone knows, and I'm also curious if that is the reason for the rake task to stop working.

Thank you


Source: (StackOverflow)

Rufus Scheduler: run every x seconds with first run immediately

I'm using the rufus scheduler to have some tasks execute every so often. I'd like the tasks to all run more or less immediately when the script starts and then at the given interval. This doesn't seem to be supported by API, or am I missing something?

I've resorted to specifying 0.1 seconds as the delay until the first run as follows

scheduler = Rufus::Scheduler.new

scheduler.every '10s', :first_in => 0.1 do
    #do some work
end 

If the :first_in property is set to 0, the scheduler waits the full 10 second before running the first time. If the value is set too low (I suppose to something that evaluates to in the past when it comes to execute the task), or if I use Time.now, the following error is raised:

~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:383:in `first_at=': cannot set first[_at|_in] in the past: 1.0e-07 -> 2014-01-22 10:44:32 +0000 (ArgumentError)
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:445:in `first_at='
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:370:in `initialize'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:457:in `initialize'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler.rb:570:in `new'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler.rb:570:in `do_schedule'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler.rb:207:in `every'
    from rufus_runner.rb:11:in `<main>'

Any idea what the right way is to do this?


Source: (StackOverflow)

JRuby/Rails rufus-scheduler stops working after a heap-space in threadsafe mode

A JRuby/Rails application with a rufus-scheduler job that runs daily. However, when the application runs into a Java Heap Space (Tomcat) the job stops running silently.

This apparently occurs only in Threadsafe mode.

Abstracted config/initializer/update_scheduler.rb

scheduler = Rufus::Scheduler.start_new

#Runs everyday at 7:30 AM - expected after all ETL/MV refreshes are executed
scheduler.cron("30 7 * * *", :tags => 'auto_update') do
  begin
    # do stuff
    Rails.logger.info "log info and duration"
  rescue Exception => s_e
    Rails.logger.error "Scheduler Failed"
  end
  Rails.logger.flush
end

class << scheduler
  def lwarn (&block)
    Rails.logger.error("Scheduler Error: " + block.call)
  end
end

MyApp::Application.config.scheduler = scheduler

Source: (StackOverflow)