sidekiq-merger 0.0.1 → 0.0.4

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: 668c85fb3075147efdfbfacd83b1f6cad5766249
4
- data.tar.gz: ef35056d67ce049cf7b0c3c328cd04f91b01a77c
3
+ metadata.gz: 4bed498597132701a71bf77a583f97668ce5264c
4
+ data.tar.gz: 66244be154087fca1647ba21d7b12727167d5106
5
5
  SHA512:
6
- metadata.gz: 031c84fa7cbf1cebe5e21244a1e7bfa85aa3d3c0a496652b825490aa2a24716cbf4bde327d4ef3e19bd099a403ef7104aa7c2d23e6d60a680ad908b7ea875628
7
- data.tar.gz: ab858f4ad9cfafe67f7a837f42df0770b329d14b5a756d2d3c0e0109e6bb10aac23694a24522cead863ea09430a8a3ad7a2e195bf23b90ec5fb0c1e0f5daac05
6
+ metadata.gz: 01887441761e31726a0c4cb6feff20e55be5202c3fa9c3d00a43ff28b54589c484ddd95f305ac0c589972e27c05c4ae46201ca408af32ee0904aae2b80827e16
7
+ data.tar.gz: 762fca326555feada8466a1eeda5acf2189a8f9e1b2b979e2568b90ccddbc5371d840833f106640889f1f69a744ce79bfa29ee932cf1f905370586375a74830b
data/.dockerignore ADDED
@@ -0,0 +1,21 @@
1
+ .bundle/
2
+ .yardoc
3
+ Gemfile.lock
4
+ _yardoc/
5
+ coverage/
6
+ doc/
7
+ pkg/
8
+ spec/reports/
9
+ tmp/
10
+ rdoc/
11
+
12
+ *.gem
13
+ *.rbc
14
+
15
+ .ruby-version
16
+ .ruby-gemset
17
+ .rvmrc
18
+
19
+ .env
20
+
21
+ .dockerignore
data/.gemrelease ADDED
@@ -0,0 +1,2 @@
1
+ bump:
2
+ tag: true
data/.gitignore CHANGED
@@ -1,9 +1,19 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
1
+ .bundle/
2
+ .yardoc
3
+ Gemfile.lock
4
+ _yardoc/
5
+ coverage/
6
+ doc/
7
+ pkg/
8
+ spec/reports/
9
+ tmp/
10
+ rdoc/
11
+
12
+ *.gem
13
+ *.rbc
14
+
15
+ .ruby-version
16
+ .ruby-gemset
17
+ .rvmrc
18
+
19
+ .env
data/.travis.yml CHANGED
@@ -4,7 +4,11 @@ rvm:
4
4
  - 2.2.6
5
5
  - 2.3.3
6
6
  - 2.4.0
7
- before_install: gem install bundler -v 1.13.6
7
+ services:
8
+ - redis-server
9
+ before_install:
10
+ - gem update --system
11
+ - gem --version
8
12
  script:
9
13
  - "bundle exec rake spec"
10
14
  - "bundle exec rubocop -D"
data/Dockerfile ADDED
@@ -0,0 +1,10 @@
1
+ FROM ruby:2.3.3
2
+ MAINTAINER dtaniwaki
3
+
4
+ ENV PORT ${PORT:-3000}
5
+ RUN gem install bundler
6
+ ADD . /gem
7
+ WORKDIR /gem/app
8
+ RUN bundle install -j4
9
+
10
+ EXPOSE 3000
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in sidekiq-lazy-batch.gemspec
4
3
  gemspec
4
+
5
+ gem "gem-release"
6
+ gem "pry"
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![Coverage Status][cov-image]][cov-link]
7
7
  [![Code Climate][gpa-image]][gpa-link]
8
8
 
9
- Merge sidekiq jobs occurring within specific period.
9
+ Merge sidekiq jobs occurring within specific period. This sidekiq middleware is inspired by [sidekiq-grouping](https://github.com/gzigzigzeo/sidekiq-grouping).
10
10
 
11
11
  ## Installation
12
12
 
@@ -18,28 +18,90 @@ gem 'sidekiq-merger'
18
18
 
19
19
  And then execute:
20
20
 
21
- $ bundle
21
+ $ bundle
22
22
 
23
23
  Or install it yourself as:
24
24
 
25
- $ gem install sidekiq-merger
25
+ $ gem install sidekiq-merger
26
26
 
27
27
  ## Usage
28
28
 
29
29
  Add merger option into your workers.
30
30
 
31
- ```
32
- class YourWorker
31
+ ```ruby
32
+ class SomeWorker
33
33
  include Sidekiq::Worker
34
34
 
35
35
  sidekiq_options merger: { key: -> (args) { args[0] } }
36
36
 
37
- def perform(all_args)
37
+ def perform(*ids)
38
38
  # Do something
39
39
  end
40
40
  end
41
41
  ```
42
42
 
43
+ Then, enqueue jobs by `perform_in` or `perform_at`.
44
+
45
+ ```ruby
46
+ SomeWorker.perform_in 100, 4
47
+ SomeWorker.perform_in 100, 3
48
+ SomeWorker.perform_in 100, 5
49
+ ```
50
+
51
+ `SomeWorker` will be executed in 100 seconds with args of `[4], [3], [5]`.
52
+
53
+ `perform_async` works without merging args.
54
+
55
+ ```ruby
56
+ SomeWorker.perform_async 4
57
+ SomeWorker.perform_async 3
58
+ SomeWorker.perform_async 5
59
+ ```
60
+
61
+ In this case, `SomeWorker` will be executed 3 times with args of `[4]`, `[3]` and `[5]`.
62
+
63
+ ## Options
64
+
65
+ ### `key` (optional, default: `nil`)
66
+
67
+ Defines merge key so different arguments can be merged.
68
+
69
+ Format: `String` or `Proc`
70
+ e.g. `sidekiq_options merger: { key: -> (args) { args[0..1] } }`
71
+
72
+ ### `unique` (optional, default: `false`)
73
+
74
+ Prevents enqueue of jobs with identical arguments.
75
+
76
+ Format: `Boolean`
77
+ e.g. `true`
78
+
79
+ ## Web UI
80
+
81
+ ![Web UI](misc/web_ui.png)
82
+
83
+ Add this line to your `config/routes.rb` to activate web UI:
84
+
85
+ ```ruby
86
+ require "sidekiq/merger/web"
87
+ ```
88
+
89
+ ## Test
90
+
91
+ $ bundle exec rspec
92
+
93
+ The test coverage is available at `./coverage/index.html`.
94
+
95
+ To check the behavior of this plugin, you can run docker containers.
96
+
97
+ $ docker-compose up
98
+
99
+ Then, open `http://localhost:3000/`.
100
+
101
+ ## Lint
102
+
103
+ $ bundle exec rubocop
104
+
43
105
  ## Contributing
44
106
 
45
107
  1. Fork it
data/app/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rack-flash3"
4
+ gem "sinatra"
5
+ gem "sidekiq"
6
+ gem "sidekiq-status"
7
+
8
+ gem "sidekiq-merger", path: "../"
data/app/app.rb ADDED
@@ -0,0 +1,43 @@
1
+ require_relative "./sidekiq"
2
+ require "sinatra/base"
3
+ require "rack/flash"
4
+ require "sidekiq/web"
5
+ require "sidekiq-status/web"
6
+ require "sidekiq/merger/web"
7
+
8
+ class App < Sinatra::Application
9
+ enable :sessions
10
+ use Rack::Flash
11
+
12
+ get "/" do
13
+ erb :index
14
+ end
15
+
16
+ post "/some_worker/perform_in" do
17
+ n = rand(10)
18
+ SomeWorker.perform_in((params[:in] || 60).to_i, n)
19
+ flash[:notice] = "Added #{n} to SomeWorker"
20
+ redirect "/"
21
+ end
22
+
23
+ post "/some_worker/perform_async" do
24
+ n = rand(10)
25
+ SomeWorker.perform_async(n)
26
+ flash[:notice] = "Added #{n} to SomeWorker"
27
+ redirect "/"
28
+ end
29
+
30
+ post "/unique_worker/perform_in" do
31
+ n = rand(10)
32
+ UniqueWorker.perform_in((params[:in] || 60).to_i, n)
33
+ flash[:notice] = "Added #{n} to UniqueWorker"
34
+ redirect "/"
35
+ end
36
+
37
+ post "/unique_worker/perform_async" do
38
+ n = rand(10)
39
+ UniqueWorker.perform_async(n)
40
+ flash[:notice] = "Added #{n} to UniqueWorker"
41
+ redirect "/"
42
+ end
43
+ end
data/app/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require "./app"
2
+
3
+ run Rack::URLMap.new("/" => App, "/sidekiq" => Sidekiq::Web)
data/app/sidekiq.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "active_support/core_ext/numeric/time"
2
+ require "sidekiq"
3
+ require "sidekiq-status"
4
+ require "sidekiq-merger"
5
+ require_relative "./some_worker"
6
+ require_relative "./unique_worker"
7
+
8
+ expiration = 30.minutes
9
+
10
+ Sidekiq.configure_client do |config|
11
+ config.redis = { url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}" }
12
+ config.client_middleware do |chain|
13
+ chain.add Sidekiq::Status::ClientMiddleware, expiration: expiration
14
+ end
15
+ end
16
+
17
+ Sidekiq.configure_server do |config|
18
+ config.redis = { url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}" }
19
+ config.server_middleware do |chain|
20
+ chain.add Sidekiq::Status::ServerMiddleware, expiration: expiration
21
+ end
22
+ config.client_middleware do |chain|
23
+ chain.add Sidekiq::Status::ClientMiddleware, expiration: expiration
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ class SomeWorker
2
+ include Sidekiq::Worker
3
+
4
+ sidekiq_options merger: { key: "foo" }
5
+
6
+ def perform(*ids)
7
+ puts "Get IDs: #{ids.inspect}"
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class UniqueWorker
2
+ include Sidekiq::Worker
3
+
4
+ sidekiq_options merger: { key: "foo", unique: true }
5
+
6
+ def perform(*ids)
7
+ puts "Get IDs: #{ids.inspect}"
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="UTF-8">
4
+ </head>
5
+ <body>
6
+ <h1>Sidekiq Merger</h1>
7
+ <% if flash[:notice] %>
8
+ <p style="color: green; font-weight: bold;"><%= flash[:notice] %></p>
9
+ <% end %>
10
+ <p>
11
+ <a href="/sidekiq" target="_blank">Open sidekiq console</a>
12
+ </p>
13
+ <h2>Workers</h2>
14
+ <div style="margin-left: 20px;">
15
+ <h3>SomeWorker</h3>
16
+ <div>
17
+ <form action="/some_worker/perform_in" method="post" style="display: inline-block;">
18
+ <input type="submit" name="perform_in" value="perform_in">
19
+ </form>
20
+ <form action="/some_worker/perform_in" method="post" style="display: inline-block;">
21
+ <input type="submit" name="perform_async" value="perform_async">
22
+ </form>
23
+ </div>
24
+ <h3>UniqueWorker</h3>
25
+ <div>
26
+ <form action="/some_worker/perform_in" method="post" style="display: inline-block;">
27
+ <input type="submit" name="perform_in" value="perform_in">
28
+ </form>
29
+ <form action="/some_worker/perform_in" method="post" style="display: inline-block;">
30
+ <input type="submit" name="perform_async" value="perform_async">
31
+ </form>
32
+ </div>
33
+ </div>
34
+ </body>
35
+ </html>
@@ -0,0 +1,7 @@
1
+ version: '2.1'
2
+ services:
3
+ app:
4
+ build: .
5
+ environment:
6
+ - REDIS_HOST=redis
7
+ - REDIS_PORT=6379
@@ -0,0 +1,26 @@
1
+ version: '2.1'
2
+ services:
3
+ worker:
4
+ extends:
5
+ file: 'docker-compose-common.yml'
6
+ service: app
7
+ command: bundle exec sidekiq -r ./sidekiq.rb
8
+ links:
9
+ - redis
10
+ environment:
11
+ - REDIS_HOST=redis
12
+ - REDIS_PORT=6379
13
+ web:
14
+ extends:
15
+ file: 'docker-compose-common.yml'
16
+ service: app
17
+ command: bundle exec rackup -p 3000 --host 0.0.0.0
18
+ ports:
19
+ - 3000:3000
20
+ links:
21
+ - redis
22
+ environment:
23
+ - REDIS_HOST=redis
24
+ - REDIS_PORT=6379
25
+ redis:
26
+ image: redis:latest
@@ -9,25 +9,21 @@ require_relative "merger/logging_observer"
9
9
  module Sidekiq::Merger
10
10
  class << self
11
11
  attr_accessor :logger
12
- end
13
-
14
- self.logger ||= Sidekiq.logger
15
12
 
16
- def logger
17
- self.class.logger
13
+ def start!
14
+ interval = Sidekiq::Merger::Config.poll_interval
15
+ observer = Sidekiq::Merger::LoggingObserver.new(logger)
16
+ flusher = Sidekiq::Merger::Flusher.new(logger)
17
+ task = Concurrent::TimerTask.new(
18
+ execution_interval: interval
19
+ ) { flusher.flush }
20
+ task.add_observer(observer)
21
+ logger.info(
22
+ "[Sidekiq::Merger] Started polling merges every #{interval} seconds"
23
+ )
24
+ task.execute
25
+ end
18
26
  end
19
27
 
20
- def start!
21
- interval = Sidekiq::Merger::Config.poll_interval
22
- observer = Sidekiq::Merger::LoggingObserver.new(logger)
23
- flusher = Sidekiq::Merger::Flusher.new(logger)
24
- task = Concurrent::TimerTask.new(
25
- execution_interval: interval
26
- ) { flusher.flush }
27
- task.add_observer(observer)
28
- logger.info(
29
- "[Sidekiq::Merger] Started polling batches every #{interval} seconds"
30
- )
31
- task.execute
32
- end
28
+ self.logger = Sidekiq.logger
33
29
  end
@@ -4,12 +4,12 @@ class Sidekiq::Merger::Flusher
4
4
  end
5
5
 
6
6
  def flush
7
- batches = Sidekiq::Merger::Batch.all.select(&:can_flush?)
8
- unless batches.empty?
7
+ merges = Sidekiq::Merger::Merge.all.select(&:can_flush?)
8
+ unless merges.empty?
9
9
  @logger.info(
10
- "[Sidekiq::Merger] Trying to flush batched queues: #{batches.map(&:full_batch_key).join(",")}"
10
+ "[Sidekiq::Merger] Trying to flush merged queues: #{merges.map(&:full_merge_key).join(",")}"
11
11
  )
12
- batches.each(&:flush)
12
+ merges.each(&:flush)
13
13
  end
14
14
  end
15
15
  end