sidekiq-merger 0.0.1 → 0.0.4

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: 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