tantot 0.1.1 → 0.1.2
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 +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
|