Compare commits

...

19 Commits

Author SHA1 Message Date
dependabot[bot]
a64f05aa68 Bump sinatra from 2.2.0 to 2.2.3
Bumps [sinatra](https://github.com/sinatra/sinatra) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/sinatra/sinatra/releases)
- [Changelog](https://github.com/sinatra/sinatra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinatra/sinatra/compare/v2.2.0...v2.2.3)

---
updated-dependencies:
- dependency-name: sinatra
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 02:41:43 +00:00
Dzmitry Plashchynski
4294bad43a Update Gemfile.lock 2022-09-03 19:22:59 +03:00
Dzmitry Plashchynski
0702e20add Bump 2.0.1 2022-09-03 15:27:02 +03:00
Dzmitry Plashchynski
db8c29afbe Merge pull request #109 from itbeaver/fix_job_args
Fixes arguments for jobs
2022-09-03 15:22:26 +03:00
Aleksandr Bobrov
43e411cf0f Fix args 2022-09-03 00:26:10 +04:00
Dzmitry Plashchynski
e43ad4d409 Merge pull request #108 from plashchynski/dependabot/bundler/activerecord-7.0.3.1
Bump activerecord from 7.0.3 to 7.0.3.1
2022-07-24 22:52:25 +03:00
Dzmitry Plashchynski
c5c58b559f Write PID in the daemon mode 2022-07-24 22:50:05 +03:00
Dzmitry Plashchynski
81d1e3496f remove duplicated file 2022-07-24 22:44:45 +03:00
Dzmitry Plashchynski
ddbfa4c42e Fix specs 2022-07-24 22:38:08 +03:00
Dzmitry Plashchynski
e03d9b4ba6 Remove crono_test.sqlite from git cache 2022-07-24 22:37:50 +03:00
dependabot[bot]
811ab31978 Bump activerecord from 7.0.3 to 7.0.3.1
Bumps [activerecord](https://github.com/rails/rails) from 7.0.3 to 7.0.3.1.
- [Release notes](https://github.com/rails/rails/releases)
- [Changelog](https://github.com/rails/rails/blob/v7.0.3.1/activerecord/CHANGELOG.md)
- [Commits](https://github.com/rails/rails/compare/v7.0.3...v7.0.3.1)

---
updated-dependencies:
- dependency-name: activerecord
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-15 11:38:13 +00:00
Dzmitry Plashchynski
cb5064852a Merge pull request #107 from mediafinger/add-github-actions-for-specs
Add GitHub actions for specs
2022-07-15 14:37:21 +03:00
Andreas Finger
a421a6207b ci: Add GitHub Action to run specs 2022-07-11 10:43:02 +02:00
Andreas Finger
4abc999583 doc: List compatible Ruby versions in the README 2022-07-11 10:41:20 +02:00
Dzmitry Plashchynski
0e1dec2956 Merge pull request #106 from plashchynski/dependabot/bundler/rails-html-sanitizer-1.4.3
Bump rails-html-sanitizer from 1.4.2 to 1.4.3
2022-07-08 13:05:37 +03:00
dependabot[bot]
3a17938571 Bump rails-html-sanitizer from 1.4.2 to 1.4.3
Bumps [rails-html-sanitizer](https://github.com/rails/rails-html-sanitizer) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/rails/rails-html-sanitizer/releases)
- [Changelog](https://github.com/rails/rails-html-sanitizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/rails-html-sanitizer/compare/v1.4.2...v1.4.3)

---
updated-dependencies:
- dependency-name: rails-html-sanitizer
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-06 12:23:15 +00:00
Dzmitry Plashchynski
5391930954 Merge branch 'main' of https://github.com/plashchynski/crono 2022-06-16 11:08:28 +02:00
Dzmitry Plashchynski
5c16c8c6dd Do not pass empty arguments to the worker. Closes #95 2022-06-16 11:08:22 +02:00
Dzmitry Plashchynski
b1cc71e9a4 Update README.md 2022-05-30 00:25:46 +03:00
13 changed files with 158 additions and 198 deletions

36
.github/workflows/rspec.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: "RSpec"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '00 12 * * *' # daily at 12:00
jobs:
specs:
name: specs
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
ruby: ['2.7', '3.0', '3.1'] # Due to https://github.com/actions/runner/issues/849, we have to use quotes
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Ruby and install gems
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
cache-version: 1 # change this value when you have to empty the cache manually
- name: Run specs
run: |
bundle exec rspec spec/

View File

@@ -1,3 +1,7 @@
2.0.1
-----------
- Fix a job argument error
2.0.0
-----------
- Converted this gem to a proper Rails engine

View File

@@ -1,74 +1,74 @@
PATH
remote: .
specs:
crono (1.1.2)
crono (2.0.1)
rails (>= 5.2.8)
sprockets-rails
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.3)
actionpack (= 7.0.3)
activesupport (= 7.0.3)
actioncable (7.0.3.1)
actionpack (= 7.0.3.1)
activesupport (= 7.0.3.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.3)
actionpack (= 7.0.3)
activejob (= 7.0.3)
activerecord (= 7.0.3)
activestorage (= 7.0.3)
activesupport (= 7.0.3)
actionmailbox (7.0.3.1)
actionpack (= 7.0.3.1)
activejob (= 7.0.3.1)
activerecord (= 7.0.3.1)
activestorage (= 7.0.3.1)
activesupport (= 7.0.3.1)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.3)
actionpack (= 7.0.3)
actionview (= 7.0.3)
activejob (= 7.0.3)
activesupport (= 7.0.3)
actionmailer (7.0.3.1)
actionpack (= 7.0.3.1)
actionview (= 7.0.3.1)
activejob (= 7.0.3.1)
activesupport (= 7.0.3.1)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.3)
actionview (= 7.0.3)
activesupport (= 7.0.3)
actionpack (7.0.3.1)
actionview (= 7.0.3.1)
activesupport (= 7.0.3.1)
rack (~> 2.0, >= 2.2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.3)
actionpack (= 7.0.3)
activerecord (= 7.0.3)
activestorage (= 7.0.3)
activesupport (= 7.0.3)
actiontext (7.0.3.1)
actionpack (= 7.0.3.1)
activerecord (= 7.0.3.1)
activestorage (= 7.0.3.1)
activesupport (= 7.0.3.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.3)
activesupport (= 7.0.3)
actionview (7.0.3.1)
activesupport (= 7.0.3.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.3)
activesupport (= 7.0.3)
activejob (7.0.3.1)
activesupport (= 7.0.3.1)
globalid (>= 0.3.6)
activemodel (7.0.3)
activesupport (= 7.0.3)
activerecord (7.0.3)
activemodel (= 7.0.3)
activesupport (= 7.0.3)
activestorage (7.0.3)
actionpack (= 7.0.3)
activejob (= 7.0.3)
activerecord (= 7.0.3)
activesupport (= 7.0.3)
activemodel (7.0.3.1)
activesupport (= 7.0.3.1)
activerecord (7.0.3.1)
activemodel (= 7.0.3.1)
activesupport (= 7.0.3.1)
activestorage (7.0.3.1)
actionpack (= 7.0.3.1)
activejob (= 7.0.3.1)
activerecord (= 7.0.3.1)
activesupport (= 7.0.3.1)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.3)
activesupport (7.0.3.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -90,7 +90,7 @@ GEM
haml (5.2.2)
temple (>= 0.8.0)
tilt
i18n (1.10.0)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
loofah (2.18.0)
crass (~> 1.0.2)
@@ -100,8 +100,8 @@ GEM
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.2)
minitest (5.15.0)
mustermann (1.1.1)
minitest (5.16.2)
mustermann (2.0.2)
ruby2_keywords (~> 0.0.1)
net-imap (0.2.3)
digest
@@ -118,36 +118,40 @@ GEM
net-protocol
timeout
nio4r (2.5.8)
nokogiri (1.13.6-arm64-darwin)
nokogiri (1.13.7-arm64-darwin)
racc (~> 1.4)
nokogiri (1.13.7-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.13.7-x86_64-linux)
racc (~> 1.4)
racc (1.6.0)
rack (2.2.3.1)
rack-protection (2.2.0)
rack (2.2.4)
rack-protection (2.2.3)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (7.0.3)
actioncable (= 7.0.3)
actionmailbox (= 7.0.3)
actionmailer (= 7.0.3)
actionpack (= 7.0.3)
actiontext (= 7.0.3)
actionview (= 7.0.3)
activejob (= 7.0.3)
activemodel (= 7.0.3)
activerecord (= 7.0.3)
activestorage (= 7.0.3)
activesupport (= 7.0.3)
rails (7.0.3.1)
actioncable (= 7.0.3.1)
actionmailbox (= 7.0.3.1)
actionmailer (= 7.0.3.1)
actionpack (= 7.0.3.1)
actiontext (= 7.0.3.1)
actionview (= 7.0.3.1)
activejob (= 7.0.3.1)
activemodel (= 7.0.3.1)
activerecord (= 7.0.3.1)
activestorage (= 7.0.3.1)
activesupport (= 7.0.3.1)
bundler (>= 1.15.0)
railties (= 7.0.3)
railties (= 7.0.3.1)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.2)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
railties (7.0.3)
actionpack (= 7.0.3)
activesupport (= 7.0.3)
railties (7.0.3.1)
actionpack (= 7.0.3.1)
activesupport (= 7.0.3.1)
method_source
rake (>= 12.2)
thor (~> 1.0)
@@ -175,12 +179,12 @@ GEM
rspec-support (~> 3.10)
rspec-support (3.11.0)
ruby2_keywords (0.0.5)
sinatra (2.2.0)
mustermann (~> 1.0)
sinatra (2.2.3)
mustermann (~> 2.0)
rack (~> 2.2)
rack-protection (= 2.2.0)
rack-protection (= 2.2.3)
tilt (~> 2.0)
sprockets (4.0.3)
sprockets (4.1.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.4.2)
@@ -188,10 +192,10 @@ GEM
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sqlite3 (1.4.2)
strscan (3.0.3)
strscan (3.0.4)
temple (0.8.2)
thor (1.2.1)
tilt (2.0.10)
tilt (2.0.11)
timecop (0.9.5)
timeout (0.3.0)
tzinfo (2.0.4)
@@ -199,10 +203,12 @@ GEM
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.5.4)
zeitwerk (2.6.0)
PLATFORMS
arm64-darwin-21
x86_64-darwin-21
x86_64-linux
DEPENDENCIES
bundler (>= 2)

View File

@@ -8,7 +8,7 @@ Crono is a time-based background job scheduler daemon (just like Cron) for Ruby
Currently, there is no such thing as Ruby Cron for Rails. Well, there's [Whenever](https://github.com/javan/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](https://github.com/plashchynski/crono/raw/master/examples/crono_web_ui.png)
![Web UI](https://github.com/plashchynski/crono/raw/main/examples/crono_web_ui.png)
## Installation
@@ -31,6 +31,10 @@ Run the migration:
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
@@ -211,4 +215,4 @@ Feel free to create an [issues](https://github.com/plashchynski/crono/issues)
## License
Please see [LICENSE](https://github.com/plashchynski/crono/blob/master/LICENSE) for licensing details.
Please see [LICENSE](LICENSE) for licensing details.

View File

@@ -24,7 +24,7 @@ module Crono
setup_log
write_pid unless config.daemonize
write_pid if config.daemonize
load_rails
Cronotab.process(File.expand_path(config.cronotab))
print_banner

View File

@@ -9,10 +9,10 @@ module Crono
attr_accessor :performer, :period, :job_args, :last_performed_at, :job_options,
:next_performed_at, :job_log, :job_logger, :healthy, :execution_interval
def initialize(performer, period, job_args, job_options = nil)
def initialize(performer, period, job_args = nil, job_options = nil)
self.execution_interval = 0.minutes
self.performer, self.period = performer, period
self.job_args = JSON.generate(job_args)
self.job_args = JSON.generate(job_args) if job_args.present?
self.job_log = StringIO.new
self.job_logger = Logger.new(job_log)
self.job_options = job_options || {}

View File

@@ -1,14 +1,15 @@
module Crono
# Crono::PerformerProxy is a proxy used in cronotab.rb semantic
class PerformerProxy
def initialize(performer, scheduler, job_args)
def initialize(performer, scheduler, job_args = nil, job_options = nil)
@performer = performer
@scheduler = scheduler
@job_args = job_args
@job_options = job_options
end
def every(period, **options)
@job = Job.new(@performer, Period.new(period, **options), @job_args, @options)
@job = Job.new(@performer, Period.new(period, **options), @job_args, @job_options)
@scheduler.add_job(@job)
self
end
@@ -19,12 +20,12 @@ module Crono
end
def with_options(options)
@options = options
@job_options = options
self
end
end
def self.perform(performer, *job_args)
PerformerProxy.new(performer, Crono.scheduler, job_args)
PerformerProxy.new(performer, Crono.scheduler, *job_args)
end
end

View File

@@ -1,3 +1,3 @@
module Crono
VERSION = '2.0.0'
VERSION = '2.0.1'
end

View File

@@ -11,7 +11,7 @@ describe Crono::CLI do
expect(cli).to receive(:start_working_loop)
expect(cli).to receive(:parse_options)
expect(cli).to receive(:parse_command)
expect(cli).to receive(:write_pid)
expect(cli).not_to receive(:write_pid)
expect(Crono::Cronotab).to receive(:process)
cli.run
end
@@ -25,7 +25,8 @@ describe Crono::CLI do
expect(cli).to receive(:start_working_loop_in_daemon)
expect(cli).to receive(:parse_options)
expect(cli).to receive(:parse_command)
expect(cli).not_to receive(:write_pid)
expect(cli).to receive(:setup_log)
expect(cli).to receive(:write_pid)
expect(Crono::Cronotab).to receive(:process)
cli.run
end

Binary file not shown.

View File

@@ -1,23 +1,30 @@
require 'spec_helper'
class TestJob
def perform(args)
def perform(*args)
puts 'Test!'
end
end
class TestFailingJob
def perform(args)
def perform(*args)
raise 'Some error'
end
end
class TestNoArgsJob
def perform
puts 'Test!'
end
end
describe Crono::Job do
let(:period) { Crono::Period.new(2.day, at: '15:00') }
let(:job_args) {[{some: 'data'}]}
let(:job) { Crono::Job.new(TestJob, period, []) }
let(:job_with_args) { Crono::Job.new(TestJob, period, job_args) }
let(:failing_job) { Crono::Job.new(TestFailingJob, period, []) }
let(:not_args_job) { Crono::Job.new(TestJob, period) }
it 'should contain performer and period' do
expect(job.performer).to be TestJob
@@ -70,6 +77,10 @@ describe Crono::Job do
test_preform_job_twice
end
it 'should execute twice without args' do
test_preform_job_twice not_args_job
end
it 'should execute twice without initialize execution_interval' do
test_preform_job_twice
end
@@ -88,10 +99,10 @@ describe Crono::Job do
expect(thread).to be_stop
end
def test_preform_job_twice
expect(job).to receive(:perform_job).twice
job.perform.join
thread = job.perform.join
def test_preform_job_twice(jon_instance = job)
expect(jon_instance).to receive(:perform_job).twice
jon_instance.perform.join
thread = jon_instance.perform.join
expect(thread).to be_stop
end
end

View File

@@ -26,13 +26,19 @@ describe Crono::PerformerProxy do
end
it 'should add job with args to schedule' do
expect(Crono::Job).to receive(:new).with(TestJob, kind_of(Crono::Period), [:some, {some: 'data'}], nil)
expect(Crono::Job).to receive(:new).with(TestJob, kind_of(Crono::Period), :some, { some: 'data' })
allow(Crono.scheduler).to receive(:add_job)
Crono.perform(TestJob, :some, {some: 'data'}).every(2.days, at: '15:30')
Crono.perform(TestJob, :some, { some: 'data' }).every(2.days, at: '15:30')
end
it 'should add job without args to schedule' do
expect(Crono::Job).to receive(:new).with(TestJob, kind_of(Crono::Period), nil, nil)
allow(Crono.scheduler).to receive(:add_job)
Crono.perform(TestJob).every(2.days, at: '15:30')
end
it 'should add job with options to schedule' do
expect(Crono::Job).to receive(:new).with(TestJob, kind_of(Crono::Period), [], {some_option: true})
expect(Crono::Job).to receive(:new).with(TestJob, kind_of(Crono::Period), nil, { some_option: true })
allow(Crono.scheduler).to receive(:add_job)
Crono.perform(TestJob).with_options(some_option: true).every(2.days, at: '15:30')
end

View File

@@ -1,109 +0,0 @@
require 'spec_helper'
require 'crono/cli'
describe Crono::CLI do
let(:cli) { Crono::CLI.instance }
describe '#run' do
it 'should initialize rails with #load_rails and start working loop' do
expect(cli).to receive(:load_rails)
expect(cli).to receive(:have_jobs?).and_return(true)
expect(cli).to receive(:start_working_loop)
expect(cli).to receive(:parse_options)
expect(cli).to receive(:parse_command)
expect(cli).to receive(:write_pid)
expect(Crono::Cronotab).to receive(:process)
cli.run
end
context 'should run as daemon' do
before { cli.config.daemonize = true }
it 'should initialize rails with #load_rails and start working loop' do
expect(cli).to receive(:load_rails)
expect(cli).to receive(:have_jobs?).and_return(true)
expect(cli).to receive(:start_working_loop_in_daemon)
expect(cli).to receive(:parse_options)
expect(cli).to receive(:parse_command)
expect(cli).not_to receive(:write_pid)
expect(Crono::Cronotab).to receive(:process)
cli.run
end
end
end
describe '#parse_options' do
it 'should set cronotab' do
cli.send(:parse_options, ['--cronotab', '/tmp/cronotab.rb'])
expect(cli.config.cronotab).to be_eql '/tmp/cronotab.rb'
end
it 'should set logfile' do
cli.send(:parse_options, ['--logfile', 'log/crono.log'])
expect(cli.config.logfile).to be_eql 'log/crono.log'
end
it 'should set pidfile' do
cli.send(:parse_options, ['--pidfile', 'tmp/pids/crono.0.log'])
expect(cli.config.pidfile).to be_eql 'tmp/pids/crono.0.log'
end
it 'should set piddir' do
cli.send(:parse_options, ['--piddir', 'tmp/pids'])
expect(cli.config.piddir).to be_eql 'tmp/pids'
end
it 'should set process_name' do
cli.send(:parse_options, ['--process_name', 'crono0'])
expect(cli.config.process_name).to be_eql 'crono0'
end
it 'should set monitor' do
cli.send(:parse_options, ['--monitor'])
expect(cli.config.monitor).to be true
end
it 'should set environment' do
cli.send(:parse_options, ['--environment', 'production'])
expect(cli.config.environment).to be_eql('production')
end
end
describe '#parse_command' do
it 'should set daemonize on start' do
cli.send(:parse_command, ['start'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on stop' do
cli.send(:parse_command, ['stop'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on restart' do
cli.send(:parse_command, ['restart'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on run' do
cli.send(:parse_command, ['run'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on zap' do
cli.send(:parse_command, ['zap'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on reload' do
cli.send(:parse_command, ['reload'])
expect(cli.config.daemonize).to be true
end
it 'should set daemonize on status' do
cli.send(:parse_command, ['status'])
expect(cli.config.daemonize).to be true
end
end
end