sidekiq-batch 0.1.0.pre → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 279810838005ed551056776d77629a5cb9f244c2
4
- data.tar.gz: d4f09f5eab7044a6811b69d2090f9ecf3ac53e02
3
+ metadata.gz: cf8a9c0f01008a49c2b6584a0b1238eb76e3db57
4
+ data.tar.gz: b30363e23b7e82c8092b5691089ebc61ed10cef2
5
5
  SHA512:
6
- metadata.gz: bcc10bdb6bc8e2188ebfe97b4382f9f9de9f83a283ff3c72fbdc98cebf899b1e4e360964ed0a8ef1fe42c9fbc4d4fcdcd6f280576afaa7dd4a07de8cc87a0967
7
- data.tar.gz: 2d646ba8e04fb71229bfe42f0cd5975e771b7c42ecd62c981fd5971709c229bb9e8a129ae13d1e22210fe3a5f1d7fed31f5ab5e083f46c937f7feba7fcec8a0b
6
+ metadata.gz: 761296bf005a0328ca8f152c776fbc1891e86b6e996ce4ead7cfe85f1c97b37b39111a2e6fb3950af2a228fc9b8aa427ce2666dc66b68dac27e87ab856db4751
7
+ data.tar.gz: 8b268734d9c29148eeb661fb6cdc3ba6c8ff08a128c4ca8bdf28e4f313007614189191242bab085a7a8f043667df50af75a87585bbd1c76af1207e120b70c209
data/.gitignore CHANGED
@@ -8,3 +8,4 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  dump.rdb
11
+ sidekiq-batch-*.gem
data/Gemfile CHANGED
@@ -1,4 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in sidekiq-batch.gemspec
4
3
  gemspec
4
+
5
+ group :test do
6
+ gem 'codeclimate-test-reporter'
7
+ end
data/README.md CHANGED
@@ -1,5 +1,15 @@
1
+ [gem]: https://rubygems.org/gems/sidekiq-batch
2
+ [travis]: https://travis-ci.org/breamware/sidekiq-batch
3
+ [codeclimate]: https://codeclimate.com/github/breamware/sidekiq-batch
4
+
1
5
  # Sidekiq::Batch
2
6
 
7
+ [![Gem Version](https://badge.fury.io/rb/sidekiq-batch.svg)][gem]
8
+ [![Build Status](https://travis-ci.org/breamware/sidekiq-batch.svg?branch=master)][travis]
9
+ [![Code Climate](https://codeclimate.com/github/breamware/sidekiq-batch/badges/gpa.svg)][codeclimate]
10
+ [![Code Climate](https://codeclimate.com/github/breamware/sidekiq-batch/badges/coverage.svg)][codeclimate]
11
+ [![Code Climate](https://codeclimate.com/github/breamware/sidekiq-batch/badges/issue_count.svg)][codeclimate]
12
+
3
13
  Simple Sidekiq Batch Job implementation.
4
14
 
5
15
  ## Installation
@@ -8,7 +8,7 @@ module Sidekiq
8
8
  return unless %w(success complete).include?(event)
9
9
  instance = clazz.constantize.send(:new) rescue nil
10
10
  return unless instance
11
- instance.send("on_#{event}", Status.new(bid), opts) rescue nil
11
+ instance.send("on_#{event}", Sidekiq::Batch::Status.new(bid), opts) rescue nil
12
12
  end
13
13
  end
14
14
 
@@ -16,13 +16,13 @@ module Sidekiq
16
16
  def call_if_needed(event, bid)
17
17
  needed = Sidekiq.redis do |r|
18
18
  r.multi do
19
- r.hget(bid, event)
20
- r.hset(bid, event, true)
19
+ r.hget("BID-#{bid}", event)
20
+ r.hset("BID-#{bid}", event, true)
21
21
  end
22
22
  end
23
23
  return if 'true' == needed[0]
24
24
  callback, opts, queue = Sidekiq.redis do |r|
25
- r.hmget(bid,
25
+ r.hmget("BID-#{bid}",
26
26
  "callback_#{event}", "callback_#{event}_opts",
27
27
  'callback_queue')
28
28
  end
@@ -33,6 +33,8 @@ module Sidekiq
33
33
  Sidekiq::Client.push('class' => Sidekiq::Batch::Callback::Worker,
34
34
  'args' => [callback, event, opts, bid],
35
35
  'queue' => queue)
36
+ ensure
37
+ Sidekiq::Batch.cleanup_redis(bid) if event == :success
36
38
  end
37
39
  end
38
40
  end
@@ -1,29 +1,10 @@
1
1
  module Sidekiq
2
2
  class Batch
3
3
  module Middleware
4
- def self.extended(base)
5
- base.class_eval do
6
- register_middleware
7
- end
8
- end
9
-
10
- def register_middleware
11
- Sidekiq.configure_server do |config|
12
- config.client_middleware do |chain|
13
- chain.add ClientMiddleware
14
- end
15
- config.server_middleware do |chain|
16
- chain.add ClientMiddleware
17
- chain.add ServerMiddleware
18
- end
19
- end
20
- end
21
-
22
4
  class ClientMiddleware
23
5
  def call(_worker, msg, _queue, _redis_pool = nil)
24
6
  if (bid = Thread.current[:bid])
25
- Batch.increment_job_queue(bid) if
26
- msg[:bid] = bid
7
+ Batch.increment_job_queue(bid) if (msg[:bid] = bid)
27
8
  end
28
9
  yield
29
10
  end
@@ -33,19 +14,45 @@ module Sidekiq
33
14
  def call(_worker, msg, _queue)
34
15
  if (bid = msg['bid'])
35
16
  begin
17
+ Thread.current[:bid] = bid
36
18
  yield
19
+ Thread.current[:bid] = nil
37
20
  Batch.process_successful_job(bid)
38
21
  rescue
39
22
  Batch.process_failed_job(bid, msg['jid'])
40
23
  raise
24
+ ensure
25
+ Thread.current[:bid] = nil
41
26
  end
42
27
  else
43
28
  yield
44
29
  end
45
30
  end
46
31
  end
32
+
33
+ def self.configure
34
+ Sidekiq.configure_client do |config|
35
+ config.client_middleware do |chain|
36
+ chain.add Sidekiq::Batch::Middleware::ClientMiddleware
37
+ end
38
+ end
39
+ Sidekiq.configure_server do |config|
40
+ config.client_middleware do |chain|
41
+ chain.add Sidekiq::Batch::Middleware::ClientMiddleware
42
+ end
43
+ config.server_middleware do |chain|
44
+ chain.add Sidekiq::Batch::Middleware::ServerMiddleware
45
+ end
46
+ end
47
+ Sidekiq::Worker.send(:define_method, 'bid') do
48
+ Thread.current[:bid]
49
+ end
50
+ Sidekiq::Worker.send(:define_method, 'batch') do
51
+ Sidekiq::Batch.new(Thread.current[:bid]) if Thread.current[:bid]
52
+ end
53
+ end
47
54
  end
48
55
  end
49
56
  end
50
57
 
51
- Sidekiq::Batch::Middleware.send(:extend, Sidekiq::Batch::Middleware)
58
+ Sidekiq::Batch::Middleware.configure
@@ -1,7 +1,7 @@
1
1
  module Sidekiq
2
2
  class Batch
3
3
  class Status
4
- attr_reader :bid, :total, :failures, :created_at, :failure_info
4
+ attr_reader :bid
5
5
 
6
6
  def initialize(bid)
7
7
  @bid = bid
@@ -12,11 +12,27 @@ module Sidekiq
12
12
  end
13
13
 
14
14
  def pending
15
- Sidekiq.redis { |r| r.get("#{bid}-to_process") }.to_i
15
+ Sidekiq.redis { |r| r.hget("BID-#{bid}", 'pending') }.to_i
16
+ end
17
+
18
+ def failures
19
+ Sidekiq.redis { |r| r.scard("BID-#{bid}-failed") }.to_i
20
+ end
21
+
22
+ def created_at
23
+ Sidekiq.redis { |r| r.hget("BID-#{bid}", 'created_at') }
24
+ end
25
+
26
+ def total
27
+ Sidekiq.redis { |r| r.hget("BID-#{bid}", 'total') }.to_i
28
+ end
29
+
30
+ def failure_info
31
+ Sidekiq.redis { |r| r.smembers("BID-#{bid}-failed") } || []
16
32
  end
17
33
 
18
34
  def complete?
19
- 'true' == Sidekiq.redis { |r| r.hget(bid, 'complete') }
35
+ 'true' == Sidekiq.redis { |r| r.hget("BID-#{bid}", 'complete') }
20
36
  end
21
37
 
22
38
  def data
@@ -1,5 +1,5 @@
1
1
  module Sidekiq
2
2
  class Batch
3
- VERSION = '0.1.0.pre'.freeze
3
+ VERSION = '0.1.0'.freeze
4
4
  end
5
5
  end
data/lib/sidekiq/batch.rb CHANGED
@@ -10,47 +10,70 @@ module Sidekiq
10
10
  class Batch
11
11
  class NoBlockGivenError < StandardError; end
12
12
 
13
+ BID_EXPIRE_TTL = 108_000
14
+
13
15
  attr_reader :bid, :description, :callback_queue
14
16
 
15
17
  def initialize(existing_bid = nil)
16
18
  @bid = existing_bid || SecureRandom.urlsafe_base64(10)
17
- Sidekiq.redis { |r| r.set("#{bid}-to_process", 0) }
19
+ Sidekiq.redis do |r|
20
+ r.multi do
21
+ r.hset("BID-#{bid}", 'created_at', Time.now)
22
+ r.expire("BID-#{bid}", BID_EXPIRE_TTL)
23
+ end
24
+ end
18
25
  end
19
26
 
20
27
  def description=(description)
21
28
  @description = description
22
- Sidekiq.redis { |r| r.hset(bid, 'description', description) }
29
+ persist_bid_attr('description', description)
23
30
  end
24
31
 
25
32
  def callback_queue=(callback_queue)
26
33
  @callback_queue = callback_queue
27
- Sidekiq.redis { |r| r.hset(bid, 'callback_queue', callback_queue) }
34
+ persist_bid_attr('callback_queue', callback_queue)
28
35
  end
29
36
 
30
37
  def on(event, callback, options = {})
31
38
  return unless %w(success complete).include?(event.to_s)
32
39
  Sidekiq.redis do |r|
33
- r.hset(bid, "callback_#{event}", callback)
34
- r.hset(bid, "callback_#{event}_opts", options.to_json)
40
+ r.multi do
41
+ r.hset("BID-#{bid}", "callback_#{event}", callback)
42
+ r.hset("BID-#{bid}", "callback_#{event}_opts", options.to_json)
43
+ r.expire("BID-#{bid}", BID_EXPIRE_TTL)
44
+ end
35
45
  end
36
46
  end
37
47
 
38
48
  def jobs
39
49
  raise NoBlockGivenError unless block_given?
40
50
 
41
- Batch.increment_job_queue(bid)
51
+ Sidekiq.redis { |r| r.hincrby("BID-#{bid}", 'to_process', 1) }
42
52
  Thread.current[:bid] = bid
43
53
  yield
44
- Batch.process_successful_job(bid)
54
+ Thread.current[:bid] = nil
55
+ Sidekiq.redis { |r| r.hincrby("BID-#{bid}", 'to_process', -1) }
56
+ end
57
+
58
+ private
59
+
60
+ def persist_bid_attr(attribute, value)
61
+ Sidekiq.redis do |r|
62
+ r.multi do
63
+ r.hset("BID-#{bid}", attribute, value)
64
+ r.expire("BID-#{bid}", BID_EXPIRE_TTL)
65
+ end
66
+ end
45
67
  end
46
68
 
47
69
  class << self
48
70
  def process_failed_job(bid, jid)
49
71
  to_process = Sidekiq.redis do |r|
50
72
  r.multi do
51
- r.sadd("#{bid}-failed", jid)
52
- r.scard("#{bid}-failed")
53
- r.get("#{bid}-to_process")
73
+ r.sadd("BID-#{bid}-failed", jid)
74
+ r.scard("BID-#{bid}-failed")
75
+ r.hget("BID-#{bid}", 'to_process')
76
+ r.expire("BID-#{bid}-failed", BID_EXPIRE_TTL)
54
77
  end
55
78
  end
56
79
  if to_process[2].to_i == to_process[1].to_i
@@ -59,20 +82,36 @@ module Sidekiq
59
82
  end
60
83
 
61
84
  def process_successful_job(bid)
62
- to_process = Sidekiq.redis do |r|
85
+ out = Sidekiq.redis do |r|
63
86
  r.multi do
64
- r.decr("#{bid}-to_process")
65
- r.get("#{bid}-to_process")
87
+ r.hincrby("BID-#{bid}", 'to_process', -1)
88
+ r.scard("BID-#{bid}-failed")
89
+ r.hincrby("BID-#{bid}", 'pending', -1)
90
+ r.expire("BID-#{bid}", BID_EXPIRE_TTL)
66
91
  end
67
92
  end
68
- if to_process[1].to_i == 0
69
- Callback.call_if_needed(:success, bid)
70
- Callback.call_if_needed(:complete, bid)
93
+
94
+ puts "processed process_successful_job"
95
+ Callback.call_if_needed(:complete, bid) if out[1].to_i == out[0].to_i
96
+ Callback.call_if_needed(:success, bid) if out[0].to_i.zero?
97
+ end
98
+
99
+ def cleanup_redis(bid)
100
+ Sidekiq.redis do |r|
101
+ r.del("BID-#{bid}",
102
+ "BID-#{bid}-failed")
71
103
  end
72
104
  end
73
105
 
74
106
  def increment_job_queue(bid)
75
- Sidekiq.redis { |r| r.incr("#{bid}-to_process") }
107
+ Sidekiq.redis do |r|
108
+ r.multi do
109
+ %w(to_process pending total).each do |c|
110
+ r.hincrby("BID-#{bid}", c, 1)
111
+ end
112
+ r.expire("BID-#{bid}", BID_EXPIRE_TTL)
113
+ end
114
+ end
76
115
  end
77
116
  end
78
117
  end
@@ -19,9 +19,10 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency "sidekiq", "~> 4"
22
+ spec.add_dependency "sidekiq", "~> 3"
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.12"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "fakeredis", "~> 0.5.0"
27
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-batch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcin Naglik
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-22 00:00:00.000000000 Z
11
+ date: 2016-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4'
19
+ version: '3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4'
26
+ version: '3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: fakeredis
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.5.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.5.0
69
83
  description: Sidekiq Batch Jobs Implementation
70
84
  email:
71
85
  - marcin.naglik@gmail.com
@@ -102,9 +116,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
116
  version: '0'
103
117
  required_rubygems_version: !ruby/object:Gem::Requirement
104
118
  requirements:
105
- - - ">"
119
+ - - ">="
106
120
  - !ruby/object:Gem::Version
107
- version: 1.3.1
121
+ version: '0'
108
122
  requirements: []
109
123
  rubyforge_project:
110
124
  rubygems_version: 2.5.1