Git Product home page Git Product logo

crono's Introduction

Job scheduler for Rails

Gem Version

Crono is a time-based background job scheduler daemon (just like Cron) for Ruby on Rails.

The Purpose

Currently, there is no such thing as Ruby Cron for Rails. Well, there's Whenever but it works on top of Unix Cron, so you can't manage it from Ruby. Crono is pure Ruby. It doesn't use Unix Cron and other platform-dependent things. So you can use it on all platforms supported by Ruby. It persists job states to your database using Active Record. You have full control of jobs performing process. It's Ruby, so you can understand and modify it to fit your needs.

Web UI

Installation

Add the following line to your application's Gemfile:

gem 'crono'

Run the bundle command to install it.
After you install Crono, you can run the generator:

rails generate crono:install

It will create a configuration file config/cronotab.rb and migration
Run the migration:

rake db:migrate

Now you are ready to move forward to create a job and schedule it.

Compatibility

  • Crono v1.1.2 and older are compatible with Ruby 2.7.x and older
  • Crono v2.0.0 and newer are compatible with Ruby 2.7.x and newer

Usage

The basic usage

You can specify a simple job by editing config/cronotab.rb:

# config/cronotab.rb
class TestJob
  def perform
    puts 'Test!'
  end
end

Crono.perform(TestJob).every 5.seconds

Then, run a crono process:

bundle exec crono -e development

Job Schedule

Schedule list is defined in the file config/cronotab.rb, that created using rake crono:install. The semantic is pretty straightforward:

# config/cronotab.rb
Crono.perform(TestJob).every 2.days, at: {hour: 15, min: 30}
Crono.perform(TestJob).every 1.week, on: :monday, at: "15:30"

You can schedule one job a few times if you want the job to be performed a few times a day or a week:

Crono.perform(TestJob).every 1.week, on: :monday
Crono.perform(TestJob).every 1.week, on: :thursday

The at can be a Hash:

Crono.perform(TestJob).every 1.day, at: {hour: 12, min: 15}

You can schedule a job with arguments, which can contain objects that can be serialized using JSON.generate

Crono.perform(TestJob, 'some', 'args').every 1.day, at: {hour: 12, min: 15}

You can set some options that not passed to the job but affect how the job will be treated by Crono. For example, you can set to truncate job logs (which stored in the database) to a certain number of records:

Crono.perform(TestJob).with_options(truncate_log: 100).every 1.week, on: :monday

Job classes

Crono can use Active Job jobs from app/jobs/. Here's an example of a job:

# app/jobs/test_job.rb
class TestJob < ActiveJob::Base
  def perform(options)
    # put you scheduled code here
    # Comments.deleted.clean_up...
  end
end

The ActiveJob jobs are convenient because you can use one job in both periodic and enqueued ways. But Active Job is not required. Any class can be used as a crono job if it implements a method perform:

class TestJob # This is not an Active Job job, but pretty legal Crono job.
  def perform(*args)
    # put you scheduled code here
    # Comments.deleted.clean_up...
  end
end

Run rake tasks

Here's an example of a Rake Task within a job:

# config/cronotab.rb
require 'rake'

Rails.app_class.load_tasks

class Test
  def perform
    Rake::Task['crono:hello'].execute
  end
end

Crono.perform(Test).every 5.seconds

With the rake task of:

# lib/tasks/test.rake
namespace :crono do
  desc 'Update all tables'
  task :hello => :environment do
    puts "hello"
  end
end

Please note that crono uses threads, so your code should be thread-safe

Run crono

Run crono in your Rails project root directory:

bundle exec crono -e development

Usage:

Usage: crono [options] [start|stop|restart|run]
    -C, --cronotab PATH              Path to cronotab file (Default: config/cronotab.rb)
    -L, --logfile PATH               Path to writable logfile (Default: log/crono.log)
    -P, --pidfile PATH               Deprecated! use --piddir with --process_name; Path to pidfile (Default: )
    -D, --piddir PATH                Path to piddir (Default: tmp/pids)
    -N, --process_name NAME          Name of the process (Default: crono)
    -m, --monitor                    Start monitor process for a deamon (Default false)
    -e, --environment ENV            Application environment (Default: development)

Run as a daemon

To run Crono as a daemon, please add to your Gemfile:

gem 'daemons'

Then:

bundle install; bundle exec crono start RAILS_ENV=development

There are "start", "stop", and "restart" commands.

Web UI

Crono can display the current state of Crono jobs.

Add the following to your config/routes.rb:

Rails.application.routes.draw do
    mount Crono::Engine, at: '/crono'
    ...

Access management and other questions described in the wiki.

Known issues

For Rails 5, in case of the errors:

`require': cannot load such file -- rack/showexceptions (LoadError)

See the related issue #52

Capistrano

Use the capistrano-crono gem (github).

Support

Feel free to create an issues

License

Please see LICENSE for licensing details.

crono's People

Contributors

0xrichardh avatar acolyer avatar adamico avatar andrisbriedis avatar avialima avatar chandravati avatar cisolarix avatar cseelus avatar dependabot[bot] avatar gitter-badger avatar janko avatar jannishuebl avatar lhz avatar magynhard avatar mediafinger avatar michaelachrisco avatar miroslavcsonka avatar misteral avatar muzk avatar pachacamac avatar petergoldstein avatar plashchynski avatar redrick avatar simi avatar thomasfedb avatar trevoke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crono's Issues

Trouble daemonizing crono on production Ubuntu server

If I run bundle exec crono -e production in project root on production server, it works.
ps aux | grep crono also returns the process

However, if I try to daemonize the process (so I can write mina deployment task), it fails silently.
I have tried:

bundle exec crono -e production -d
bundle exec crono -e production -d true
bundle exec crono -e production --daemonize
bundle exec crono -e production --daemonize true
bundle exec crono -d -e production
bundle exec crono -d true -e production
bundle exec crono --daemonize -e production
bundle exec crono --daemonize true -e production

ps aux | grep crono returns only the grep process after every one of those commands.
What is going on?

Use perform_now instead of perform

Would it be possible to use ActiveJob's peform_now instead of perform? The main reason I ask is that using peform_now will call all of the ActiveJob callbacks and error handlers. The error handler callback is particularly important for reporting problems to a error reporting system like Sentry. Is there a reason perform was used instead of perform_now?

Jobs scheduled at same time exclude each other.

If two jobs are scheduled to execute at the same time, they may be missed.

Example cronotab.rb:

Crono.perform(VeryImportantJob).every 1.day, at: {hour: 23, min: 0}
Crono.perform(OtherImportantJob).every 1.day, at: {hour: 23, min: 00}

Rather than simply taking the next job off the queue, crono should check which jobs have not been executed and which should be executed.

Psudo-code for the described logic:

init_time = Time.now

while (true)
  first = Time.now + 1.hour

  jobs.each do |job|
    next_time = job.period.occurance_since(job.last_run_time || init_time)

    if next_time.past?
      job.perform
    else
      if next_time < first
        first = next_time
      end
    end
  end

  sleep(first - Time.now)
end

Restart crono issue

I have defined 2 jobs in cronotab:
Crono.perform(CheckBuildsAndNotifyJob, "Check Build Version", "AM").every 1.day, at: '09:30'
Crono.perform(CheckBuildsAndNotifyJob, "Check Build Version", "PM").every 1.day, at: '18:30'

The crono stopped yesterday for some reason and I restart my rails server as well as crono.
And the 2 jobs are triggered immediate I start crono.
It seems that it will memorize the unperformed jobs when crono is down and will run them on next start.

How can I disable this feature?

Scheduled task runs at the wrong time

I have a task scheduled to run at 4am UTC (9pm PST) but it actually ran at random time 11.30am PST. I'm puzzled. Other jobs seem to honor the time but some jobs clearly don't.

Crono.perform(CheckUnscheduledDeliveryPickupTomorrowJob).every 1.day, at: '04:00'

DB connection pool issue.

When the script runs, getting error..

could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)

jobs cleanup

When a job is removed from crontab.rb, it must be "marked" as disable or similar so it doesn't run next time

Crono memory footprint

Crono consumes about 100 MB of RAM at startup. Over time it consumes much more of it. I have a process that read about 4MB XML file, parse it and store some data from it to the database. I run it every 5 minutes. After the first script run, crono consumes about 320MB RAM, second run an crono consumes about 700 MB RAM. After couple more runs I got to over 1 GB of RAM consumed by crono and about 50 MB RAM free. My server got a bit slow because of this. Also tried to run this on heroku and got a lot of memory warnings.

I've managed to work-out a partial solution:, I fork the process at the beginning of the job 'process' method so Ruby creates a new process with my task. This new process also takes up about 320 MB RAM while running but when it finishes, the RAM is free again. This is ok for me but still the Crono process takes up about 100 MB on startup and this amount slowly rizes (couple of MB each job run). After 24h Crono consumes about 500 MB RAM now.

I've tried to read about the memory management in Ruby but no luck to fix this. Any ideas to make this memory footprint stable?

Run crono automatically with rails s

Hello,

Tanks for this gem, very simple to use!

To test it, I just add it to a brand new rails app, at first I was waiting in front of the console to see the first test (print something) to appears... Nothing appends

I figure it out latter that I have to run bundle exec crono.

Is there any possibilities to make crono runs/launches when you start your rails server? Or maybe I'm missing something.

Crono runs the task just the first time

This is an awesome gem, if only it can do what it says.

Crono runs my tasks, but just once, for the first time.

My cronotab looks like this:

require 'rake'
Quadra::Application.load_tasks

class InvoiceUpsert
  def perform
    Rake::Task['invoice:batch_upsert'].invoke
  end
end

class PaymentUpsert
  def perform
    Rake::Task['payment:batch_upsert'].invoke
  end
end


Crono.perform(PaymentUpsert).every 1.day, at: { hour: 02, min: 15 }
Crono.perform(InvoiceUpsert).every 15.minutes

Any suggestions? Or is this a bug?

table_name_prefix not taken into account

Hi,

in my application.rb file i used

config.active_record.table_name_prefix = 'xyz_'

to create a namespace inside a database that is allreay in use by other applications as well.

When i try to start the crono job on commandline it says that it cannot find the table CRONO_JOBS which is correct because the table name is xyz_crono_jobs.

Is this a bug or do i have to set some options somewhere to make this work ?

Thx and greetings

Holger

Run tasks only on weekdays

Maybe I am missing something but is there a way to run a task only on weekdays? Or some way to exclude Saturday and Sunday at least?

At generation sample job with crono

At rails generate crono:install
I think that the gem should create an example job for the rails project within the app folder.

For example:

$ rails generate crono:install

Should create:

# app/crono_jobs/test.rb
module CronoJobs
class Test < ActiveJob::Base
  def perform
    # put you scheduled code here
    # Comments.deleted.clean_up...
    fail 'You forgot to set up your crono job...'
  end
end
#config/cronotab.rb
include CronoJobs
Crono.perform(CronoJobs::Test).every 2.days, at: {hour: 15, min: 30}

mount Crono::Web, at: '/crono' fails

mount Crono::Web, at: '/crono' fails because depending by haml ?

$ rails s
=> Booting Thin
=> Rails 4.2.5 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Exiting
/home/lsoave/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require': cannot load such file -- haml (LoadError)
...
    from /home/lsoave/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/crono-0.9.0/lib/crono/web.rb:1:in `'
...

ActiveSupport bundle error

I have a legacy app that I thought might work with this gem, but I get this bundle error:

Bundler could not find compatible versions for gem "activesupport":
  In Gemfile:
    crono (>= 0) ruby depends on
      activejob (~> 4.0) ruby depends on
        activesupport (= 4.2.0) ruby

    jbuilder (~> 2.0) ruby depends on
      activesupport (4.1.0)

set job each hours at 00/15/30/45

Hi there,
So I need execute a job each hour, each 15 minutes exactly, independent from the deploy hour.

It's the first time that I use this GEM and it's my first app in Ruby :)

In node.js my code to do this is

var job = new CronJob('0 */15 * * * *', function () {
        do something....
    }, null, true, "");

I try 2 different approach

1) every hours at : 00/15/30/45

Crono.perform(myJob).every 1.hours,          at: {min:00}
Crono.perform(myJob).every 1.hours,          at: {min:15}
Crono.perform(myJob).every 1.hours,          at: {min:30}
Crono.perform(myJob).every 1.hours,          at: {min:45}

NOT WORK! period should be at least 1 day to use 'at'

2) every days each hours at : 00/15/30/45

Crono.perform(myJob).every 1.day,          at: {hour: *, min:00}
Crono.perform(myJob).every 1.day,          at: {hour: *, min:15}
Crono.perform(myJob).every 1.day,          at: {hour: *, min:30}
Crono.perform(myJob).every 1.day,          at: {hour: *, min:45}

NOT WORK! syntax error, unexpected * (SyntaxError)

Any suggestion??

undefined method `compact'

After Following your installation steps i am receiving this error.

bundle exec crono 
undefined method `compact' for {:hour=>15, :min=>30}:Hash
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/period.rb:68:in `time_atts'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/period.rb:32:in `initial_next'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/period.rb:14:in `next'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/job.rb:16:in `initialize'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/performer_proxy.rb:10:in `new'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/performer_proxy.rb:10:in `every'
/var/www/billgist/web_app/config/cronotab.rb:14:in `<top (required)>'
/usr/local/lib/ruby/gems/2.1.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/usr/local/lib/ruby/gems/2.1.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `block in require'
/usr/local/lib/ruby/gems/2.1.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:213:in `load_dependency'
/usr/local/lib/ruby/gems/2.1.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/cronotab.rb:7:in `process'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/lib/crono/cli.rb:24:in `run'
/usr/local/lib/ruby/gems/2.1.0/gems/crono-0.9.0/exe/crono:8:in `<top (required)>'
/usr/local/bin/crono:23:in `load'
/usr/local/bin/crono:23:in `<main>'

cat _config/cronotab.rb_

# cronotab.rb โ€” Crono configuration file
#
# Here you can specify periodic jobs and schedule.
# You can use ActiveJob's jobs from `app/jobs/`
# You can use any class. The only requirement is that
# class should have a method `perform` without arguments.
#
 class TestJob
   def perform
     puts 'Test!'
   end
 end
#
 Crono.perform(TestJob).every 2.days, at: '15:30'
#

Rails Version 4.0.0
Ruby Version 2.1.0p0

Unknown database

Hello,
I'm deploying a crono application in production, I've done the installation and migration but crono keeps on returning me an error when I start it: Unknown database ***_dev.
Of course it's pointing to the DB name in development, while it should point to the production environment, but I haven't found any way to change it. This problem does not affect the Rails application which uses crono, it regurlarly finds and uses the production database, so the problem is not on the database.yml.

bundle exec crono start RAILS_ENV=production
Unknown database '***_dev'

/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/mysql2_adapter.rb:29:in rescue in mysql2_connection' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/mysql2_adapter.rb:12:in mysql2_connection'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:729:in new_connection' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:773:in checkout_new_connection'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:752:in try_to_checkout_new_connection' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:713:in acquire_connection'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:490:in checkout' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in connection'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:883:in retrieve_connection' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_handling.rb:128:in retrieve_connection'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_handling.rb:91:in connection' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/model_schema.rb:442:in load_schema!'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/attributes.rb:233:in load_schema!' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/attribute_decorators.rb:28:in load_schema!'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/model_schema.rb:437:in load_schema' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/model_schema.rb:349:in attribute_types'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/model_schema.rb:368:in type_for_attribute' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/table_metadata.rb:34:in type'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/predicate_builder.rb:165:in build_bind_param' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/predicate_builder.rb:124:in block in create_binds_for_hash'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/predicate_builder.rb:100:in each' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/predicate_builder.rb:100:in create_binds_for_hash'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/predicate_builder.rb:36:in create_binds' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/where_clause_factory.rb:20:in build'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/query_methods.rb:632:in where!' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/query_methods.rb:625:in where'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation/finder_methods.rb:78:in find_by' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/relation.rb:224:in find_or_create_by'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.0.2/lib/active_record/querying.rb:6:in find_or_create_by' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/crono-1.1.2/lib/crono/job.rb:114:in model'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/crono-1.1.2/lib/crono/job.rb:55:in load' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/crono-1.1.2/lib/crono/scheduler.rb:11:in add_job'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/crono-1.1.2/lib/crono/performer_proxy.rb:12:in every' /home/***/***/config/cronotab.rb:16:in <top (required)>'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:293:in require' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:293:in block in require'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:259:in load_dependency' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:293:in require'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/crono-1.1.2/lib/crono/cronotab.rb:7:in process' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/crono-1.1.2/lib/crono/cli.rb:29:in run'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/crono-1.1.2/exe/crono:8:in <top (required)>' /home/***/.rbenv/versions/2.4.0/bin/crono:22:in load'
/home/
/.rbenv/versions/2.4.0/bin/crono:22:in <top (required)>' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli/exec.rb:74:in load'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli/exec.rb:74:in kernel_load' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli/exec.rb:27:in run'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli.rb:335:in exec' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor/command.rb:27:in run'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in invoke_command' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor.rb:359:in dispatch'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli.rb:20:in dispatch' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor/base.rb:440:in start'
/home//.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli.rb:11:in start' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/exe/bundle:32:in block in <top (required)>'
/home/
/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/friendly_errors.rb:121:in with_friendly_errors' /home/***/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/exe/bundle:24:in <top (required)>'
/home/***/.rbenv/versions/2.4.0/bin/bundle:22:in load' /home/***/.rbenv/versions/2.4.0/bin/bundle:22:in

'

Can you please help?

Tnx
Jean

Migration field log too long for Postgres

When trying to follow installation

rake db:migrate

Found this error in Rails 5 + PostgreSQL

Running via Spring preloader in process 372
== 20161202004223 CreateCronoJobs: migrating ==================================
-- create_table(:crono_jobs, {})
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

The limit on text can be at most 1GB - 1byte.

Which gets easily fixed replacing in migration file:

t.text      :log, limit: 1000000000 # For PostgreSQL

Monthly scheduling

Similar to #56, I'm in a situation where I need to perform a job at a monthly interval. For example, every first of the month.

@plashchynski , if you're okay, I'm keen to work on this feature.

To get some context, I'd like to know if you have had initial thought around this feature. Were there specific reasons why monthly interval is not supported?

If this is a good feature to add, what kind of DSLs should be supported? Some ideas I have:

Crono.perform(Job).every 1.month, on: 1, at: {hour: 12, min: 30} # specify date and time
Crono.perform(Job).every 1.month, on: 2 # specify date only with default time

Can't get logging to work.

I am running a rake task within config/cronotab.rb e.g.

# config/cronotab.rb
require 'rake'

Rails.app_class.load_tasks

class QboRenewTokens
  def perform
    Rake::Task['quickbooks:renew_oauth2_tokens'].invoke
   end
end

Crono.perform(QboRenewTokens).with_options(truncate_log: 100).every 5.minutes

Within the rake task I have both Rails.logger and p commands

If I run the task via command line bin/rake quickbooks:renew_oauth2_token I see the output in the console and in the log/development.log.

I am running crono as a daemon but none of my logger output shows up in log/crono.log nor log/development.log.

This is all that is recorded in log/crono.log

I, [2017-08-11T08:22:44.237388 #3867]  INFO -- : Perform QboRenewTokens
I, [2017-08-11T08:22:44.238103 #3867]  INFO -- : Finished QboRenewTokens in 0.00 seconds
I, [2017-08-11T08:27:44.237794 #3867]  INFO -- : Perform QboRenewTokens
I, [2017-08-11T08:27:44.238448 #3867]  INFO -- : Finished QboRenewTokens in 0.00 seconds

Creating jobs dynamically, at runtime

Hi,

Is there any way to create scheduled jobs at runtime, driven by user actions?

For instance - to let users create scheduled, recurring tasks?
As I suspect the answer would be no - is it in crono's vision / roadmap to consider such a feature?

Supporting multiple rails instances

If I have multiple stateless rails instances running in different servers, then Crono stars the job in all of the instances. I was hoping since Crono synchronises on DB, then it will only start the job in one instance.

Is there any way to do this with crono?

Crono did job but in dashboard it show: Never performed yet.

I have four workers perform every 600 seconds. The result is perfect. I didn't get any error messages. However, In the dashboard one of workers always show: Never performed yet. Although this didn't effect the result, sometimes, workers suspend without error message. It's hard to track what happened.

Should I provide any information to figure out the problem?

Documentation: how to start crono

Thanks fo the great gem!

The documentation only explains how to start crono from the command line. I'd like to have it autostarted with a Rails project instead of creating a Linux init script or something. Can it start automatically when Rails is started? Do we need to create an initializer? What are the consequences of running as a daemon vs. not running it as a daemon?

Again, thank you.

Migration version for Rails 5 and above

Crono generator leaves out migration version as it now appears in migrations from rails 5 and above...

before:

class CreateCronoJobs < ActiveRecord::Migration
  ...omitted...
end

now (rails 5 and above):

class CreateCronoJobs < ActiveRecord::Migration[5.1]
  ...omitted...
end

easy fix thou, will submit PR ASAP :)

Does not load as daemon

I've added the daemons gem to my gemfile. crono does not load as a deamon when issuing command bundle exec crono start on Ubuntu 14.04. How do I troubleshoot it?

Weekely scheduling on weekday at given time not work

class DataCsvReport
def perform
Rake::Task['DataReconciliation:pull_tables_csv'].execute
end
end

this do not work
Crono.perform(DataCsvReport).every 1.week, on: :wednesday, at: {hour: 18, min: 45}

Below is my system time and date to make sure setting passed above is correct
2.2.2 :021 > Time.now
=> 2017-11-08 18:41:05 +0530
2.2.2 :022 > Time.now.to_date
=> Wed, 08 Nov 2017

All other scheduling like daily, hourly etc working fine as expected:

Crono.perform(DataCsvReport).every 1.day, at: {hour: 18, min: 59}
Crono.perform(DataCsvReport).every 5.minutes

Timezone issues

Hi,

I have a crontab that contains:

Crono.perform(SendPreLockdownEmailsJob).every 1.days, at: '00:01'

Rails' timezone is set to UTC+4. According to that, the job should always run at 20:00 UTC everyday. The problem is that it sometimes run on 00:01 UTC too for some reason that I don't understand. You can see what I mean from the job's logs:

I, [2017-05-07T20:01:00.000688 #8]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-07T20:01:00.333131 #8]  INFO -- : Finished SendPreLockdownEmailsJob in 0.33 seconds
I, [2017-05-08T00:01:00.001753 #8]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-08T00:01:00.245461 #8]  INFO -- : Finished SendPreLockdownEmailsJob in 0.24 seconds
I, [2017-05-08T20:50:36.271039 #8]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-08T20:50:36.365803 #8]  INFO -- : Finished SendPreLockdownEmailsJob in 0.09 seconds
I, [2017-05-09T00:01:00.000563 #8]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-09T00:01:00.128860 #8]  INFO -- : Finished SendPreLockdownEmailsJob in 0.13 seconds
I, [2017-05-09T20:01:00.000598 #8]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-09T20:01:00.181408 #8]  INFO -- : Finished SendPreLockdownEmailsJob in 0.18 seconds
I, [2017-05-10T20:01:00.001467 #9]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-10T20:01:00.304802 #9]  INFO -- : Finished SendPreLockdownEmailsJob in 0.30 seconds
I, [2017-05-11T00:01:00.000725 #9]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-11T00:01:00.238791 #9]  INFO -- : Finished SendPreLockdownEmailsJob in 0.24 seconds
I, [2017-05-12T00:01:00.000630 #9]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-12T00:01:00.233772 #9]  INFO -- : Finished SendPreLockdownEmailsJob in 0.23 seconds
I, [2017-05-12T20:01:00.000284 #8]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-12T20:01:00.329280 #8]  INFO -- : Finished SendPreLockdownEmailsJob in 0.33 seconds
I, [2017-05-13T00:01:00.000260 #8]  INFO -- : Perform SendPreLockdownEmailsJob
I, [2017-05-13T00:01:00.338922 #8]  INFO -- : Finished SendPreLockdownEmailsJob in 0.34 seconds

So the problem is that the at option is sometimes interpreted as UTC, sometimes interpreted as Rails timezone and sometimes both. Any help?

Use with rails v5.*

I am getting a bundle conflict due to crono's activejob (~> 4.0) requirement on Rails 5.0.0.rc1
Any plans for a compatible beta?

Crono fails to start with Web UI route active on Rails 5

First thanks for your work. We use Crono in production for over a year now and it has kicked of tens of thousands of jobs on our servers.

Upgrading one of our apps to Rails 5 we encountered a problem though:

Running the Crono gem works as long as the route to the Web UI (mount Crono::Web, at: '/crono') is not active. With the route added, crono doesn't start locally as well as on our production machine (Heroku).

We can reproduce this problem within a clean new Rails 5.0.0.1 app with only the Crono gem added as well.

Error log from development machine (macOS 10.11.6 with Ruby 2.3.1, paths shortened for readability):

bundler: failed to load command: crono (/bin/crono)
LoadError: cannot load such file -- rack/showexceptions
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `block in require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/sinatra-1.0/lib/sinatra/showexceptions.rb:1:in `<top (required)>'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `block in require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/sinatra-1.0/lib/sinatra/base.rb:6:in `<top (required)>'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `block in require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/crono-1.0.3/lib/crono/web.rb:2:in `<top (required)>'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `block in require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /Users/chris/Sites/crono/config/routes.rb:2:in `block in <top (required)>'
  /lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/routing/route_set.rb:389:in `instance_exec'
  /lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/routing/route_set.rb:389:in `eval_block'
  /lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/routing/route_set.rb:371:in `draw'
  /Users/chris/Sites/crono/config/routes.rb:1:in `<top (required)>'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `block in load'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/routes_reloader.rb:40:in `block in load_paths'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/routes_reloader.rb:40:in `each'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/routes_reloader.rb:40:in `load_paths'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/routes_reloader.rb:16:in `reload!'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/routes_reloader.rb:26:in `block in updater'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/file_update_checker.rb:77:in `execute'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/routes_reloader.rb:27:in `updater'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/routes_reloader.rb:7:in `execute_if_updated'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application/finisher.rb:119:in `block in <module:Finisher>'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/initializable.rb:30:in `instance_exec'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/initializable.rb:30:in `run'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/initializable.rb:55:in `block in run_initializers'
  /lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
  /lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
  /lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
  /lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
  /lib/ruby/2.3.0/tsort.rb:347:in `each'
  /lib/ruby/2.3.0/tsort.rb:347:in `call'
  /lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
  /lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
  /lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/initializable.rb:54:in `run_initializers'
  /lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/application.rb:352:in `initialize!'
  /Users/chris/Sites/crono/config/environment.rb:5:in `<top (required)>'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `block in require'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency'
  /lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require'
  /lib/ruby/gems/2.3.0/gems/crono-1.0.3/lib/crono/cli.rb:84:in `load_rails'
  /lib/ruby/gems/2.3.0/gems/crono-1.0.3/lib/crono/cli.rb:28:in `run'
  /lib/ruby/gems/2.3.0/gems/crono-1.0.3/exe/crono:8:in `<top (required)>'
  /bin/crono:23:in `load'
  /bin/crono:23:in `<top (required)>'

job_id forces FK in rails 4.2.7.1 and 4.2.8

when doing migration (rails 4.2.7.1 and 4.2.8 on postgres db), rails interprets job_id as a reference to job table (which does not exist).
Changing the job_id string in the migration file:
t.string :job_id, null: false, foreign_key: false
(add foreign_key: false) solves the problem

crono with rake tast only execute one time on start

Rails 5.0.1
ruby 2.3.3

here is my code:
namespace :crono do
  desc "hello"
  task :hello => :environment do
    puts 'hello...'
  end
end

in cronotab.rb:
require 'rake'

Rails.app_class.load_tasks

class Test
  def perform
    Rake::Task['crono:hello'].invoke
  end
end
Crono.perform(Test).every 5.seconds

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.