aggregate_root 2.16.0 → 2.17.0
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/aggregate_root/instrumented_apply_strategy.rb +1 -3
- data/lib/aggregate_root/instrumented_repository.rb +2 -2
- data/lib/aggregate_root/repository.rb +1 -1
- data/lib/aggregate_root/snapshot_repository.rb +16 -12
- data/lib/aggregate_root/version.rb +1 -1
- data/lib/aggregate_root.rb +26 -13
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec3c57bd9d2903a392c849933d4d108cfe511a4477ab306e809701ca664520ab
|
4
|
+
data.tar.gz: a30551197ae98c554afcd5ecffdd3b5121b856a24dd2f98e5396d2a136a04267
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d02749d90d889cdf25784d0786ed2de633877c157cbc9d850d16ffbff8bb88515b639e4a23a6e4d70652651142011479412bf462d4b7809f877c2f9e281d8e7
|
7
|
+
data.tar.gz: 0e6ebcb2c9632d762c1d35adab32e694699cc399cf90b03abfcc154a64c7d7768f541c6ec70085749ecafa931f4b9fd440e2aebcd257d282b0260802f47d1911
|
@@ -8,9 +8,7 @@ module AggregateRoot
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def call(aggregate, event)
|
11
|
-
instrumentation.instrument("apply.aggregate_root",
|
12
|
-
aggregate: aggregate,
|
13
|
-
event: event) do
|
11
|
+
instrumentation.instrument("apply.aggregate_root", aggregate: aggregate, event: event) do
|
14
12
|
strategy.call(aggregate, event)
|
15
13
|
end
|
16
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "delegate"
|
4
4
|
module AggregateRoot
|
5
5
|
class InstrumentedRepository
|
6
6
|
def initialize(repository, instrumentation)
|
@@ -21,7 +21,7 @@ module AggregateRoot
|
|
21
21
|
aggregate: aggregate,
|
22
22
|
version: aggregate.version,
|
23
23
|
stored_events: aggregate.unpublished_events.to_a,
|
24
|
-
stream: stream_name
|
24
|
+
stream: stream_name,
|
25
25
|
) { repository.store(aggregate, stream_name) }
|
26
26
|
end
|
27
27
|
|
@@ -16,7 +16,7 @@ module AggregateRoot
|
|
16
16
|
event_store.publish(
|
17
17
|
aggregate.unpublished_events.to_a,
|
18
18
|
stream_name: stream_name,
|
19
|
-
expected_version: aggregate.version
|
19
|
+
expected_version: aggregate.version,
|
20
20
|
)
|
21
21
|
aggregate.version = aggregate.version + aggregate.unpublished_events.count
|
22
22
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "ruby_event_store/event"
|
4
4
|
|
5
5
|
module AggregateRoot
|
6
6
|
class SnapshotRepository
|
@@ -10,11 +10,11 @@ module AggregateRoot
|
|
10
10
|
NotDumpableAggregateRoot = Class.new(StandardError)
|
11
11
|
|
12
12
|
def initialize(event_store, interval = DEFAULT_SNAPSHOT_INTERVAL)
|
13
|
-
raise ArgumentError,
|
14
|
-
raise ArgumentError,
|
13
|
+
raise ArgumentError, "interval must be an Integer" unless interval.instance_of?(Integer)
|
14
|
+
raise ArgumentError, "interval must be greater than 0" unless interval > 0
|
15
15
|
@event_store = event_store
|
16
16
|
@interval = interval
|
17
|
-
@error_handler = ->(_) {
|
17
|
+
@error_handler = ->(_) {}
|
18
18
|
end
|
19
19
|
|
20
20
|
attr_writer :error_handler
|
@@ -41,9 +41,7 @@ module AggregateRoot
|
|
41
41
|
|
42
42
|
def store(aggregate, stream_name)
|
43
43
|
events = aggregate.unpublished_events.to_a
|
44
|
-
event_store.publish(events,
|
45
|
-
stream_name: stream_name,
|
46
|
-
expected_version: aggregate.version)
|
44
|
+
event_store.publish(events, stream_name: stream_name, expected_version: aggregate.version)
|
47
45
|
|
48
46
|
aggregate.version = aggregate.version + events.count
|
49
47
|
|
@@ -63,16 +61,21 @@ module AggregateRoot
|
|
63
61
|
def publish_snapshot_event(aggregate, stream_name, last_event_id)
|
64
62
|
event_store.publish(
|
65
63
|
Snapshot.new(
|
66
|
-
data: {
|
64
|
+
data: {
|
65
|
+
marshal: build_marshal(aggregate),
|
66
|
+
last_event_id: last_event_id,
|
67
|
+
version: aggregate.version,
|
68
|
+
},
|
67
69
|
),
|
68
|
-
stream_name: SNAPSHOT_STREAM_PATTERN.(stream_name)
|
70
|
+
stream_name: SNAPSHOT_STREAM_PATTERN.(stream_name),
|
69
71
|
)
|
70
72
|
end
|
71
73
|
|
72
74
|
def build_marshal(aggregate)
|
73
75
|
Marshal.dump(aggregate)
|
74
76
|
rescue TypeError
|
75
|
-
raise NotDumpableAggregateRoot,
|
77
|
+
raise NotDumpableAggregateRoot,
|
78
|
+
"#{aggregate.class} cannot be dumped.
|
76
79
|
It may be caused by instance variables being: bindings, procedure or method objects, instances of class IO, or singleton objects.
|
77
80
|
Snapshot skipped."
|
78
81
|
end
|
@@ -84,7 +87,8 @@ Snapshot skipped."
|
|
84
87
|
def load_marshal(snpashot_event)
|
85
88
|
Marshal.load(snpashot_event.data.fetch(:marshal))
|
86
89
|
rescue TypeError, ArgumentError
|
87
|
-
raise NotRestorableSnapshot,
|
90
|
+
raise NotRestorableSnapshot,
|
91
|
+
"Aggregate root cannot be restored from the last snapshot (event id: #{snpashot_event.event_id}).
|
88
92
|
It may be caused by aggregate class rename or Marshal version mismatch.
|
89
93
|
Loading aggregate based on the whole stream."
|
90
94
|
end
|
@@ -95,4 +99,4 @@ Loading aggregate based on the whole stream."
|
|
95
99
|
just_published_events > events_since_time_for_snapshot
|
96
100
|
end
|
97
101
|
end
|
98
|
-
end
|
102
|
+
end
|
data/lib/aggregate_root.rb
CHANGED
@@ -15,7 +15,7 @@ module AggregateRoot
|
|
15
15
|
|
16
16
|
def on(*event_klasses, &block)
|
17
17
|
event_klasses.each do |event_klass|
|
18
|
-
name = event_klass
|
18
|
+
name = event_type_for(event_klass)
|
19
19
|
raise(ArgumentError, "Anonymous class is missing name") if name.start_with? ANONYMOUS_CLASS
|
20
20
|
|
21
21
|
handler_name = "on_#{name}"
|
@@ -62,36 +62,48 @@ module AggregateRoot
|
|
62
62
|
@unpublished_events.each
|
63
63
|
end
|
64
64
|
|
65
|
-
UNMARSHALED_VARIABLES = [
|
65
|
+
UNMARSHALED_VARIABLES = %i[@version @unpublished_events]
|
66
66
|
|
67
67
|
def marshal_dump
|
68
|
-
instance_variables
|
69
|
-
|
70
|
-
vars
|
71
|
-
|
68
|
+
instance_variables
|
69
|
+
.reject { |m| UNMARSHALED_VARIABLES.include? m }
|
70
|
+
.inject({}) do |vars, attr|
|
71
|
+
vars[attr] = instance_variable_get(attr)
|
72
|
+
vars
|
73
|
+
end
|
72
74
|
end
|
73
75
|
|
74
76
|
def marshal_load(vars)
|
75
|
-
vars.each
|
76
|
-
instance_variable_set(attr, value) unless UNMARSHALED_VARIABLES.include?(attr)
|
77
|
-
end
|
77
|
+
vars.each { |attr, value| instance_variable_set(attr, value) unless UNMARSHALED_VARIABLES.include?(attr) }
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
81
|
def self.with_default_apply_strategy
|
82
82
|
Module.new do
|
83
83
|
def self.included(host_class)
|
84
|
-
|
85
|
-
|
84
|
+
warn <<~EOW
|
85
|
+
Please replace include AggregateRoot.with_default_apply_strategy with include AggregateRoot
|
86
|
+
EOW
|
87
|
+
host_class.include AggregateRoot
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
90
92
|
def self.with_strategy(strategy)
|
93
|
+
warn <<~EOW
|
94
|
+
Please replace include AggregateRoot.with_strategy(...) with include AggregateRoot.with(strategy: ...)
|
95
|
+
EOW
|
96
|
+
with(strategy: strategy)
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.with(strategy: -> { DefaultApplyStrategy.new }, event_type_resolver: ->(value) { value.to_s })
|
91
100
|
Module.new do
|
92
|
-
|
101
|
+
define_singleton_method :included do |host_class|
|
93
102
|
host_class.extend Constructor
|
94
103
|
host_class.include AggregateMethods
|
104
|
+
host_class.define_singleton_method :event_type_for do |value|
|
105
|
+
event_type_resolver.call(value)
|
106
|
+
end
|
95
107
|
end
|
96
108
|
|
97
109
|
define_method :apply_strategy do
|
@@ -101,6 +113,7 @@ module AggregateRoot
|
|
101
113
|
end
|
102
114
|
|
103
115
|
def self.included(host_class)
|
104
|
-
host_class.
|
116
|
+
host_class.extend OnDSL
|
117
|
+
host_class.include with
|
105
118
|
end
|
106
119
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aggregate_root
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arkency
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: ruby_event_store
|
@@ -15,14 +15,14 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 2.
|
18
|
+
version: 2.17.0
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - '='
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: 2.
|
25
|
+
version: 2.17.0
|
26
26
|
email: dev@arkency.com
|
27
27
|
executables: []
|
28
28
|
extensions: []
|
@@ -62,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: '0'
|
64
64
|
requirements: []
|
65
|
-
rubygems_version: 3.6.
|
65
|
+
rubygems_version: 3.6.9
|
66
66
|
specification_version: 4
|
67
67
|
summary: Event sourced aggregate root implementation for RubyEventStore
|
68
68
|
test_files: []
|