aggregate_root 0.39.0 → 0.40.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07b31561cc74b2f7be4a3a714f2af9e9f1b82a6567707249da9d16f8271f7f2f
4
- data.tar.gz: 612fdb3ec19422a7885ed38c64f70f241fa67b34270be0ab708ef3186581d24d
3
+ metadata.gz: 6af35e06f7f261f5275b2e0f74b4abba41d7437a94d9527d66e7add0bf6d3788
4
+ data.tar.gz: fe132199dc2121bdb0bf5aa2591714aab84553a90a270307f79890b0276fca6a
5
5
  SHA512:
6
- metadata.gz: d55999302930c6c01dd9275f0d0bd092a33c078d09c61d69703fa91f18715b5330e50c3e3d752bfece462aecaf1f0200b58fea52bf891035666c9e6a2430cc43
7
- data.tar.gz: 3601973a69042ad88e2aa0f24091cc2aad120b4c5d265b98587a72def5b8f4cb456f161c19dcd34cb1bfbd4e625e623fd0ce64fbb74997b3cad60b7ac543b4bc
6
+ metadata.gz: 7157ba51608adc985fe90e595c7413b20ff15445d7c0830f05199c130f9449a4ac3f566b616beade6c19c4511168b078603f37e1dd79a4818f89c426c7b2f4fe
7
+ data.tar.gz: 50fe99d76b6073c9068a0cb93dd6775839cda59aed9a4f761adaa097b11316e9e3c19dffd94102b6fdc75cf769f055977b1a5ee67752e18bdc577bb78de3b960
data/Gemfile CHANGED
@@ -4,4 +4,7 @@ gemspec
4
4
 
5
5
  eval_gemfile File.expand_path('../support/bundler/Gemfile.shared', __dir__)
6
6
 
7
- gem 'ruby_event_store', path: '../ruby_event_store'
7
+ gem 'ruby_event_store', path: '../ruby_event_store'
8
+ gem 'protobuf_nested_struct'
9
+ gem 'google-protobuf', '~> 3.7.0'
10
+ gem 'activesupport', '~> 5.0'
@@ -25,5 +25,5 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
- spec.add_dependency 'ruby_event_store', '= 0.39.0'
28
+ spec.add_dependency 'ruby_event_store', '= 0.40.0'
29
29
  end
@@ -3,92 +3,83 @@ require 'aggregate_root/configuration'
3
3
  require 'aggregate_root/transform'
4
4
  require 'aggregate_root/default_apply_strategy'
5
5
  require 'aggregate_root/repository'
6
+ require 'aggregate_root/instrumented_repository'
7
+
6
8
 
7
9
  module AggregateRoot
8
- module ClassMethods
10
+ module OnDSL
9
11
  def on(*event_klasses, &block)
10
12
  event_klasses.each do |event_klass|
11
- name = event_klass.name || raise(ArgumentError, "Anonymous class is missing name")
13
+ name = event_klass.to_s
14
+ raise(ArgumentError, "Anonymous class is missing name") if name.start_with? "#<Class:"
12
15
  handler_name = "on_#{name}"
13
16
  define_method(handler_name, &block)
14
17
  @on_methods ||= {}
15
- @on_methods[event_klass]=handler_name
18
+ @on_methods[name] = handler_name
16
19
  private(handler_name)
17
20
  end
18
21
  end
19
22
 
20
23
  def on_methods
21
- ancestors.
22
- select{|k| k.instance_variables.include?(:@on_methods)}.
23
- map{|k| k.instance_variable_get(:@on_methods) }.
24
- inject({}, &:merge)
24
+ @on_methods ||= {}
25
+ (superclass.respond_to?(:on_methods) ? superclass.on_methods : {}).merge(@on_methods)
25
26
  end
26
27
  end
27
28
 
28
- def self.included(host_class)
29
- host_class.extend(ClassMethods)
30
- end
31
-
32
- def apply(*events)
33
- events.each do |event|
34
- apply_strategy.(self, event)
35
- unpublished << event
29
+ module Constructor
30
+ def new
31
+ super().tap do |instance|
32
+ instance.instance_variable_set(:@version, -1)
33
+ instance.instance_variable_set(:@unpublished_events, [])
34
+ end
36
35
  end
37
36
  end
38
37
 
39
- def version
40
- @version ||= -1
41
- end
38
+ module AggregateMethods
39
+ def apply(*events)
40
+ events.each do |event|
41
+ apply_strategy.(self, event)
42
+ @unpublished_events << event
43
+ end
44
+ end
42
45
 
43
- def version=(value)
44
- @unpublished_events = nil
45
- @version = value
46
- end
46
+ def version
47
+ @version
48
+ end
47
49
 
48
- def unpublished_events
49
- unpublished.each
50
- end
50
+ def version=(value)
51
+ @unpublished_events = []
52
+ @version = value
53
+ end
51
54
 
52
- def load(stream_name, event_store: default_event_store)
53
- warn <<~EOW
54
- Method `load` on aggregate is deprecated. Use AggregateRoot::Repository instead.
55
- Instead of: `order = Order.new.load("OrderStreamHere")`
56
- you need to have code:
57
- ```
58
- repository = AggregateRoot::Repository.new
59
- order = repository.load(Order.new, "OrderStreamHere")
60
- ```
61
- EOW
62
- @loaded_from_stream_name = stream_name
63
- Repository.new(event_store).load(self, stream_name)
55
+ def unpublished_events
56
+ @unpublished_events.each
57
+ end
64
58
  end
65
59
 
66
- def store(stream_name = loaded_from_stream_name, event_store: default_event_store)
67
- warn <<~EOW
68
- Method `store` on aggregate is deprecated. Use AggregateRoot::Repository instead.
69
- Instead of: `order.store("OrderStreamHere")`
70
- you need to have code:
71
- ```
72
- repository = AggregateRoot::Repository.new
73
- # load and order and execute some operation on it here
74
- repository.store(order, "OrderStreamHere")
75
- ```
76
- EOW
77
- Repository.new(event_store).store(self, stream_name)
60
+ def self.with_default_apply_strategy
61
+ Module.new do
62
+ def self.included(host_class)
63
+ host_class.extend OnDSL
64
+ host_class.include AggregateRoot.with_strategy(->{ DefaultApplyStrategy.new })
65
+ end
66
+ end
78
67
  end
79
68
 
80
- private
81
- attr_reader :loaded_from_stream_name
82
-
83
- def default_event_store
84
- AggregateRoot.configuration.default_event_store
85
- end
69
+ def self.with_strategy(strategy)
70
+ Module.new do
71
+ def self.included(host_class)
72
+ host_class.extend Constructor
73
+ host_class.include AggregateMethods
74
+ end
86
75
 
87
- def unpublished
88
- @unpublished_events ||= []
76
+ define_method :apply_strategy do
77
+ strategy.call
78
+ end
79
+ end
89
80
  end
90
81
 
91
- def apply_strategy
92
- DefaultApplyStrategy.new(on_methods: self.class.on_methods)
82
+ def self.included(host_class)
83
+ host_class.include with_default_apply_strategy
93
84
  end
94
85
  end
@@ -2,13 +2,12 @@ module AggregateRoot
2
2
  MissingHandler = Class.new(StandardError)
3
3
 
4
4
  class DefaultApplyStrategy
5
- def initialize(strict: true, on_methods: {})
5
+ def initialize(strict: true)
6
6
  @strict = strict
7
- @on_methods = on_methods
8
7
  end
9
8
 
10
9
  def call(aggregate, event)
11
- name = handler_name(event)
10
+ name = handler_name(aggregate, event)
12
11
  if aggregate.respond_to?(name, true)
13
12
  aggregate.method(name).call(event)
14
13
  else
@@ -18,16 +17,16 @@ module AggregateRoot
18
17
 
19
18
  private
20
19
 
21
- def handler_name(event)
22
- on_methods.fetch(event.class) { handler_name_by_class(event.class) }
20
+ def handler_name(aggregate, event)
21
+ aggregate.class.on_methods.fetch(event.type) { handler_name_by_type(event.type) }
23
22
  end
24
23
 
25
- def handler_name_by_class(event_class)
26
- "apply_#{Transform.to_snake_case(class_name(event_class))}"
24
+ def handler_name_by_type(event_type)
25
+ "apply_#{Transform.to_snake_case(event_type(event_type))}"
27
26
  end
28
27
 
29
- def class_name(event_class)
30
- event_class.name.split("::").last
28
+ def event_type(event_type)
29
+ event_type.split(%r{::|\.}).last
31
30
  end
32
31
 
33
32
  private
@@ -0,0 +1,34 @@
1
+ module AggregateRoot
2
+ class InstrumentedRepository
3
+ def initialize(repository, instrumentation)
4
+ @repository = repository
5
+ @instrumentation = instrumentation
6
+ end
7
+
8
+ def load(aggregate, stream_name)
9
+ instrumentation.instrument("load.repository.aggregate_root",
10
+ aggregate: aggregate,
11
+ stream: stream_name) do
12
+ repository.load(aggregate, stream_name)
13
+ end
14
+ end
15
+
16
+ def store(aggregate, stream_name)
17
+ instrumentation.instrument("store.repository.aggregate_root",
18
+ aggregate: aggregate,
19
+ version: aggregate.version,
20
+ stored_events: aggregate.unpublished_events.to_a,
21
+ stream: stream_name) do
22
+ repository.store(aggregate, stream_name)
23
+ end
24
+ end
25
+
26
+ def with_aggregate(aggregate, stream_name, &block)
27
+ block.call(load(aggregate, stream_name))
28
+ store(aggregate, stream_name)
29
+ end
30
+
31
+ private
32
+ attr_reader :instrumentation, :repository
33
+ end
34
+ end
@@ -29,4 +29,4 @@ module AggregateRoot
29
29
  AggregateRoot.configuration.default_event_store
30
30
  end
31
31
  end
32
- end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module AggregateRoot
2
- VERSION = "0.39.0"
2
+ VERSION = "0.40.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aggregate_root
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.0
4
+ version: 0.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-24 00:00:00.000000000 Z
11
+ date: 2019-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_event_store
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.39.0
19
+ version: 0.40.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.39.0
26
+ version: 0.40.0
27
27
  description: Event sourced (with Rails Event Store) aggregate root implementation
28
28
  email:
29
29
  - dev@arkency.com
@@ -39,6 +39,7 @@ files:
39
39
  - lib/aggregate_root.rb
40
40
  - lib/aggregate_root/configuration.rb
41
41
  - lib/aggregate_root/default_apply_strategy.rb
42
+ - lib/aggregate_root/instrumented_repository.rb
42
43
  - lib/aggregate_root/repository.rb
43
44
  - lib/aggregate_root/transform.rb
44
45
  - lib/aggregate_root/version.rb
@@ -65,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
66
  - !ruby/object:Gem::Version
66
67
  version: '0'
67
68
  requirements: []
68
- rubygems_version: 3.0.3
69
+ rubygems_version: 3.0.1
69
70
  signing_key:
70
71
  specification_version: 4
71
72
  summary: Event sourced (with Rails Event Store) aggregate root implementation