sidekiq-batch 0.1.0.pre → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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