sidekiq-reliable-fetch 0.1.0 → 0.2.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: 35c020c4d73f87e39a4b5fa52930e42505c8e866
4
- data.tar.gz: 1d344483e74a309efe9db2355450f20a0d5f4487
3
+ metadata.gz: 803136d2fb9cf9eb4f60b0b54618e489616d763a
4
+ data.tar.gz: 8371867f1f2ce011d710d91dd0d2a3a09ab1c739
5
5
  SHA512:
6
- metadata.gz: 755c4623df1d7d672bb4c857ca53cb4b2e12d9d3e0f1cbbb37b7eb42a4f93dbba639bf91f8588607e7570eef27d50996e637f3a71d6920a8aaacdb62b9d273f5
7
- data.tar.gz: 6c76f3015bfc44f03285d151625cf3ee88024b97c8df6c970b72140290948b8625a550fccbf93f90f3291483175dd382d63f8527742269b54046271ac3be62e6
6
+ metadata.gz: ac47ebe55522819896e610f2b8bc59f69026d23967fe5611c32e6383c13ac14732ebd4f7d1884368ac43e967f958ff4b3441178407e2bdedbb8cecb00f9d55f8
7
+ data.tar.gz: 2a8f9651f266ddb272fbba06f149b7879b9f406f92a90ea74b09f9772048f900c147a48832dc7d47374093742281073065b72aeb2a660165e067b3eb0170d7c8
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ sidekiq-reliable-fetch
2
+ ======================
3
+
4
+ sidekiq-reliable-fetch is an extension to Sidekiq that adds support for reliable
5
+ fetches from Redis.
6
+
7
+ It implements in Sidekiq the reliable queue pattern using [Redis' rpoplpush
8
+ command](http://redis.io/commands/rpoplpush#pattern-reliable-queue).
9
+
10
+ ## Installation
11
+
12
+ Add the following to your `Gemfile`:
13
+
14
+ ```ruby
15
+ gem 'sidekiq-reliable-fetch'
16
+ ```
17
+
18
+ ## Configuration
19
+
20
+ Enable reliable fetches by calling this gem from your Sidekiq configuration:
21
+
22
+ ```ruby
23
+ Sidekiq.configure_server do |config|
24
+ Sidekiq::ReliableFetcher.setup_reliable_fetch!(config)
25
+
26
+ # …
27
+ end
28
+ ```
29
+
30
+ ## License
31
+
32
+ LGPL-3.0, see the LICENSE file.
@@ -2,7 +2,8 @@ module Sidekiq
2
2
  class ReliableFetcher
3
3
  WORKING_QUEUE = 'working'
4
4
  DEFAULT_DEAD_AFTER = 60 * 60 * 24 # 24 hours
5
- DEFAULT_CLEANING_INTERVAL = 60 * 30 # 30 minutes
5
+ DEFAULT_CLEANING_INTERVAL = 5000 # clean each N processed jobs
6
+ IDLE_TIMEOUT = 5 # seconds
6
7
 
7
8
  def self.setup_reliable_fetch!(config)
8
9
  config.options[:fetch] = Sidekiq::ReliableFetcher
@@ -12,20 +13,35 @@ module Sidekiq
12
13
  end
13
14
 
14
15
  def initialize(options)
15
- @strictly_ordered_queues = !!options[:strict]
16
- @queues = options[:queues].map { |q| "queue:#{q}" }
17
- @unique_queues = @queues.uniq
18
- @last_clean = Time.now.to_i
16
+ queues = options[:queues].map { |q| "queue:#{q}" }
17
+
18
+ @unique_queues = queues.uniq
19
+ @queues_iterator = queues.shuffle.cycle
20
+ @queues_size = queues.size
21
+
22
+ @nb_fetched_jobs = 0
19
23
  @cleaning_interval = options[:cleaning_interval] || DEFAULT_CLEANING_INTERVAL
20
24
  @consider_dead_after = options[:consider_dead_after] || DEFAULT_DEAD_AFTER
21
25
  end
22
26
 
23
27
  def retrieve_work
24
- clean_working_queues! if @cleaning_interval != -1 && Time.now.to_i - @last_clean > @cleaning_interval
28
+ clean_working_queues! if @cleaning_interval != -1 && @nb_fetched_jobs >= @cleaning_interval
29
+
30
+ for i in 0..@queues_size
31
+ queue = @queues_iterator.next
32
+ work = Sidekiq.redis { |conn| conn.rpoplpush(queue, "#{queue}:#{WORKING_QUEUE}") }
33
+
34
+ if work
35
+ @nb_fetched_jobs += 1
36
+ return UnitOfWork.new(queue, work)
37
+ end
38
+ end
25
39
 
26
- queue = pick_queue
27
- work = Sidekiq.redis { |conn| conn.brpoplpush(queue, "#{queue}:#{WORKING_QUEUE}", Sidekiq::Fetcher::TIMEOUT) }
28
- UnitOfWork.new(queue, work) if work
40
+ # We didn't find a job in any of the configured queues. Let's sleep a bit
41
+ # to avoid uselessly burning too much CPU
42
+ sleep(IDLE_TIMEOUT)
43
+
44
+ nil
29
45
  end
30
46
 
31
47
  def self.requeue_on_startup!(queues)
@@ -90,16 +106,6 @@ module Sidekiq
90
106
 
91
107
  private
92
108
 
93
- # Creating the Redis#brpoplpush command takes into account any
94
- # configured queue weights. By default Redis#brpoplpush returns
95
- # data from the first queue that has pending elements. We
96
- # choose the queue each time we invoke Redis#brpoplpush to honor weights
97
- # and avoid queue starvation.
98
- def pick_queue
99
- queues = @strictly_ordered_queues ? @unique_queues.dup : @queues.shuffle.uniq
100
- queues.first
101
- end
102
-
103
109
  # Detect "old" jobs and requeue them because the worker they were assigned
104
110
  # to probably failed miserably.
105
111
  # NOTE Potential problem here if a specific job always make a worker
@@ -111,7 +117,7 @@ module Sidekiq
111
117
  clean_working_queue!(queue)
112
118
  end
113
119
 
114
- @last_clean = Time.now.to_i
120
+ @nb_fetched_jobs = 0
115
121
  end
116
122
 
117
123
  def clean_working_queue!(queue)
@@ -121,12 +127,12 @@ module Sidekiq
121
127
  enqueued_at = Sidekiq.load_json(job)['enqueued_at'].to_i
122
128
  job_duration = Time.now.to_i - enqueued_at
123
129
 
124
- if job_duration > @consider_dead_after
125
- Sidekiq.logger.info "Requeued a dead job found in #{queue}:#{WORKING_QUEUE}"
130
+ next if job_duration < @consider_dead_after
126
131
 
127
- conn.rpush("#{queue}", job)
128
- conn.lrem("#{queue}:#{WORKING_QUEUE}", 1, job)
129
- end
132
+ Sidekiq.logger.info "Requeued a dead job from #{queue}:#{WORKING_QUEUE}"
133
+
134
+ conn.rpush("#{queue}", job)
135
+ conn.lrem("#{queue}:#{WORKING_QUEUE}", 1, job)
130
136
  end
131
137
  end
132
138
  end
@@ -7,7 +7,6 @@ module SidekiqReliableFetch
7
7
 
8
8
  def self.registered(app)
9
9
  app.get '/working' do
10
- puts VIEW_PATH.inspect
11
10
  @queues = SidekiqReliableFetch::WorkingQueue.all
12
11
  erb File.read(File.join(VIEW_PATH, 'working_queues.erb'))
13
12
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'sidekiq-reliable-fetch'
3
- s.version = '0.1.0'
3
+ s.version = '0.2.0'
4
4
  s.authors = ['TEA']
5
5
  s.email = 'technique@tea-ebook.com'
6
6
  s.license = 'LGPL-3.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-reliable-fetch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TEA
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-26 00:00:00.000000000 Z
11
+ date: 2016-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -32,6 +32,7 @@ extra_rdoc_files: []
32
32
  files:
33
33
  - ".gitignore"
34
34
  - LICENSE
35
+ - README.md
35
36
  - lib/sidekiq-reliable-fetch.rb
36
37
  - lib/sidekiq-reliable-fetch/api.rb
37
38
  - lib/sidekiq-reliable-fetch/web.rb