sidekiq-cron 1.0.4 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,6 +20,23 @@ module Sidekiq
20
20
  end
21
21
  end
22
22
 
23
+ # display job detail + jid history
24
+ app.get '/cron/:name' do
25
+ view_path = File.join(File.expand_path("..", __FILE__), "views")
26
+
27
+ @job = Sidekiq::Cron::Job.find(route_params[:name])
28
+ if @job
29
+ #if Slim renderer exists and sidekiq has layout.slim in views
30
+ if defined?(Slim) && File.exists?(File.join(settings.views,"layout.slim"))
31
+ render(:slim, File.read(File.join(view_path, "cron_show.slim")))
32
+ else
33
+ render(:erb, File.read(File.join(view_path, "cron_show.erb")))
34
+ end
35
+ else
36
+ redirect "#{root_path}cron"
37
+ end
38
+ end
39
+
23
40
  #enque cron job
24
41
  app.post '/cron/:name/enque' do
25
42
  if route_params[:name] === '__all__'
@@ -27,7 +44,7 @@ module Sidekiq
27
44
  elsif job = Sidekiq::Cron::Job.find(route_params[:name])
28
45
  job.enque!
29
46
  end
30
- redirect "#{root_path}cron"
47
+ redirect params['redirect'] || "#{root_path}cron"
31
48
  end
32
49
 
33
50
  #delete schedule
@@ -47,7 +64,7 @@ module Sidekiq
47
64
  elsif job = Sidekiq::Cron::Job.find(route_params[:name])
48
65
  job.enable!
49
66
  end
50
- redirect "#{root_path}cron"
67
+ redirect params['redirect'] || "#{root_path}cron"
51
68
  end
52
69
 
53
70
  #disable job
@@ -57,7 +74,7 @@ module Sidekiq
57
74
  elsif job = Sidekiq::Cron::Job.find(route_params[:name])
58
75
  job.disable!
59
76
  end
60
- redirect "#{root_path}cron"
77
+ redirect params['redirect'] || "#{root_path}cron"
61
78
  end
62
79
 
63
80
  end
data/lib/sidekiq/cron.rb CHANGED
@@ -4,5 +4,6 @@ require "sidekiq/cron/launcher"
4
4
 
5
5
  module Sidekiq
6
6
  module Cron
7
+ Redis.respond_to?(:exists_returns_integer) && Redis.exists_returns_integer = false
7
8
  end
8
9
  end
data/sidekiq-cron.gemspec CHANGED
@@ -1,127 +1,48 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
- # stub: sidekiq-cron 1.0.4 ruby lib
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/sidekiq/cron/version'
6
4
 
7
5
  Gem::Specification.new do |s|
8
6
  s.name = "sidekiq-cron".freeze
9
- s.version = "1.0.4"
7
+ s.version = Sidekiq::Cron::VERSION
10
8
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
- s.require_paths = ["lib".freeze]
13
- s.authors = ["Ondrej Bartas".freeze]
14
- s.date = "2018-08-15"
15
- s.description = "Enables to set jobs to be run in specified time (using CRON notation)".freeze
16
- s.email = "ondrej@bartas.cz".freeze
9
+ s.required_ruby_version = ">= 2.5"
10
+ s.require_paths = ["lib"]
11
+ s.authors = ["Ondrej Bartas"]
12
+ s.date = "2020-04-03"
13
+ s.description = "Enables to set jobs to be run in specified time (using CRON notation)"
14
+ s.email = "ondrej@bartas.cz"
17
15
  s.extra_rdoc_files = [
18
16
  "LICENSE.txt",
19
17
  "README.md"
20
18
  ]
21
- s.files = [
19
+ s.files = Dir.glob('lib/**/*') + Dir.glob('test/**/*') + [
22
20
  ".document",
23
- ".travis.yml",
24
21
  "Changes.md",
25
22
  "Dockerfile",
26
- "Gemfile",
27
- "LICENSE.txt",
28
- "README.md",
29
- "Rakefile",
30
- "VERSION",
31
23
  "config.ru",
32
24
  "docker-compose.yml",
33
25
  "examples/web-cron-ui.png",
34
- "lib/sidekiq-cron.rb",
35
- "lib/sidekiq/cron.rb",
36
- "lib/sidekiq/cron/job.rb",
37
- "lib/sidekiq/cron/launcher.rb",
38
- "lib/sidekiq/cron/locales/de.yml",
39
- "lib/sidekiq/cron/locales/en.yml",
40
- "lib/sidekiq/cron/locales/ja.yml",
41
- "lib/sidekiq/cron/locales/ru.yml",
42
- "lib/sidekiq/cron/locales/zh-CN.yml",
43
- "lib/sidekiq/cron/poller.rb",
44
- "lib/sidekiq/cron/support.rb",
45
- "lib/sidekiq/cron/views/cron.erb",
46
- "lib/sidekiq/cron/views/cron.slim",
47
- "lib/sidekiq/cron/web.rb",
48
- "lib/sidekiq/cron/web_extension.rb",
26
+ "Gemfile",
27
+ "LICENSE.txt",
28
+ "Rakefile",
29
+ "README.md",
49
30
  "sidekiq-cron.gemspec",
50
- "test/integration/performance_test.rb",
51
- "test/test_helper.rb",
52
- "test/unit/job_test.rb",
53
- "test/unit/poller_test.rb",
54
- "test/unit/web_extension_test.rb"
55
31
  ]
56
- s.homepage = "http://github.com/ondrejbartas/sidekiq-cron".freeze
57
- s.licenses = ["MIT".freeze]
58
- s.rubygems_version = "2.5.2.1".freeze
59
- s.summary = "Sidekiq Cron helps to add repeated scheduled jobs".freeze
32
+
33
+ s.homepage = "https://github.com/ondrejbartas/sidekiq-cron"
34
+ s.licenses = ["MIT"]
35
+ s.summary = "Sidekiq Cron helps to add repeated scheduled jobs"
60
36
 
61
- if s.respond_to? :specification_version then
62
- s.specification_version = 4
37
+ s.add_dependency("fugit", ">= 1.1")
38
+ s.add_dependency("sidekiq", ">= 4.2.1")
63
39
 
64
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
65
- s.add_runtime_dependency(%q<sidekiq>.freeze, [">= 4.2.1"])
66
- s.add_runtime_dependency(%q<fugit>.freeze, ["~> 1.1"])
67
- s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
68
- s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
69
- s.add_development_dependency(%q<redis-namespace>.freeze, [">= 1.5.2"])
70
- s.add_development_dependency(%q<shoulda-context>.freeze, [">= 0"])
71
- s.add_development_dependency(%q<rack>.freeze, [">= 0"])
72
- s.add_development_dependency(%q<rack-test>.freeze, [">= 0"])
73
- s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
74
- s.add_development_dependency(%q<minitest>.freeze, [">= 0"])
75
- s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
76
- s.add_development_dependency(%q<sdoc>.freeze, [">= 0"])
77
- s.add_development_dependency(%q<slim>.freeze, [">= 0"])
78
- s.add_development_dependency(%q<sinatra>.freeze, [">= 0"])
79
- s.add_development_dependency(%q<mocha>.freeze, [">= 0"])
80
- s.add_development_dependency(%q<coveralls>.freeze, [">= 0"])
81
- s.add_development_dependency(%q<shotgun>.freeze, [">= 0"])
82
- s.add_development_dependency(%q<guard>.freeze, [">= 0"])
83
- s.add_development_dependency(%q<guard-minitest>.freeze, [">= 0"])
84
- else
85
- s.add_dependency(%q<sidekiq>.freeze, [">= 4.2.1"])
86
- s.add_dependency(%q<fugit>.freeze, ["~> 1.1"])
87
- s.add_dependency(%q<bundler>.freeze, [">= 0"])
88
- s.add_dependency(%q<simplecov>.freeze, [">= 0"])
89
- s.add_dependency(%q<redis-namespace>.freeze, [">= 1.5.2"])
90
- s.add_dependency(%q<shoulda-context>.freeze, [">= 0"])
91
- s.add_dependency(%q<rack>.freeze, [">= 0"])
92
- s.add_dependency(%q<rack-test>.freeze, [">= 0"])
93
- s.add_dependency(%q<jeweler>.freeze, [">= 0"])
94
- s.add_dependency(%q<minitest>.freeze, [">= 0"])
95
- s.add_dependency(%q<test-unit>.freeze, [">= 0"])
96
- s.add_dependency(%q<sdoc>.freeze, [">= 0"])
97
- s.add_dependency(%q<slim>.freeze, [">= 0"])
98
- s.add_dependency(%q<sinatra>.freeze, [">= 0"])
99
- s.add_dependency(%q<mocha>.freeze, [">= 0"])
100
- s.add_dependency(%q<coveralls>.freeze, [">= 0"])
101
- s.add_dependency(%q<shotgun>.freeze, [">= 0"])
102
- s.add_dependency(%q<guard>.freeze, [">= 0"])
103
- s.add_dependency(%q<guard-minitest>.freeze, [">= 0"])
104
- end
105
- else
106
- s.add_dependency(%q<sidekiq>.freeze, [">= 4.2.1"])
107
- s.add_dependency(%q<fugit>.freeze, ["~> 1.1"])
108
- s.add_dependency(%q<bundler>.freeze, [">= 0"])
109
- s.add_dependency(%q<simplecov>.freeze, [">= 0"])
110
- s.add_dependency(%q<redis-namespace>.freeze, [">= 1.5.2"])
111
- s.add_dependency(%q<shoulda-context>.freeze, [">= 0"])
112
- s.add_dependency(%q<rack>.freeze, [">= 0"])
113
- s.add_dependency(%q<rack-test>.freeze, [">= 0"])
114
- s.add_dependency(%q<jeweler>.freeze, [">= 0"])
115
- s.add_dependency(%q<minitest>.freeze, [">= 0"])
116
- s.add_dependency(%q<test-unit>.freeze, [">= 0"])
117
- s.add_dependency(%q<sdoc>.freeze, [">= 0"])
118
- s.add_dependency(%q<slim>.freeze, [">= 0"])
119
- s.add_dependency(%q<sinatra>.freeze, [">= 0"])
120
- s.add_dependency(%q<mocha>.freeze, [">= 0"])
121
- s.add_dependency(%q<coveralls>.freeze, [">= 0"])
122
- s.add_dependency(%q<shotgun>.freeze, [">= 0"])
123
- s.add_dependency(%q<guard>.freeze, [">= 0"])
124
- s.add_dependency(%q<guard-minitest>.freeze, [">= 0"])
125
- end
40
+ s.add_development_dependency("minitest", ">= 0")
41
+ s.add_development_dependency("mocha", ">= 0")
42
+ s.add_development_dependency("redis-namespace", ">= 1.5.2")
43
+ s.add_development_dependency("rack", "~> 2.0")
44
+ s.add_development_dependency("rack-test", "~> 1.0")
45
+ s.add_development_dependency("rake", "~> 13.0")
46
+ s.add_development_dependency("shoulda-context", ">= 0")
47
+ s.add_development_dependency("simplecov", ">= 0")
126
48
  end
127
-
@@ -5,10 +5,8 @@ require 'benchmark'
5
5
  describe 'Performance Poller' do
6
6
  X = 10000
7
7
  before do
8
+ REDIS.with { |c| c.respond_to?(:redis) ? c.redis.flushdb : c.flushdb }
8
9
  Sidekiq.redis = REDIS
9
- Sidekiq.redis do |conn|
10
- conn.flushdb
11
- end
12
10
 
13
11
  #clear all previous saved data from redis
14
12
  Sidekiq.redis do |conn|
@@ -33,7 +31,7 @@ describe 'Performance Poller' do
33
31
  Time.stubs(:now).returns(enqueued_time)
34
32
  end
35
33
 
36
- it 'should enqueue 10000 jobs in less than 30s' do
34
+ it 'should enqueue 10000 jobs in less than 50s' do
37
35
  Sidekiq.redis do |conn|
38
36
  assert_equal 0, conn.llen("queue:default"), 'Queue should be empty'
39
37
  end
@@ -47,6 +45,6 @@ describe 'Performance Poller' do
47
45
  end
48
46
 
49
47
  puts "Performance test finished in #{bench.real}"
50
- assert_operator bench.real, :<, 30
48
+ assert_operator bench.real, :<, 50
51
49
  end
52
50
  end
data/test/test_helper.rb CHANGED
@@ -1,12 +1,4 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
1
+ $TESTING = true
10
2
 
11
3
  require 'simplecov'
12
4
  SimpleCov.start do
@@ -14,24 +6,25 @@ SimpleCov.start do
14
6
 
15
7
  add_group 'SidekiqCron', 'lib/'
16
8
  end
17
- require 'coveralls'
18
- Coveralls.wear!
19
9
 
20
10
  require "minitest/autorun"
21
11
  require 'shoulda-context'
22
12
  require "rack/test"
23
- require "mocha/setup"
13
+ require 'mocha/minitest'
24
14
 
25
15
  ENV['RACK_ENV'] = 'test'
26
16
 
27
17
  #SIDEKIQ Require - need to have sidekiq running!
28
18
  require 'sidekiq'
29
- require 'sidekiq/util'
19
+ require "sidekiq-pro" if ENV['SIDEKIQ_PRO_VERSION']
20
+ require "sidekiq/processor"
21
+ require "sidekiq/fetch"
22
+ require "sidekiq/cli"
23
+
30
24
  require 'sidekiq/web'
31
25
 
32
26
  Sidekiq.logger.level = Logger::ERROR
33
27
 
34
- require 'sidekiq/redis_connection'
35
28
  redis_url = ENV['REDIS_URL'] || 'redis://0.0.0.0:6379'
36
29
  REDIS = Sidekiq::RedisConnection.create(:url => redis_url, :namespace => 'testy')
37
30
 
@@ -46,6 +39,13 @@ require 'sidekiq-cron'
46
39
  require 'sidekiq/cron/web'
47
40
  require 'pp'
48
41
 
42
+ # For testing os symbilize args!
43
+ class Hash
44
+ def symbolize_keys
45
+ transform_keys { |key| key.to_sym rescue key }
46
+ end
47
+ end
48
+
49
49
  class CronTestClass
50
50
  include Sidekiq::Worker
51
51
  sidekiq_options retry: true
@@ -66,6 +66,13 @@ end
66
66
 
67
67
  module ActiveJob
68
68
  class Base
69
+ attr_accessor *%i[job_class provider_job_id queue_name arguments]
70
+
71
+ def initialize
72
+ yield self if block_given?
73
+ self.provider_job_id ||= SecureRandom.hex(12)
74
+ end
75
+
69
76
  def self.queue_name_prefix
70
77
  @queue_name_prefix
71
78
  end
@@ -80,12 +87,16 @@ module ActiveJob
80
87
  self
81
88
  end
82
89
 
90
+ def try(method, *args, &block)
91
+ send method, *args, &block if respond_to? method
92
+ end
93
+
83
94
  def self.perform_later(*args)
84
- {
85
- "job_class" => self.class.name,
86
- "queue_name" => @queue,
87
- "args" => [*args],
88
- }
95
+ new do |instance|
96
+ instance.job_class = self.class.name
97
+ instance.queue_name = @queue
98
+ instance.arguments = [*args]
99
+ end
89
100
  end
90
101
  end
91
102
  end
@@ -223,6 +223,34 @@ describe "Cron Job" do
223
223
  "class"=>"CronTestClassWithQueue",
224
224
  "args"=>[]}
225
225
  end
226
+
227
+ it "be initialized with 'class' and date_as_argument" do
228
+ job = Sidekiq::Cron::Job.new('class' => 'CronTestClassWithQueue', "date_as_argument" => true)
229
+
230
+ job_message = job.message
231
+ job_args = job_message.delete("args")
232
+ assert_equal job_message, {"retry"=>false,
233
+ "queue"=>:super,
234
+ "backtrace"=>true,
235
+ "class"=>"CronTestClassWithQueue"}
236
+ assert job_args[-1].is_a?(Float)
237
+ assert job_args[-1].between?(Time.now.to_f - 1, Time.now.to_f)
238
+ end
239
+
240
+ it "be initialized with 'class', 2 arguments and date_as_argument" do
241
+ job = Sidekiq::Cron::Job.new('class' => 'CronTestClassWithQueue', "date_as_argument" => true, "args"=> ["arg1", :arg2])
242
+
243
+ job_message = job.message
244
+ job_args = job_message.delete("args")
245
+ assert_equal job_message, {"retry"=>false,
246
+ "queue"=>:super,
247
+ "backtrace"=>true,
248
+ "class"=>"CronTestClassWithQueue"}
249
+ assert job_args[-1].is_a?(Float)
250
+ assert job_args[-1].between?(Time.now.to_f - 1, Time.now.to_f)
251
+ assert_equal job_args[0..-2], ["arg1", :arg2]
252
+ end
253
+
226
254
  end
227
255
 
228
256
  describe "cron test" do
@@ -335,6 +363,108 @@ describe "Cron Job" do
335
363
  end
336
364
  end
337
365
 
366
+ describe '#active_job_message - unknown Active Job Worker class' do
367
+ before do
368
+ SecureRandom.stubs(:uuid).returns('XYZ')
369
+ ActiveJob::Base.queue_name_prefix = ''
370
+
371
+ @args = {
372
+ name: 'Test',
373
+ cron: '* * * * *',
374
+ klass: 'UnknownActiveJobCronTestClass',
375
+ active_job: true,
376
+ queue: 'super_queue',
377
+ description: nil,
378
+ args: { foo: 'bar' }
379
+ }
380
+ @job = Sidekiq::Cron::Job.new(@args)
381
+ end
382
+
383
+ it 'should return valid payload for Sidekiq::Client' do
384
+ payload = {
385
+ 'class' => 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper',
386
+ 'wrapped' => 'UnknownActiveJobCronTestClass',
387
+ 'queue' => 'super_queue',
388
+ 'description' => nil,
389
+ 'args' => [{
390
+ 'job_class' => 'UnknownActiveJobCronTestClass',
391
+ 'job_id' => 'XYZ',
392
+ 'queue_name' => 'super_queue',
393
+ 'arguments' => [{foo: 'bar'}]
394
+ }]
395
+ }
396
+ assert_equal @job.active_job_message, payload
397
+ end
398
+ end
399
+
400
+ describe '#active_job_message with symbolize_args (hash)' do
401
+ before do
402
+ SecureRandom.stubs(:uuid).returns('XYZ')
403
+ ActiveJob::Base.queue_name_prefix = ''
404
+
405
+ @args = {
406
+ name: 'Test',
407
+ cron: '* * * * *',
408
+ klass: 'ActiveJobCronTestClass',
409
+ queue: 'super_queue',
410
+ description: nil,
411
+ symbolize_args: true,
412
+ args: { 'foo' => 'bar' }
413
+ }
414
+ @job = Sidekiq::Cron::Job.new(@args)
415
+ end
416
+
417
+ it 'should return valid payload for Sidekiq::Client' do
418
+ payload = {
419
+ 'class' => 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper',
420
+ 'wrapped' => 'ActiveJobCronTestClass',
421
+ 'queue' => 'super_queue',
422
+ 'description' => nil,
423
+ 'args' => [{
424
+ 'job_class' => 'ActiveJobCronTestClass',
425
+ 'job_id' => 'XYZ',
426
+ 'queue_name' => 'super_queue',
427
+ 'arguments' => [{foo: 'bar'}]
428
+ }]
429
+ }
430
+ assert_equal @job.active_job_message, payload
431
+ end
432
+ end
433
+
434
+ describe '#active_job_message with symbolize_args (array)' do
435
+ before do
436
+ SecureRandom.stubs(:uuid).returns('XYZ')
437
+ ActiveJob::Base.queue_name_prefix = ''
438
+
439
+ @args = {
440
+ name: 'Test',
441
+ cron: '* * * * *',
442
+ klass: 'ActiveJobCronTestClass',
443
+ queue: 'super_queue',
444
+ description: nil,
445
+ symbolize_args: true,
446
+ args: [{ 'foo' => 'bar' }]
447
+ }
448
+ @job = Sidekiq::Cron::Job.new(@args)
449
+ end
450
+
451
+ it 'should return valid payload for Sidekiq::Client' do
452
+ payload = {
453
+ 'class' => 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper',
454
+ 'wrapped' => 'ActiveJobCronTestClass',
455
+ 'queue' => 'super_queue',
456
+ 'description' => nil,
457
+ 'args' => [{
458
+ 'job_class' => 'ActiveJobCronTestClass',
459
+ 'job_id' => 'XYZ',
460
+ 'queue_name' => 'super_queue',
461
+ 'arguments' => [{foo: 'bar'}]
462
+ }]
463
+ }
464
+ assert_equal @job.active_job_message, payload
465
+ end
466
+ end
467
+
338
468
  describe '#active_job_message with queue_name_prefix' do
339
469
  before do
340
470
  SecureRandom.stubs(:uuid).returns('XYZ')
@@ -381,7 +511,7 @@ describe "Cron Job" do
381
511
 
382
512
  it 'pushes to queue active jobs message' do
383
513
  @job.expects(:enqueue_active_job)
384
- .returns(true)
514
+ .returns(ActiveJobCronTestClass.new)
385
515
  @job.enque!
386
516
  end
387
517
  end
@@ -399,7 +529,7 @@ describe "Cron Job" do
399
529
 
400
530
  it 'pushes to queue active jobs message with queue_name_prefix' do
401
531
  @job.expects(:enqueue_active_job)
402
- .returns(true)
532
+ .returns(ActiveJobCronTestClass.new)
403
533
  @job.enque!
404
534
  end
405
535
  end
@@ -907,7 +1037,8 @@ describe "Cron Job" do
907
1037
  @jobs_hash['name_of_job']['cron'] = "bad cron"
908
1038
  out = Sidekiq::Cron::Job.load_from_hash @jobs_hash
909
1039
  assert_equal 1, out.size, "should have 1 error"
910
- assert_equal ({"name_of_job"=>["'cron' -> \"bad cron\" -> ArgumentError: not a cron string \"bad cron\""]}), out
1040
+ assert_includes out['name_of_job'].first, "bad cron"
1041
+ assert_includes out['name_of_job'].first, "ArgumentError:"
911
1042
  assert_equal 1, Sidekiq::Cron::Job.all.size, "Should have only 1 job after load"
912
1043
  end
913
1044
 
@@ -4,10 +4,8 @@ require './test/test_helper'
4
4
 
5
5
  describe 'Cron Poller' do
6
6
  before do
7
+ REDIS.with { |c| c.respond_to?(:redis) ? c.redis.flushdb : c.flushdb }
7
8
  Sidekiq.redis = REDIS
8
- Sidekiq.redis do |conn|
9
- conn.flushdb
10
- end
11
9
 
12
10
  #clear all previous saved data from redis
13
11
  Sidekiq.redis do |conn|