tantot 0.1.5 → 0.1.6
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/lib/tantot.rb +7 -23
- data/lib/tantot/agent.rb +19 -0
- data/lib/tantot/agent/base.rb +71 -0
- data/lib/tantot/agent/block.rb +32 -0
- data/lib/tantot/agent/registry.rb +34 -0
- data/lib/tantot/agent/watcher.rb +46 -0
- data/lib/tantot/changes.rb +2 -3
- data/lib/tantot/config.rb +2 -2
- data/lib/tantot/errors.rb +6 -0
- data/lib/tantot/extensions/chewy.rb +66 -18
- data/lib/tantot/extensions/grape/middleware.rb +1 -1
- data/lib/tantot/manager.rb +31 -0
- data/lib/tantot/observe.rb +36 -31
- data/lib/tantot/railtie.rb +5 -0
- data/lib/tantot/strategy.rb +24 -0
- data/lib/tantot/{performer → strategy}/bypass.rb +2 -2
- data/lib/tantot/strategy/chewy.rb +33 -0
- data/lib/tantot/strategy/inline.rb +9 -0
- data/lib/tantot/strategy/sidekiq.rb +36 -0
- data/lib/tantot/version.rb +1 -1
- data/performance/profile.rb +12 -8
- data/spec/collector/block_spec.rb +33 -0
- data/spec/collector/options_spec.rb +211 -0
- data/spec/collector/watcher_spec.rb +180 -0
- data/spec/extensions/chewy_spec.rb +280 -78
- data/spec/sidekiq_spec.rb +38 -58
- data/spec/spec_helper.rb +27 -2
- data/spec/tantot_spec.rb +0 -370
- metadata +19 -15
- data/lib/tantot/collector.rb +0 -70
- data/lib/tantot/collector/base.rb +0 -46
- data/lib/tantot/collector/block.rb +0 -69
- data/lib/tantot/collector/watcher.rb +0 -67
- data/lib/tantot/formatter.rb +0 -10
- data/lib/tantot/formatter/compact.rb +0 -9
- data/lib/tantot/formatter/detailed.rb +0 -9
- data/lib/tantot/performer.rb +0 -24
- data/lib/tantot/performer/chewy.rb +0 -31
- data/lib/tantot/performer/inline.rb +0 -9
- data/lib/tantot/performer/sidekiq.rb +0 -21
- data/lib/tantot/registry.rb +0 -11
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- François-Pierre Bouchard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -157,30 +157,31 @@ files:
|
|
157
157
|
- bin/console
|
158
158
|
- bin/setup
|
159
159
|
- lib/tantot.rb
|
160
|
+
- lib/tantot/agent.rb
|
161
|
+
- lib/tantot/agent/base.rb
|
162
|
+
- lib/tantot/agent/block.rb
|
163
|
+
- lib/tantot/agent/registry.rb
|
164
|
+
- lib/tantot/agent/watcher.rb
|
160
165
|
- lib/tantot/changes.rb
|
161
|
-
- lib/tantot/collector.rb
|
162
|
-
- lib/tantot/collector/base.rb
|
163
|
-
- lib/tantot/collector/block.rb
|
164
|
-
- lib/tantot/collector/watcher.rb
|
165
166
|
- lib/tantot/config.rb
|
166
167
|
- lib/tantot/errors.rb
|
167
168
|
- lib/tantot/extensions/chewy.rb
|
168
169
|
- lib/tantot/extensions/grape/middleware.rb
|
169
|
-
- lib/tantot/
|
170
|
-
- lib/tantot/formatter/compact.rb
|
171
|
-
- lib/tantot/formatter/detailed.rb
|
170
|
+
- lib/tantot/manager.rb
|
172
171
|
- lib/tantot/observe.rb
|
173
|
-
- lib/tantot/performer.rb
|
174
|
-
- lib/tantot/performer/bypass.rb
|
175
|
-
- lib/tantot/performer/chewy.rb
|
176
|
-
- lib/tantot/performer/inline.rb
|
177
|
-
- lib/tantot/performer/sidekiq.rb
|
178
172
|
- lib/tantot/railtie.rb
|
179
|
-
- lib/tantot/
|
173
|
+
- lib/tantot/strategy.rb
|
174
|
+
- lib/tantot/strategy/bypass.rb
|
175
|
+
- lib/tantot/strategy/chewy.rb
|
176
|
+
- lib/tantot/strategy/inline.rb
|
177
|
+
- lib/tantot/strategy/sidekiq.rb
|
180
178
|
- lib/tantot/version.rb
|
181
179
|
- lib/tantot/watcher.rb
|
182
180
|
- performance/profile.rb
|
183
181
|
- spec/changes_spec.rb
|
182
|
+
- spec/collector/block_spec.rb
|
183
|
+
- spec/collector/options_spec.rb
|
184
|
+
- spec/collector/watcher_spec.rb
|
184
185
|
- spec/extensions/chewy_spec.rb
|
185
186
|
- spec/sidekiq_spec.rb
|
186
187
|
- spec/spec_helper.rb
|
@@ -212,6 +213,9 @@ specification_version: 4
|
|
212
213
|
summary: Delayed, grouped and compact ActiveRecord callbacks
|
213
214
|
test_files:
|
214
215
|
- spec/changes_spec.rb
|
216
|
+
- spec/collector/block_spec.rb
|
217
|
+
- spec/collector/options_spec.rb
|
218
|
+
- spec/collector/watcher_spec.rb
|
215
219
|
- spec/extensions/chewy_spec.rb
|
216
220
|
- spec/sidekiq_spec.rb
|
217
221
|
- spec/spec_helper.rb
|
data/lib/tantot/collector.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
require 'tantot/collector/base'
|
2
|
-
require 'tantot/collector/watcher'
|
3
|
-
require 'tantot/collector/block'
|
4
|
-
|
5
|
-
COLLECTOR_CLASSES = [Tantot::Collector::Block, Tantot::Collector::Watcher]
|
6
|
-
|
7
|
-
module Tantot
|
8
|
-
module Collector
|
9
|
-
class Manager
|
10
|
-
def initialize
|
11
|
-
@collectors = {}
|
12
|
-
end
|
13
|
-
|
14
|
-
def register_watch(context, block)
|
15
|
-
resolve!(context).register_watch(context, block)
|
16
|
-
end
|
17
|
-
|
18
|
-
def run(&block)
|
19
|
-
yield
|
20
|
-
ensure
|
21
|
-
sweep
|
22
|
-
end
|
23
|
-
|
24
|
-
def push(context, instance, mutations)
|
25
|
-
collector = resolve!(context)
|
26
|
-
Tantot.logger.debug do
|
27
|
-
mutate = mutations.size.zero? ? 'destroy' : "#{mutations.size} mutations(s)"
|
28
|
-
"[Tantot] [Collecting] [#{collector.class.name.demodulize}] #{mutate} on <#{instance.class.name}:#{instance.id}> for <#{collector.debug_context(context)}>"
|
29
|
-
end
|
30
|
-
collector.push(context, instance, mutations)
|
31
|
-
sweep if Tantot.config.sweep_on_push
|
32
|
-
end
|
33
|
-
|
34
|
-
def sweep(performer_name = nil)
|
35
|
-
@collectors.values.each {|collector| collector.sweep(performer_name)}
|
36
|
-
end
|
37
|
-
|
38
|
-
def perform(context, changes)
|
39
|
-
collector = resolve!(context)
|
40
|
-
Tantot.logger.debug { "[Tantot] [Run] [#{collector.class.name.demodulize}] #{collector.debug_perform(context, changes)}" }
|
41
|
-
collector.perform(context, changes)
|
42
|
-
end
|
43
|
-
|
44
|
-
def marshal(context, changes)
|
45
|
-
collector = resolve!(context)
|
46
|
-
context, changes = collector.marshal(context, changes)
|
47
|
-
context[:collector_class] = collector.class
|
48
|
-
[context, changes]
|
49
|
-
end
|
50
|
-
|
51
|
-
def unmarshal(context, changes)
|
52
|
-
context.deep_symbolize_keys!
|
53
|
-
collector_class = context[:collector_class].constantize
|
54
|
-
collector = @collectors[collector_class] || @collectors[collector_class] = collector_class.new
|
55
|
-
collector.unmarshal(context, changes)
|
56
|
-
end
|
57
|
-
|
58
|
-
def resolve(context)
|
59
|
-
collector_class = COLLECTOR_CLASSES.find {|c| c.manages?(context)}
|
60
|
-
return nil unless collector_class
|
61
|
-
@collectors[collector_class] || @collectors[collector_class] = collector_class.new
|
62
|
-
end
|
63
|
-
|
64
|
-
def resolve!(context)
|
65
|
-
resolve(context) || (raise "No collector manages current context: #{context.inspect}")
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,46 +0,0 @@
|
|
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,69 +0,0 @@
|
|
1
|
-
module Tantot
|
2
|
-
module Collector
|
3
|
-
class Block < Base
|
4
|
-
self.context_key = :block_id
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@stash = Hash.new do |block_id_hash, block_id|
|
8
|
-
block_id_hash[block_id] = Hash.new do |id_hash, id|
|
9
|
-
id_hash[id] = {}
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def register_watch(context, block)
|
15
|
-
Tantot.registry.watch_config[context[:block_id]] = {context: context, block: block}
|
16
|
-
end
|
17
|
-
|
18
|
-
def perform(context, changes_by_id)
|
19
|
-
watch_config = Tantot.registry.watch_config[context[:block_id]]
|
20
|
-
watch_config[:context][:model].instance_exec(Tantot::Changes::ById.new(changes_by_id), &watch_config[:block])
|
21
|
-
end
|
22
|
-
|
23
|
-
def marshal(context, changes_by_id)
|
24
|
-
[context, changes_by_id]
|
25
|
-
end
|
26
|
-
|
27
|
-
def unmarshal(context, changes_by_id)
|
28
|
-
changes_by_id = changes_by_id.each.with_object({}) do |(id, changes), change_hash|
|
29
|
-
change_hash[id.to_i] = changes
|
30
|
-
end
|
31
|
-
[context, changes_by_id]
|
32
|
-
end
|
33
|
-
|
34
|
-
def debug_block(block)
|
35
|
-
location, line = block.source_location
|
36
|
-
short_path = defined?(Rails) ? Pathname.new(location).relative_path_from(Rails.root).to_s : location
|
37
|
-
"block @ #{short_path}##{line}"
|
38
|
-
end
|
39
|
-
|
40
|
-
def debug_context(context)
|
41
|
-
block = Tantot.registry.watch_config[context[:block_id]][:block]
|
42
|
-
debug_block(block)
|
43
|
-
end
|
44
|
-
|
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|
|
51
|
-
watch_config = Tantot.registry.watch_config[block_id]
|
52
|
-
debug_changes(watch_config, changes_by_id)
|
53
|
-
end.join(" / ")
|
54
|
-
end
|
55
|
-
|
56
|
-
def debug_perform(context, changes_by_id)
|
57
|
-
watch_config = Tantot.registry.watch_config[context[:block_id]]
|
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]
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
module Tantot
|
2
|
-
module Collector
|
3
|
-
class Watcher < Base
|
4
|
-
self.context_key = :watcher
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@stash = Hash.new do |watcher_hash, watcher|
|
8
|
-
watcher_hash[watcher] = Hash.new do |model_hash, model|
|
9
|
-
model_hash[model] = Hash.new do |id_hash, id|
|
10
|
-
id_hash[id] = {}
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def register_watch(context, block)
|
17
|
-
Tantot.registry.watch_config[context[:watcher]] = {context: context}
|
18
|
-
end
|
19
|
-
|
20
|
-
def perform(context, changes_by_model)
|
21
|
-
context[:watcher].new.perform(Tantot::Changes::ByModel.new(changes_by_model))
|
22
|
-
end
|
23
|
-
|
24
|
-
def marshal(context, changes_by_model)
|
25
|
-
changes_by_model = changes_by_model.each.with_object({}) do |(model_class, changes), hash|
|
26
|
-
hash[model_class.name] = changes
|
27
|
-
end
|
28
|
-
[context, changes_by_model]
|
29
|
-
end
|
30
|
-
|
31
|
-
def unmarshal(context, changes_by_model)
|
32
|
-
context[:watcher] = context[:watcher].constantize
|
33
|
-
changes_by_model = changes_by_model.each.with_object({}) do |(model_class_name, changes_by_id), model_hash|
|
34
|
-
model_hash[model_class_name.constantize] = changes_by_id.each.with_object({}) do |(id, changes), change_hash|
|
35
|
-
change_hash[id.to_i] = changes
|
36
|
-
end
|
37
|
-
end
|
38
|
-
[context, changes_by_model]
|
39
|
-
end
|
40
|
-
|
41
|
-
def debug_context(context)
|
42
|
-
context[:watcher].name
|
43
|
-
end
|
44
|
-
|
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(" / ")
|
51
|
-
end
|
52
|
-
|
53
|
-
def debug_perform(context, changes_by_model)
|
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]
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
data/lib/tantot/formatter.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
require 'tantot/formatter/compact'
|
2
|
-
require 'tantot/formatter/detailed'
|
3
|
-
|
4
|
-
module Tantot
|
5
|
-
module Formatter
|
6
|
-
def self.resolve(name)
|
7
|
-
"Tantot::Formatter::#{name.to_s.camelize}".safe_constantize or raise "Can't find formatter class `#{name}`"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
data/lib/tantot/performer.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'tantot/performer/bypass'
|
2
|
-
require 'tantot/performer/inline'
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'chewy'
|
6
|
-
require 'tantot/performer/chewy'
|
7
|
-
rescue LoadError
|
8
|
-
nil
|
9
|
-
end
|
10
|
-
|
11
|
-
begin
|
12
|
-
require 'sidekiq'
|
13
|
-
require 'tantot/performer/sidekiq'
|
14
|
-
rescue LoadError
|
15
|
-
nil
|
16
|
-
end
|
17
|
-
|
18
|
-
module Tantot
|
19
|
-
module Performer
|
20
|
-
def self.resolve(name)
|
21
|
-
"Tantot::Performer::#{name.to_s.camelize}".safe_constantize or raise "Can't find performer class `#{name}`"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,31 +0,0 @@
|
|
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(context[: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.merge({chewy_strategy: ::Chewy.strategy.current.name}), 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
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Tantot
|
2
|
-
module Performer
|
3
|
-
class Sidekiq
|
4
|
-
class Worker
|
5
|
-
include ::Sidekiq::Worker
|
6
|
-
|
7
|
-
def perform(context, changes)
|
8
|
-
context, changes = Tantot.collector.unmarshal(context, changes)
|
9
|
-
Tantot.collector.perform(context, changes)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def run(context, changes)
|
14
|
-
queue = context[:options][:queue] || Tantot.config.sidekiq_queue
|
15
|
-
::Sidekiq::Client.push('class' => Tantot::Performer::Sidekiq::Worker,
|
16
|
-
'args' => Tantot.collector.marshal(context, changes),
|
17
|
-
'queue' => queue)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|