tantot 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/lib/tantot/collector/base.rb +46 -0
- data/lib/tantot/collector/block.rb +16 -25
- data/lib/tantot/collector/watcher.rb +19 -39
- data/lib/tantot/collector.rb +5 -12
- data/lib/tantot/config.rb +3 -6
- data/lib/tantot/extensions/chewy.rb +4 -5
- data/lib/tantot/observe.rb +4 -1
- data/lib/tantot/performer/chewy.rb +31 -0
- data/lib/tantot/performer.rb +7 -0
- data/lib/tantot/railtie.rb +1 -1
- data/lib/tantot/version.rb +1 -1
- data/lib/tantot/watcher.rb +1 -1
- data/spec/extensions/chewy_spec.rb +97 -84
- data/spec/sidekiq_spec.rb +22 -4
- data/spec/tantot_spec.rb +6 -6
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56725354395a9033cc635de74a735b73edac40b3
|
4
|
+
data.tar.gz: f5a41a93122899cb7ee27946a18a50a6b7fec825
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97e9aad665296f329b93269feb68ba1e6e3aecd099e3b91bc9fe60f3f91fc4f88dbaa4e32b9958e4ad7d4ac55950896b308d81cd6823144975b85033eeded7ce
|
7
|
+
data.tar.gz: 195da978eb98c9accd59e17b2679012a8e74bbb6bf33092e21cff06f909c3fbac9fa6fd57345ae1b613ab4c6046a664d578437ed52f835fe0080107def78f3fa
|
data/Gemfile
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Tantot
|
2
|
+
module Collector
|
3
|
+
class Base
|
4
|
+
class_attribute :context_key
|
5
|
+
|
6
|
+
def self.manages?(context)
|
7
|
+
context.key?(self.context_key)
|
8
|
+
end
|
9
|
+
|
10
|
+
def register_watch(context, block)
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
def push(context, instance, mutations)
|
15
|
+
formatter = Tantot::Formatter.resolve(context[:options][:format] || Tantot.config.format).new
|
16
|
+
attribute_hash = get_stash(context, instance)
|
17
|
+
mutations.each do |attr, changes|
|
18
|
+
attribute_hash[attr] = formatter.push(attribute_hash[attr], context, changes)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def sweep(performer_name)
|
23
|
+
if @stash.any?
|
24
|
+
Tantot.logger.debug { "[Tantot] [Sweeping] [#{self.class.name.demodulize}] #{debug_state}" }
|
25
|
+
@stash.each do |id, changes|
|
26
|
+
context = Tantot.registry.watch_config[id][:context]
|
27
|
+
performer = Tantot::Performer.resolve(performer_name || context[:options][:performer] || Tantot.config.performer).new
|
28
|
+
Tantot.logger.debug { "[Tantot] [Performer] [#{self.class.name.demodulize}] [#{performer.class.name.demodulize}] #{debug_state(Hash[id, changes])}" }
|
29
|
+
performer.run(context, changes)
|
30
|
+
end
|
31
|
+
@stash.clear
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def debug_changes_for_model(model, changes_by_id)
|
36
|
+
"#{model.name}#{changes_by_id.keys.inspect}"
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def get_stash(context, instance)
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module Tantot
|
2
2
|
module Collector
|
3
|
-
class Block
|
4
|
-
|
5
|
-
context.key?(:block_id)
|
6
|
-
end
|
3
|
+
class Block < Base
|
4
|
+
self.context_key = :block_id
|
7
5
|
|
8
6
|
def initialize
|
9
7
|
@stash = Hash.new do |block_id_hash, block_id|
|
@@ -17,22 +15,6 @@ module Tantot
|
|
17
15
|
Tantot.registry.watch_config[context[:block_id]] = {context: context, block: block}
|
18
16
|
end
|
19
17
|
|
20
|
-
def push(context, instance, mutations)
|
21
|
-
options = context.fetch(:options, {})
|
22
|
-
formatter = Tantot::Formatter.resolve(options[:format] || Tantot.config.default_watcher_options[:format]).new
|
23
|
-
attribute_hash = @stash[context[:block_id]][instance.id]
|
24
|
-
mutations.each do |attr, changes|
|
25
|
-
attribute_hash[attr] = formatter.push(attribute_hash[attr], context, changes)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def sweep(performer, context = {})
|
30
|
-
@stash.each do |block_id, changes|
|
31
|
-
performer.run({block_id: block_id}, changes)
|
32
|
-
end
|
33
|
-
@stash.clear
|
34
|
-
end
|
35
|
-
|
36
18
|
def perform(context, changes_by_id)
|
37
19
|
watch_config = Tantot.registry.watch_config[context[:block_id]]
|
38
20
|
watch_config[:context][:model].instance_exec(Tantot::Changes::ById.new(changes_by_id), &watch_config[:block])
|
@@ -60,17 +42,26 @@ module Tantot
|
|
60
42
|
debug_block(block)
|
61
43
|
end
|
62
44
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
45
|
+
def debug_changes(watch_config, changes_by_id)
|
46
|
+
"#{debug_changes_for_model(watch_config[:context][:model], changes_by_id)} for #{debug_block(watch_config[:block])}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def debug_state(stash = @stash)
|
50
|
+
stash.collect do |block_id, changes_by_id|
|
66
51
|
watch_config = Tantot.registry.watch_config[block_id]
|
67
|
-
|
52
|
+
debug_changes(watch_config, changes_by_id)
|
68
53
|
end.join(" / ")
|
69
54
|
end
|
70
55
|
|
71
56
|
def debug_perform(context, changes_by_id)
|
72
57
|
watch_config = Tantot.registry.watch_config[context[:block_id]]
|
73
|
-
|
58
|
+
debug_changes(watch_config, changes_by_id)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def get_stash(context, instance)
|
64
|
+
@stash[context[:block_id]][instance.id]
|
74
65
|
end
|
75
66
|
|
76
67
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module Tantot
|
2
2
|
module Collector
|
3
|
-
class Watcher
|
4
|
-
|
5
|
-
context.key?(:watcher)
|
6
|
-
end
|
3
|
+
class Watcher < Base
|
4
|
+
self.context_key = :watcher
|
7
5
|
|
8
6
|
def initialize
|
9
7
|
@stash = Hash.new do |watcher_hash, watcher|
|
@@ -16,30 +14,7 @@ module Tantot
|
|
16
14
|
end
|
17
15
|
|
18
16
|
def register_watch(context, block)
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
def push(context, instance, mutations)
|
23
|
-
watcher = context[:watcher]
|
24
|
-
model = context[:model]
|
25
|
-
formatter = Tantot::Formatter.resolve(watcher.watcher_options[:format]).new
|
26
|
-
attribute_hash = @stash[watcher][model][instance.id]
|
27
|
-
mutations.each do |attr, changes|
|
28
|
-
attribute_hash[attr] = formatter.push(attribute_hash[attr], context, changes)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def sweep(performer, context = {})
|
33
|
-
watcher = context[:watcher]
|
34
|
-
filtered_stash = watcher ? @stash.select {|w, _c| w == watcher} : @stash
|
35
|
-
filtered_stash.each do |w, changes_by_model|
|
36
|
-
performer.run({watcher: w}, changes_by_model)
|
37
|
-
end
|
38
|
-
if watcher
|
39
|
-
@stash.delete(watcher)
|
40
|
-
else
|
41
|
-
@stash.clear
|
42
|
-
end
|
17
|
+
Tantot.registry.watch_config[context[:watcher]] = {context: context}
|
43
18
|
end
|
44
19
|
|
45
20
|
def perform(context, changes_by_model)
|
@@ -64,22 +39,27 @@ module Tantot
|
|
64
39
|
end
|
65
40
|
|
66
41
|
def debug_context(context)
|
67
|
-
context[:watcher].name
|
42
|
+
context[:watcher].name
|
68
43
|
end
|
69
44
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end.flatten.join(" / ")
|
45
|
+
def debug_changes(watcher, changes_by_model)
|
46
|
+
"#{watcher.name}(#{changes_by_model.collect {|model, changes_by_id| debug_changes_for_model(model, changes_by_id)}.join(" & ")})"
|
47
|
+
end
|
48
|
+
|
49
|
+
def debug_state(stash = @stash)
|
50
|
+
stash.collect {|watcher, changes_by_model| debug_changes(watcher, changes_by_model)}.flatten.join(" / ")
|
77
51
|
end
|
78
52
|
|
79
53
|
def debug_perform(context, changes_by_model)
|
80
|
-
|
81
|
-
|
82
|
-
|
54
|
+
debug_changes(context[:watcher], changes_by_model)
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def get_stash(context, instance)
|
60
|
+
watcher = context[:watcher]
|
61
|
+
model = context[:model]
|
62
|
+
@stash[watcher][model][instance.id]
|
83
63
|
end
|
84
64
|
|
85
65
|
end
|
data/lib/tantot/collector.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'tantot/collector/base'
|
1
2
|
require 'tantot/collector/watcher'
|
2
3
|
require 'tantot/collector/block'
|
3
4
|
|
@@ -27,24 +28,16 @@ module Tantot
|
|
27
28
|
"[Tantot] [Collecting] [#{collector.class.name.demodulize}] #{mutate} on <#{instance.class.name}:#{instance.id}> for <#{collector.debug_context(context)}>"
|
28
29
|
end
|
29
30
|
collector.push(context, instance, mutations)
|
30
|
-
sweep
|
31
|
+
sweep if Tantot.config.sweep_on_push
|
31
32
|
end
|
32
33
|
|
33
|
-
def sweep(
|
34
|
-
|
35
|
-
specific_collector = resolve(context)
|
36
|
-
collectors = specific_collector ? [specific_collector] : @collectors.values
|
37
|
-
collectors.each do |collector|
|
38
|
-
if Tantot.logger.debug? && (debug_state = collector.debug_state(context))
|
39
|
-
Tantot.logger.debug { "[Tantot] [Sweeping] [#{collector.class.name.demodulize}] [#{performer.class.name.demodulize}] #{debug_state}" }
|
40
|
-
end
|
41
|
-
collector.sweep(performer, context)
|
42
|
-
end
|
34
|
+
def sweep(performer_name = nil)
|
35
|
+
@collectors.values.each {|collector| collector.sweep(performer_name)}
|
43
36
|
end
|
44
37
|
|
45
38
|
def perform(context, changes)
|
46
39
|
collector = resolve!(context)
|
47
|
-
Tantot.logger.debug { "[Tantot] [
|
40
|
+
Tantot.logger.debug { "[Tantot] [Run] [#{collector.class.name.demodulize}] #{collector.debug_perform(context, changes)}" }
|
48
41
|
collector.perform(context, changes)
|
49
42
|
end
|
50
43
|
|
data/lib/tantot/config.rb
CHANGED
@@ -2,16 +2,13 @@ module Tantot
|
|
2
2
|
class Config
|
3
3
|
include Singleton
|
4
4
|
|
5
|
-
attr_accessor :performer, :
|
5
|
+
attr_accessor :performer, :format, :use_after_commit_callbacks, :sweep_on_push
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@performer = :inline
|
9
|
+
@format = :compact
|
9
10
|
@use_after_commit_callbacks = true
|
10
|
-
@
|
11
|
-
format: :compact
|
12
|
-
}
|
13
|
-
@console_mode = false
|
14
|
-
@chewy_strategy = :atomic
|
11
|
+
@sweep_on_push = false
|
15
12
|
end
|
16
13
|
end
|
17
14
|
end
|
@@ -26,6 +26,8 @@ module Tantot
|
|
26
26
|
class ChewyWatcher
|
27
27
|
include Tantot::Watcher
|
28
28
|
|
29
|
+
watcher_options performer: :chewy
|
30
|
+
|
29
31
|
def perform(changes_by_model)
|
30
32
|
changes_by_model.each do |model, changes_by_id|
|
31
33
|
model_watches = model._tantot_chewy_callbacks
|
@@ -70,11 +72,8 @@ module Tantot
|
|
70
72
|
|
71
73
|
# Make sure there are any backreferences
|
72
74
|
if backreference.any?
|
73
|
-
|
74
|
-
::Chewy.
|
75
|
-
Tantot.logger.debug { "[Tantot] [Chewy] [update_index] #{reference} (#{backreference.count} objects): #{backreference.inspect}" }
|
76
|
-
::Chewy.derive_type(reference).update_index(backreference, options)
|
77
|
-
end
|
75
|
+
Tantot.logger.debug { "[Tantot] [Chewy] [update_index] #{reference} (#{backreference.count} objects): #{backreference.inspect}" }
|
76
|
+
::Chewy.derive_type(reference).update_index(backreference, options)
|
78
77
|
end
|
79
78
|
end
|
80
79
|
|
data/lib/tantot/observe.rb
CHANGED
@@ -61,7 +61,10 @@ module Tantot
|
|
61
61
|
options: options
|
62
62
|
}
|
63
63
|
|
64
|
-
|
64
|
+
if watcher
|
65
|
+
context[:watcher] = watcher
|
66
|
+
options.reverse_merge!(watcher.watcher_options)
|
67
|
+
end
|
65
68
|
context[:block_id] = CityHash.hash64(block.source_location.collect(&:to_s).join) if block_given?
|
66
69
|
|
67
70
|
Tantot.collector.register_watch(context, block)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Tantot
|
2
|
+
module Performer
|
3
|
+
class Chewy
|
4
|
+
class Worker
|
5
|
+
include ::Sidekiq::Worker
|
6
|
+
|
7
|
+
def perform(context, changes)
|
8
|
+
context, changes = Tantot.collector.unmarshal(context, changes)
|
9
|
+
::Chewy.strategy(Tantot.config.chewy_strategy) do
|
10
|
+
Tantot.collector.perform(context, changes)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(context, changes)
|
16
|
+
case ::Chewy.strategy.current.name
|
17
|
+
when :atomic, :urgent
|
18
|
+
Tantot::Performer::Inline.new.run(context, changes)
|
19
|
+
when /sidekiq/
|
20
|
+
context, changes = Tantot.collector.marshal(context, changes)
|
21
|
+
Tantot::Performer::Chewy::Worker.perform_async(context, changes)
|
22
|
+
when :bypass
|
23
|
+
return
|
24
|
+
else
|
25
|
+
# No strategy defined, do an Inline run and let Chewy fail
|
26
|
+
Tantot::Performer::Inline.new.run(context, changes)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/tantot/performer.rb
CHANGED
data/lib/tantot/railtie.rb
CHANGED
data/lib/tantot/version.rb
CHANGED
data/lib/tantot/watcher.rb
CHANGED
@@ -8,7 +8,7 @@ module Tantot
|
|
8
8
|
|
9
9
|
class_methods do
|
10
10
|
def watcher_options(opts = {})
|
11
|
-
self.watcher_options_hash ||=
|
11
|
+
self.watcher_options_hash ||= {}
|
12
12
|
self.watcher_options_hash = self.watcher_options_hash.merge(opts)
|
13
13
|
end
|
14
14
|
end
|
@@ -1,127 +1,140 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
3
|
+
if defined?(::Chewy)
|
4
4
|
|
5
|
-
|
6
|
-
before do
|
7
|
-
stub_const("Chewy", {})
|
8
|
-
end
|
5
|
+
describe Tantot::Extensions::Chewy do
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
[nil, :self, :class_method, :block].product([:some, :all]).each do |backreference_opt, attribute_opt|
|
8
|
+
it "should update indexes using backreference: #{backreference_opt.inspect}, attributes: #{attribute_opt}" do
|
9
|
+
chewy_type = double
|
13
10
|
|
14
|
-
|
15
|
-
|
11
|
+
watch_index_params = ['foo']
|
12
|
+
watch_index_params << :id if attribute_opt == :some
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
block_callback = proc do |changes|
|
15
|
+
self.yielded_changes = changes
|
16
|
+
[1, 2, 3]
|
17
|
+
end
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
case backreference_opt
|
20
|
+
when nil, :block
|
21
|
+
when :self
|
22
|
+
watch_index_params << {method: :self}
|
23
|
+
when :class_method
|
24
|
+
watch_index_params << {method: :class_get_ids}
|
25
|
+
end
|
29
26
|
|
30
|
-
|
31
|
-
|
27
|
+
stub_model(:city) do
|
28
|
+
class_attribute :yielded_changes
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
if backreference_opt == :block
|
31
|
+
watch_index(*watch_index_params, &block_callback)
|
32
|
+
else
|
33
|
+
watch_index(*watch_index_params)
|
34
|
+
end
|
38
35
|
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
def self.class_get_ids(changes)
|
37
|
+
self.yielded_changes = changes
|
38
|
+
[1, 2, 3]
|
39
|
+
end
|
42
40
|
end
|
43
|
-
end
|
44
41
|
|
45
|
-
|
42
|
+
city1 = city2 = nil
|
46
43
|
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
Tantot.collector.run do
|
45
|
+
city1 = City.create!
|
46
|
+
city2 = City.create!
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
expect(Chewy).to receive(:derive_type).with('foo').and_return(chewy_type)
|
48
|
+
# Stub the integration point between us and Chewy
|
49
|
+
expect(Chewy).to receive(:derive_type).with('foo').and_return(chewy_type)
|
54
50
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
51
|
+
# Depending on backreference
|
52
|
+
case backreference_opt
|
53
|
+
when nil, :self
|
54
|
+
# Implicit and self reference will update with the created model id
|
55
|
+
expect(chewy_type).to receive(:update_index).with([city1.id, city2.id], {})
|
56
|
+
when :class_method, :block
|
57
|
+
# Validate that the returned ids are updated
|
58
|
+
expect(chewy_type).to receive(:update_index).with([1, 2, 3], {})
|
59
|
+
end
|
63
60
|
end
|
61
|
+
|
62
|
+
# Make sure the callbacks received the changes
|
63
|
+
if [:class_method, :block].include?(backreference_opt)
|
64
|
+
expect(City.yielded_changes).to eq(Tantot::Changes::ById.new({city1.id => {"id" => [nil, city1.id]}, city2.id => {"id" => [nil, city2.id]}}))
|
65
|
+
end
|
66
|
+
|
64
67
|
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should allow registering an index watch on self (all attributes, destroy)" do
|
71
|
+
chewy_type = double
|
65
72
|
|
66
|
-
|
67
|
-
|
68
|
-
expect(City.yielded_changes).to eq(Tantot::Changes::ById.new({city1.id => {"id" => [nil, city1.id]}, city2.id => {"id" => [nil, city2.id]}}))
|
73
|
+
stub_model(:city) do
|
74
|
+
watch_index 'foo'
|
69
75
|
end
|
70
76
|
|
71
|
-
|
72
|
-
|
77
|
+
city = City.create!
|
78
|
+
Tantot.collector.sweep(:bypass)
|
73
79
|
|
74
|
-
|
75
|
-
|
80
|
+
Tantot.collector.run do
|
81
|
+
city.destroy
|
76
82
|
|
77
|
-
|
78
|
-
|
83
|
+
expect(Chewy).to receive(:derive_type).with('foo').and_return(chewy_type)
|
84
|
+
expect(chewy_type).to receive(:update_index).with([city.id], {})
|
85
|
+
end
|
79
86
|
end
|
80
87
|
|
81
|
-
|
82
|
-
|
88
|
+
it "should allow registering an index watch on self (all attributes, destroy, block)" do
|
89
|
+
chewy_type = double
|
83
90
|
|
84
|
-
|
85
|
-
|
91
|
+
stub_model(:city) do
|
92
|
+
watch_index 'foo' do |changes|
|
93
|
+
changes.ids
|
94
|
+
end
|
95
|
+
end
|
86
96
|
|
87
|
-
|
88
|
-
|
89
|
-
expect(chewy_type).to receive(:update_index).with([city.id], {})
|
90
|
-
end
|
91
|
-
end
|
97
|
+
city = City.create!
|
98
|
+
Tantot.collector.sweep(:bypass)
|
92
99
|
|
93
|
-
|
94
|
-
|
100
|
+
Tantot.collector.run do
|
101
|
+
city.destroy
|
95
102
|
|
96
|
-
|
97
|
-
|
98
|
-
changes.ids
|
103
|
+
expect(Chewy).to receive(:derive_type).with('foo').and_return(chewy_type)
|
104
|
+
expect(chewy_type).to receive(:update_index).with([city.id], {})
|
99
105
|
end
|
100
106
|
end
|
101
107
|
|
102
|
-
|
103
|
-
|
108
|
+
it "should allow returning nothing in a callback" do
|
109
|
+
stub_model(:city) do
|
110
|
+
watch_index('foo') { 1 if false }
|
111
|
+
watch_index('bar') { [] }
|
112
|
+
watch_index('baz') { nil }
|
113
|
+
end
|
104
114
|
|
105
|
-
|
106
|
-
|
115
|
+
Tantot.collector.run do
|
116
|
+
City.create!
|
107
117
|
|
108
|
-
|
109
|
-
|
110
|
-
expect(chewy_type).to receive(:update_index).with([city.id], {})
|
118
|
+
expect(Chewy).not_to receive(:derive_type)
|
119
|
+
end
|
111
120
|
end
|
112
121
|
end
|
113
122
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
watch_index('bar') { [] }
|
118
|
-
watch_index('baz') { nil }
|
123
|
+
describe "Chewy.strategy" do
|
124
|
+
before do
|
125
|
+
allow(Tantot.config).to receive(:sweep_on_push).and_return(true)
|
119
126
|
end
|
120
127
|
|
121
|
-
|
122
|
-
|
128
|
+
it "should bypass if Chewy.strategy is :bypass" do
|
129
|
+
stub_model(:city) do
|
130
|
+
watch_index('foo')
|
131
|
+
end
|
123
132
|
|
124
133
|
expect(Chewy).not_to receive(:derive_type)
|
134
|
+
Chewy.strategy :bypass do
|
135
|
+
City.create!
|
136
|
+
end
|
125
137
|
end
|
126
138
|
end
|
139
|
+
|
127
140
|
end
|
data/spec/sidekiq_spec.rb
CHANGED
@@ -31,7 +31,13 @@ if defined?(::Sidekiq)
|
|
31
31
|
City.create name: 'foo'
|
32
32
|
end
|
33
33
|
expect(Tantot::Performer::Sidekiq::Worker.jobs.size).to eq(1)
|
34
|
-
expect(Tantot::Performer::Sidekiq::Worker.jobs.first["args"]).to eq([{
|
34
|
+
expect(Tantot::Performer::Sidekiq::Worker.jobs.first["args"]).to eq([{
|
35
|
+
"model" => "City",
|
36
|
+
"attributes" => ["name"],
|
37
|
+
"options" => {},
|
38
|
+
"watcher" => "SidekiqWatcher",
|
39
|
+
"collector_class" => "Tantot::Collector::Watcher"},
|
40
|
+
{"City" => {"1" => {"name" => [nil, 'foo']}}}])
|
35
41
|
end
|
36
42
|
|
37
43
|
it "should call the watcher" do
|
@@ -49,7 +55,7 @@ if defined?(::Sidekiq)
|
|
49
55
|
# Create a model, then sweep. It should have called perform wihtout triggering a sidekiq worker
|
50
56
|
city = City.create name: 'foo'
|
51
57
|
expect_any_instance_of(SidekiqWatcher).to receive(:perform).with(Tantot::Changes::ByModel.new({City => {city.id => {"name" => [nil, 'foo']}}}))
|
52
|
-
Tantot.collector.sweep(
|
58
|
+
Tantot.collector.sweep(:inline)
|
53
59
|
expect(Tantot::Performer::Sidekiq::Worker.jobs.size).to eq(0)
|
54
60
|
|
55
61
|
# Further modifications should trigger through sidekiq when exiting the strategy block
|
@@ -57,7 +63,13 @@ if defined?(::Sidekiq)
|
|
57
63
|
city.save
|
58
64
|
end
|
59
65
|
expect(Tantot::Performer::Sidekiq::Worker.jobs.size).to eq(1)
|
60
|
-
expect(Tantot::Performer::Sidekiq::Worker.jobs.first["args"]).to eq([{
|
66
|
+
expect(Tantot::Performer::Sidekiq::Worker.jobs.first["args"]).to eq([{
|
67
|
+
"model" => "City",
|
68
|
+
"attributes" => ["name"],
|
69
|
+
"options" => {},
|
70
|
+
"watcher" => "SidekiqWatcher",
|
71
|
+
"collector_class" => "Tantot::Collector::Watcher"},
|
72
|
+
{"City" => {"1" => {"name" => ['foo', 'bar']}}}])
|
61
73
|
end
|
62
74
|
end
|
63
75
|
end
|
@@ -81,7 +93,13 @@ if defined?(::Sidekiq)
|
|
81
93
|
end
|
82
94
|
expect(Tantot::Performer::Sidekiq::Worker.jobs.size).to eq(1)
|
83
95
|
block_id = Tantot.registry.watch_config.keys.last
|
84
|
-
expect(Tantot::Performer::Sidekiq::Worker.jobs.first["args"]).to eq([{
|
96
|
+
expect(Tantot::Performer::Sidekiq::Worker.jobs.first["args"]).to eq([{
|
97
|
+
"model" => "City",
|
98
|
+
"attributes" => ["name"],
|
99
|
+
"options" => {},
|
100
|
+
"block_id" => block_id,
|
101
|
+
"collector_class" => "Tantot::Collector::Block"},
|
102
|
+
{"1" => {"name" => [nil, 'foo']}}])
|
85
103
|
end
|
86
104
|
|
87
105
|
it "should call the watcher" do
|
data/spec/tantot_spec.rb
CHANGED
@@ -64,7 +64,7 @@ describe Tantot do
|
|
64
64
|
it "calls back on model update" do
|
65
65
|
city = City.create!
|
66
66
|
city.reload
|
67
|
-
Tantot.collector.sweep(
|
67
|
+
Tantot.collector.sweep(:bypass)
|
68
68
|
|
69
69
|
expect(watcher_instance).to receive(:perform).with(Tantot::Changes::ByModel.new({City => {city.id => {"name" => [nil, 'foo']}}}))
|
70
70
|
Tantot.collector.run do
|
@@ -76,7 +76,7 @@ describe Tantot do
|
|
76
76
|
it "calls back on model destroy" do
|
77
77
|
city = City.create!(name: 'foo')
|
78
78
|
city.reload
|
79
|
-
Tantot.collector.sweep(
|
79
|
+
Tantot.collector.sweep(:bypass)
|
80
80
|
|
81
81
|
expect(watcher_instance).to receive(:perform).with(Tantot::Changes::ByModel.new({City => {city.id => {"name" => ['foo']}}}))
|
82
82
|
Tantot.collector.run do
|
@@ -99,7 +99,7 @@ describe Tantot do
|
|
99
99
|
Tantot.collector.run do
|
100
100
|
city = City.create name: 'foo'
|
101
101
|
expect(watcher_instance).to receive(:perform).with(Tantot::Changes::ByModel.new({City => {city.id => {"name" => [nil, 'foo']}}}))
|
102
|
-
Tantot.collector.sweep(
|
102
|
+
Tantot.collector.sweep(:inline)
|
103
103
|
city.name = 'bar'
|
104
104
|
city.save
|
105
105
|
expect(watcher_instance).to receive(:perform).with(Tantot::Changes::ByModel.new({City => {city.id => {"name" => ['foo', 'bar']}}}))
|
@@ -148,7 +148,7 @@ describe Tantot do
|
|
148
148
|
city = City.create!(name: "Quebec", country_id: country.id)
|
149
149
|
country.reload
|
150
150
|
city.reload
|
151
|
-
Tantot.collector.sweep(
|
151
|
+
Tantot.collector.sweep(:bypass)
|
152
152
|
|
153
153
|
expect(watcher_instance).to receive(:perform).once.with(Tantot::Changes::ByModel.new({City => {city.id => {"name" => ['Quebec', 'foo', 'bar'], "country_id" => [country.id, nil]}}, Country => {country.id => {"country_code" => ['CDN', 'US']}}}))
|
154
154
|
Tantot.collector.run do
|
@@ -191,7 +191,7 @@ describe Tantot do
|
|
191
191
|
expect(watchA_instance).to receive(:perform).once.with(Tantot::Changes::ByModel.new({City => {city.id => {"name" => ['Quebec', 'foo', 'bar'], "country_id" => [country.id, nil]}}, Country => {country.id => {"country_code" => ['CDN', 'US']}}}))
|
192
192
|
# WatchB receives the last value of rating since it has been destroyed
|
193
193
|
expect(watchB_instance).to receive(:perform).once.with(Tantot::Changes::ByModel.new({City => {city.id => {"rating" => [12]}}}))
|
194
|
-
Tantot.collector.sweep(
|
194
|
+
Tantot.collector.sweep(:bypass)
|
195
195
|
|
196
196
|
Tantot.collector.run do
|
197
197
|
city.name = "foo"
|
@@ -224,7 +224,7 @@ describe Tantot do
|
|
224
224
|
it "should also watch on destroy, but when watching all attributes, change hash is empty" do
|
225
225
|
city = City.create!(name: 'foo')
|
226
226
|
city.reload
|
227
|
-
Tantot.collector.sweep(
|
227
|
+
Tantot.collector.sweep(:bypass)
|
228
228
|
|
229
229
|
expect(watcher_instance).to receive(:perform).with(Tantot::Changes::ByModel.new({City => {city.id => {}}}))
|
230
230
|
Tantot.collector.run do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tantot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- François-Pierre Bouchard
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- lib/tantot.rb
|
160
160
|
- lib/tantot/changes.rb
|
161
161
|
- lib/tantot/collector.rb
|
162
|
+
- lib/tantot/collector/base.rb
|
162
163
|
- lib/tantot/collector/block.rb
|
163
164
|
- lib/tantot/collector/watcher.rb
|
164
165
|
- lib/tantot/config.rb
|
@@ -171,6 +172,7 @@ files:
|
|
171
172
|
- lib/tantot/observe.rb
|
172
173
|
- lib/tantot/performer.rb
|
173
174
|
- lib/tantot/performer/bypass.rb
|
175
|
+
- lib/tantot/performer/chewy.rb
|
174
176
|
- lib/tantot/performer/inline.rb
|
175
177
|
- lib/tantot/performer/sidekiq.rb
|
176
178
|
- lib/tantot/railtie.rb
|