chewy_resque 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +10 -0
- data/chewy_resque.gemspec +32 -0
- data/lib/chewy_resque.rb +13 -0
- data/lib/chewy_resque/config.rb +23 -0
- data/lib/chewy_resque/index.rb +36 -0
- data/lib/chewy_resque/log_subscriber.rb +23 -0
- data/lib/chewy_resque/mixin.rb +52 -0
- data/lib/chewy_resque/railtie.rb +7 -0
- data/lib/chewy_resque/version.rb +3 -0
- data/lib/chewy_resque/worker.rb +45 -0
- data/spec/config_spec.rb +29 -0
- data/spec/index_spec.rb +51 -0
- data/spec/log_subscriber_spec.rb +38 -0
- data/spec/mixin_spec.rb +70 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/worker_spec.rb +18 -0
- metadata +212 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2561d103b0c172673e93d9e6e3e5d94bc96a1a56
|
4
|
+
data.tar.gz: 270b2ce4fec791cb27a6fbbf664e308c807dc94d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5296adaa7587deabc268e6141a8c940bcb0864f34ed1c758d91cee0901e76bf4bc351938ef23ba105deda1f03e0df1313e127463604be946a49ac5142b56cf1d
|
7
|
+
data.tar.gz: 479a7a117c8e05b837ab46d677b3891590018f296aff90ff445e6068f29982fcc32dc3fab1f10bb1f4d33b775bcb9c4adb349888df519c81d5c4ed9b93287c8c
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Daniel Hahn
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# ChewyResque
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/razum2um/chewy_resque.svg?branch=master)](https://travis-ci.org/razum2um/chewy_kiqqer)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/razum2um/chewy_resque.png)](https://codeclimate.com/github/razum2um/chewy_kiqqer)
|
5
|
+
[![Test Coverage](https://codeclimate.com/github/razum2um/chewy_resque/coverage.png)](https://codeclimate.com/github/razum2um/chewy_kiqqer)
|
6
|
+
|
7
|
+
This is an alternative udpate/callback mechanism for [Chewy](https://github.com/toptal/chewy). It queues the updates as [Resque](https://github.com/resque/resque) jobs.
|
8
|
+
|
9
|
+
You can pass backrefs like with the standard chewy mechanism, but the job itself will always receive an array of ids.
|
10
|
+
|
11
|
+
It is possible to install more multiple update hooks.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
gem 'chewy_resque'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install chewy_resque
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
Just add the module and set it up:
|
30
|
+
|
31
|
+
class User < ActiveRecord::Base
|
32
|
+
include ChewyResque::Mixin
|
33
|
+
|
34
|
+
async_update_index index: 'users#user', backref: :something
|
35
|
+
end
|
36
|
+
|
37
|
+
Giving a backref is also optional (also check the chewy docs for the concept). The backref is the element
|
38
|
+
which will be indexed. The default is to use the current record.
|
39
|
+
|
40
|
+
# use the current record for the backref
|
41
|
+
... backref: :self
|
42
|
+
# call a method on the current record to get the backref
|
43
|
+
... backref: :some_method
|
44
|
+
# Pass a proc. It will be called with the current record to get the backref
|
45
|
+
... backref: -> (rec) { |rec| rec.do_something }
|
46
|
+
|
47
|
+
## Update handling
|
48
|
+
|
49
|
+
The resque does *not* use Chewy's `atomic` update, since that functionality is deeply linked with Chewy's syncronous update mechanism.
|
50
|
+
|
51
|
+
|
52
|
+
However, if you have multiple database transactions, the resque will still queue multiple jobs. The same is true when you enqueue jobs manually.
|
53
|
+
|
54
|
+
ChewyResque uses locking via redis to ensure that all updates for one database record are run sequentially. This prevents race conditions which could lead to outdated data being written to the index otherwise.
|
55
|
+
|
56
|
+
## Logging
|
57
|
+
|
58
|
+
Logging is disabled by default, but you can set `ChewyResque.logger` if you need log output (e.g. `ChewyResque.logger = Rails.logger`). ChewyResque uses ActiveSupport notifications, which you can also subscribe to.
|
59
|
+
See `log_subscriber.rb` for more info.
|
60
|
+
|
61
|
+
## Acknoledgements
|
62
|
+
|
63
|
+
This gem is heavily borrowed from [chewy_kiqqer](https://github.com/averell23/chewy_kiqqer).
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
1. Fork it
|
68
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
70
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
71
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'chewy_resque/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "chewy_resque"
|
8
|
+
spec.version = ChewyResque::VERSION
|
9
|
+
spec.authors = ["Vlad Bokov"]
|
10
|
+
spec.email = ["bokov.vlad@gmail.com"]
|
11
|
+
spec.description = %q{Resque integration for chewy and resque}
|
12
|
+
spec.summary = %q{Small helper gem that allows you to automatically run all chewy index updates in resque}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "Apache V2"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'resque', '~> 1.24'
|
22
|
+
spec.add_dependency 'chewy'
|
23
|
+
spec.add_dependency 'mlanett-redis-lock'
|
24
|
+
spec.add_dependency 'activesupport', '>= 3.2.0'
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "kaminari"
|
29
|
+
spec.add_development_dependency "rspec"
|
30
|
+
spec.add_development_dependency "pry-byebug"
|
31
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
32
|
+
end
|
data/lib/chewy_resque.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_support/notifications'
|
2
|
+
require 'active_support/log_subscriber'
|
3
|
+
|
4
|
+
require "chewy_resque/version"
|
5
|
+
require "chewy_resque/mixin"
|
6
|
+
require "chewy_resque/worker"
|
7
|
+
require "chewy_resque/index"
|
8
|
+
require "chewy_resque/config"
|
9
|
+
require "chewy_resque/log_subscriber"
|
10
|
+
|
11
|
+
require "chewy_resque/railtie" if defined?(::Rails)
|
12
|
+
|
13
|
+
ChewyResque::LogSubscriber.attach_to 'chewy_resque'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module ChewyResque
|
4
|
+
|
5
|
+
def self.logger
|
6
|
+
@logger || Logger.new(STDOUT)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.logger=(value)
|
10
|
+
@logger = value
|
11
|
+
end
|
12
|
+
|
13
|
+
# Locking scope for redis locks. Only necessary if
|
14
|
+
# one redis instances locks more than one application
|
15
|
+
def self.locking_scope=(value)
|
16
|
+
@locking_scope = value
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.locking_scope
|
20
|
+
@locking_scope || 'chewy'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
require 'resque'
|
3
|
+
|
4
|
+
module ChewyResque
|
5
|
+
class Index
|
6
|
+
|
7
|
+
attr_reader :index_name
|
8
|
+
|
9
|
+
def initialize(backref: :self, index: nil, queue: nil, only_if: nil)
|
10
|
+
@only_if = only_if
|
11
|
+
@index_name = index
|
12
|
+
@backref_method = backref
|
13
|
+
@queue = queue
|
14
|
+
end
|
15
|
+
|
16
|
+
def enqueue(object)
|
17
|
+
return if @only_if.respond_to?(:call) && @only_if.call(object)
|
18
|
+
if (ids = backref_ids(object).compact).present?
|
19
|
+
Resque.enqueue_to(@queue || Resque.queue_from_class(ChewyResque::Worker),
|
20
|
+
ChewyResque::Worker,
|
21
|
+
@index_name,
|
22
|
+
ids)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def backref(object)
|
27
|
+
return @backref_method.call(object) if @backref_method.respond_to?(:call)
|
28
|
+
return object if @backref_method.to_s == 'self'
|
29
|
+
object.send(@backref_method)
|
30
|
+
end
|
31
|
+
|
32
|
+
def backref_ids(object)
|
33
|
+
Array.wrap(backref(object)).map { |object| object.respond_to?(:id) ? object.id : object.to_i }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ChewyResque
|
2
|
+
|
3
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
4
|
+
|
5
|
+
def perform(event)
|
6
|
+
info "ChewyResque job ran on #{event.payload[:index_name]} with ids #{event.payload[:ids]} - duration #{event.duration}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def index(event)
|
10
|
+
debug "ChewyResque index updated on #{event.payload[:index_name]} with ids #{event.payload[:ids]} - duration #{event.duration}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def queue_jobs(event)
|
14
|
+
debug "ChewyResque queued jobs from #{event.payload[:class]} #{event.payload[:id]}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def logger
|
18
|
+
ChewyResque.logger
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/core_ext/array/wrap'
|
3
|
+
|
4
|
+
module ChewyResque
|
5
|
+
|
6
|
+
def self.default_queue=(queue)
|
7
|
+
@default_queue = queue
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.default_queue
|
11
|
+
@default_queue || 'default'
|
12
|
+
end
|
13
|
+
|
14
|
+
module Mixin
|
15
|
+
|
16
|
+
extend ActiveSupport::Concern
|
17
|
+
|
18
|
+
included do
|
19
|
+
class_attribute :indexers
|
20
|
+
self.indexers = []
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
def async_update_index(index, queue: nil, backref: :self, only_if: nil)
|
26
|
+
install_chewy_hooks if indexers.empty? # Only install them once
|
27
|
+
indexers << ChewyResque::Index.new(index: index, queue: queue, backref: backref, only_if: only_if)
|
28
|
+
end
|
29
|
+
|
30
|
+
def install_chewy_hooks
|
31
|
+
after_commit :queue_chewy_jobs
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def queue_chewy_jobs
|
36
|
+
ActiveSupport::Notifications.instrument('queue_jobs.chewy_resque', class: self.class.name, id: self.id) do
|
37
|
+
self.class.indexers or return
|
38
|
+
self.class.indexers.each do |idx|
|
39
|
+
begin
|
40
|
+
idx.enqueue(self)
|
41
|
+
rescue => e
|
42
|
+
# ResqueSpec stubs all exeptions from here in tests, even no logs
|
43
|
+
if ChewyResque.logger.respond_to? :error
|
44
|
+
ChewyResque.logger.error "Cannot update index #{idx.index_name}: #{e}\n#{e.backtrace}"
|
45
|
+
end
|
46
|
+
raise e
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'chewy'
|
2
|
+
require 'resque'
|
3
|
+
require 'redis-lock'
|
4
|
+
|
5
|
+
module ChewyResque
|
6
|
+
class Worker
|
7
|
+
def self.queue
|
8
|
+
ChewyResque::locking_scope
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.perform(index_name, ids)
|
12
|
+
ActiveSupport::Notifications.instrument('perform.chewy_resque', index_name: index_name, ids: ids) do
|
13
|
+
with_lock(index_name, ids)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.with_lock(index_name, ids)
|
18
|
+
lock_name = "chewy-resque:#{ChewyResque.locking_scope}:#{index_name}-#{ids.join('-')}"
|
19
|
+
Resque.redis.lock(lock_name, life: 60, acquire: 5) { index(index_name, ids) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.index(index_name, ids)
|
23
|
+
ActiveSupport::Notifications.instrument('index.chewy_resque', index_name: index_name, ids: ids) do
|
24
|
+
with_strategy do
|
25
|
+
Chewy.derive_type(index_name).update_index(ids)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.with_strategy
|
31
|
+
if Chewy.respond_to?(:strategy) && Chewy.strategy.current.name == :base
|
32
|
+
# production
|
33
|
+
begin
|
34
|
+
Chewy.strategy(:atomic)
|
35
|
+
yield
|
36
|
+
ensure
|
37
|
+
Chewy.strategy.pop
|
38
|
+
end
|
39
|
+
else
|
40
|
+
# 0.6.2 or test
|
41
|
+
yield
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'config' do
|
4
|
+
context '#logger' do
|
5
|
+
|
6
|
+
after(:each) { ChewyResque.logger = nil }
|
7
|
+
|
8
|
+
it 'can be set from the outside' do
|
9
|
+
ChewyResque.logger = :nolog
|
10
|
+
expect(ChewyResque.logger).to eq(:nolog)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
context '#locking_scope' do
|
16
|
+
|
17
|
+
after(:each) { ChewyResque.locking_scope = nil }
|
18
|
+
|
19
|
+
it 'can be set from the outside' do
|
20
|
+
ChewyResque.locking_scope = '42'
|
21
|
+
expect(ChewyResque.locking_scope).to eq('42')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'has a default' do
|
25
|
+
expect(ChewyResque.locking_scope).to eq('chewy')
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/spec/index_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChewyResque::Index do
|
4
|
+
|
5
|
+
context 'compute the backref' do
|
6
|
+
|
7
|
+
it 'defaults to the corresponding object' do
|
8
|
+
object = Object.new
|
9
|
+
idx = ChewyResque::Index.new
|
10
|
+
expect(idx.backref(object)).to eq object
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can run a random method' do
|
14
|
+
object = double(foobar: :backref)
|
15
|
+
idx = ChewyResque::Index.new(backref: :foobar)
|
16
|
+
expect(idx.backref(object)).to eq :backref
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can use a proc' do
|
20
|
+
object = double(foobar: :my_backref)
|
21
|
+
idx = ChewyResque::Index.new(backref: -> (r) { r.foobar })
|
22
|
+
expect(idx.backref(object)).to eq :my_backref
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'turning backrefs into ids' do
|
26
|
+
let(:idx) { ChewyResque::Index.new }
|
27
|
+
|
28
|
+
it 'uses the ids of the objects' do
|
29
|
+
expect(idx.backref_ids([double(id: 3), double(id: 6)])).to eq [3, 6]
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'turns everything else into ints' do
|
33
|
+
expect(idx.backref_ids([3, '6'])).to eq [3, 6]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'queue the job' do
|
39
|
+
it 'queues the job with the settings from the index' do
|
40
|
+
object = double(id: 24)
|
41
|
+
idx = ChewyResque::Index.new index: 'foo#bar',
|
42
|
+
queue: 'hello'
|
43
|
+
|
44
|
+
expect(Resque).to receive(:enqueue_to).with('hello', ChewyResque::Worker, 'foo#bar', [24])
|
45
|
+
idx.enqueue object
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChewyResque::LogSubscriber do
|
4
|
+
|
5
|
+
let(:subscriber) { ChewyResque::LogSubscriber.new }
|
6
|
+
let(:logger) { Logger.new(nil) }
|
7
|
+
|
8
|
+
it 'logs a perform with the default logger' do
|
9
|
+
expect {
|
10
|
+
subscriber.perform(double(payload: { index_name: 'foo', ids: [1,2] }, duration: 0.2))
|
11
|
+
}.to_not raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'logs a perform event' do
|
15
|
+
allow(subscriber).to receive(:logger).and_return(logger)
|
16
|
+
expect(logger).to receive(:info)
|
17
|
+
expect {
|
18
|
+
subscriber.perform(double(payload: { index_name: 'foo', ids: [1,2] }, duration: 0.2))
|
19
|
+
}.to_not raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'logs an index event' do
|
23
|
+
allow(subscriber).to receive(:logger).and_return(logger)
|
24
|
+
expect(logger).to receive(:debug)
|
25
|
+
expect {
|
26
|
+
subscriber.index(double(payload: { index_name: 'foo', ids: [1,2] }, duration: 0.2))
|
27
|
+
}.to_not raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'log a queue_jobs event' do
|
31
|
+
allow(subscriber).to receive(:logger).and_return(logger)
|
32
|
+
expect(logger).to receive(:debug)
|
33
|
+
expect {
|
34
|
+
subscriber.queue_jobs(double(payload: { class: 'Huha', id: 123 }))
|
35
|
+
}.to_not raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/spec/mixin_spec.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Gummi
|
4
|
+
include ChewyResque::Mixin
|
5
|
+
|
6
|
+
def self.after_commit(*args) ; end
|
7
|
+
|
8
|
+
def id ; 17 ; end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
class GummiSubclass < Gummi
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ChewyResque::Mixin do
|
16
|
+
|
17
|
+
before(:each) { Gummi.indexers.clear }
|
18
|
+
|
19
|
+
context '#update_index' do
|
20
|
+
|
21
|
+
it 'installs the hooks if nothing was installed yet' do
|
22
|
+
expect(Gummi).to receive(:install_chewy_hooks)
|
23
|
+
Gummi.async_update_index('xxx')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not install the hooks twice' do
|
27
|
+
expect(Gummi).to receive(:install_chewy_hooks).once
|
28
|
+
Gummi.async_update_index('xxx')
|
29
|
+
Gummi.async_update_index('xxx')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'installs the indexer' do
|
33
|
+
expect(ChewyResque::Index).to receive(:new)
|
34
|
+
.with(index: 'some#thing', queue: :medium, backref: :foobar, only_if: nil)
|
35
|
+
.and_return(:idx)
|
36
|
+
Gummi.async_update_index('some#thing', queue: :medium, backref: :foobar)
|
37
|
+
expect(Gummi.indexers).to eq [:idx]
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'installs the indexer' do
|
41
|
+
Gummi.async_update_index('some#thing', queue: :medium, backref: :foobar)
|
42
|
+
expect(GummiSubclass.indexers.size).to eq 1
|
43
|
+
expect(GummiSubclass.indexers).to equal(Gummi.indexers)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context '#install hooks' do
|
49
|
+
|
50
|
+
it 'installs the hooks' do
|
51
|
+
expect(Gummi).to receive(:after_commit).with(:queue_chewy_jobs)
|
52
|
+
Gummi.install_chewy_hooks
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
context '#queue_chewy_jobs' do
|
58
|
+
|
59
|
+
let(:record) { Gummi.new }
|
60
|
+
|
61
|
+
it 'queues the job' do
|
62
|
+
idx = double
|
63
|
+
expect(idx).to receive(:enqueue).with(record)
|
64
|
+
allow(Gummi).to receive(:indexers).and_return([idx])
|
65
|
+
record.queue_chewy_jobs
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
ENV['REDIS_NAMESPACE_QUIET'] ||= '1'
|
2
|
+
|
3
|
+
require "codeclimate-test-reporter"
|
4
|
+
CodeClimate::TestReporter.start
|
5
|
+
|
6
|
+
require 'chewy_resque'
|
7
|
+
require 'chewy'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.before do
|
11
|
+
logger = Logger.new(STDOUT)
|
12
|
+
logger.level = Logger::ERROR
|
13
|
+
ChewyResque.logger = logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/spec/worker_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChewyResque::Worker do
|
4
|
+
|
5
|
+
let(:worker) { ChewyResque::Worker.new }
|
6
|
+
let(:lock) { double(acquire!: true, release!: true) }
|
7
|
+
|
8
|
+
before(:each) { allow(worker).to receive(:lock).and_return(lock) }
|
9
|
+
|
10
|
+
it 'calls the indexing with chewy' do
|
11
|
+
index = double
|
12
|
+
expect(Chewy).to receive(:derive_type).with('foo#bar').and_return(index)
|
13
|
+
expect(index).to receive(:update_index).with([17])
|
14
|
+
|
15
|
+
worker.class.perform('foo#bar', [17])
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chewy_resque
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vlad Bokov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: resque
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.24'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.24'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: chewy
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mlanett-redis-lock
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.2.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.2.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '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'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: kaminari
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-byebug
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: codeclimate-test-reporter
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: Resque integration for chewy and resque
|
154
|
+
email:
|
155
|
+
- bokov.vlad@gmail.com
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- ".gitignore"
|
161
|
+
- ".travis.yml"
|
162
|
+
- Gemfile
|
163
|
+
- LICENSE.txt
|
164
|
+
- README.md
|
165
|
+
- Rakefile
|
166
|
+
- chewy_resque.gemspec
|
167
|
+
- lib/chewy_resque.rb
|
168
|
+
- lib/chewy_resque/config.rb
|
169
|
+
- lib/chewy_resque/index.rb
|
170
|
+
- lib/chewy_resque/log_subscriber.rb
|
171
|
+
- lib/chewy_resque/mixin.rb
|
172
|
+
- lib/chewy_resque/railtie.rb
|
173
|
+
- lib/chewy_resque/version.rb
|
174
|
+
- lib/chewy_resque/worker.rb
|
175
|
+
- spec/config_spec.rb
|
176
|
+
- spec/index_spec.rb
|
177
|
+
- spec/log_subscriber_spec.rb
|
178
|
+
- spec/mixin_spec.rb
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/worker_spec.rb
|
181
|
+
homepage: ''
|
182
|
+
licenses:
|
183
|
+
- Apache V2
|
184
|
+
metadata: {}
|
185
|
+
post_install_message:
|
186
|
+
rdoc_options: []
|
187
|
+
require_paths:
|
188
|
+
- lib
|
189
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ">="
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: '0'
|
199
|
+
requirements: []
|
200
|
+
rubyforge_project:
|
201
|
+
rubygems_version: 2.2.2
|
202
|
+
signing_key:
|
203
|
+
specification_version: 4
|
204
|
+
summary: Small helper gem that allows you to automatically run all chewy index updates
|
205
|
+
in resque
|
206
|
+
test_files:
|
207
|
+
- spec/config_spec.rb
|
208
|
+
- spec/index_spec.rb
|
209
|
+
- spec/log_subscriber_spec.rb
|
210
|
+
- spec/mixin_spec.rb
|
211
|
+
- spec/spec_helper.rb
|
212
|
+
- spec/worker_spec.rb
|