nexia_event_store 0.9.1 → 0.10.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
  SHA1:
3
- metadata.gz: 17ccc001ca06cb2c0fdc059a29a30f63e00f028b
4
- data.tar.gz: 8b3538b01bb2cb879905c4edd13dc92f708c4d8e
3
+ metadata.gz: f2dba3805be9987a863b9c80cad063ff5ce6ecd2
4
+ data.tar.gz: 735780ad87bad4795370e51bcf22b71f85184e51
5
5
  SHA512:
6
- metadata.gz: 837398a20abc3b289698d61711da897da5824ceb384a4fdcd21b5143ad11f8a71552567c81d1202c643e1bf95a9178119027602d7a18a744e2352ed63c5023ec
7
- data.tar.gz: 58671b2fe871f9664ddd1153528c27c55063b4665d8fccae638f62a191e8c6e86b31ed98047e1b2728013958e4e56acc1eb8ad19815eda2aa2d4edbff1875aea
6
+ metadata.gz: 2b3aac7d78671e3b9ffd7c136d88ebded20358121fdf9759762cdd846e697325972725e1183a570412e475fe7fbed5bc3fd9768e885037efb1cf848e122f9ad5
7
+ data.tar.gz: 4da1989af164abf4802e5e963491fd68a2da8993154f568107ed8e02d0e8f1e88b4a576371032ee787c16906151a89fa0fabef2e3d94286c69c9d21343d79ddd
@@ -41,12 +41,7 @@ module EventStore
41
41
 
42
42
  t = Time.now
43
43
  result_hash = events_hash.inject([]) do |snapshot, (key, value)|
44
- fully_qualified_name, _ = key.split(EventStore::SNAPSHOT_KEY_DELIMITER)
45
- raw_event = value.split(EventStore::SNAPSHOT_DELIMITER)
46
- event_id = raw_event.first.to_i
47
- serialized_event = EventStore.unescape_bytea(raw_event[1])
48
- occurred_at = Time.parse(raw_event.last)
49
- snapshot + [SerializedEvent.new(fully_qualified_name, serialized_event, event_id, occurred_at)]
44
+ snapshot + [serialized_event_from_snapshot_event(key, value)]
50
45
  end
51
46
  logger.debug { "#{self.class.name} serializing events took #{Time.now - t} seconds" }
52
47
  result_hash.sort_by(&:event_id).each { |e| yield e }
@@ -99,16 +94,47 @@ module EventStore
99
94
  end
100
95
 
101
96
  def update_fqns!(logger = default_logger)
102
- updated_events = replace_fqns_in_snapshot_hash(read_with_rebuild(logger)) { |fqn| yield fqn }
97
+ logger.debug { "Replacing FQNs in snapshot events" }
98
+ updated_events = replace_fqns_in_snapshot_hash(read_with_rebuild(logger)) { |fqn| yield fqn }
99
+
100
+ logger.debug { "Replacing FQNs in snapshot event ids" }
103
101
  updated_event_ids = replace_fqns_in_snapshot_hash(current_event_id_numbers) { |fqn|
104
102
  fqn == 'current_event_id' ? fqn : (yield fqn)
105
103
  }
106
104
 
107
- update_snapshot_tables(updated_event_ids, updated_events, replace: true)
105
+ logger.debug "Updating snapshot tables in redis"
106
+ replace_snapshot_tables(updated_event_ids, updated_events)
107
+ end
108
+
109
+ def reject!(logger = default_logger)
110
+ events_to_keep = read_with_rebuild(logger)
111
+ event_ids = current_event_id_numbers
112
+
113
+ events_to_keep.dup.each { |snapshot_key, snapshot_event|
114
+ serialized_event = serialized_event_from_snapshot_event(snapshot_key, snapshot_event)
115
+ drop_it = yield serialized_event
116
+
117
+ if drop_it
118
+ events_to_keep.delete(snapshot_key)
119
+ event_ids.delete(snapshot_key)
120
+ end
121
+ }
122
+
123
+ replace_snapshot_tables(event_ids.flatten, events_to_keep.flatten)
108
124
  end
109
125
 
110
126
  private
111
127
 
128
+ def serialized_event_from_snapshot_event(snapshot_key, snapshot_value)
129
+ fully_qualified_name, _ = snapshot_key.split(EventStore::SNAPSHOT_KEY_DELIMITER)
130
+ raw_event = snapshot_value.split(EventStore::SNAPSHOT_DELIMITER)
131
+ event_id = raw_event.first.to_i
132
+ serialized_event = EventStore.unescape_bytea(raw_event[1])
133
+ occurred_at = Time.parse(raw_event.last)
134
+
135
+ SerializedEvent.new(fully_qualified_name, serialized_event, event_id, occurred_at)
136
+ end
137
+
112
138
  def replace_fqns_in_snapshot_hash(snapshot_keyed_hash)
113
139
  snapshot_keyed_hash.inject([]) { |memo, (snapshot_key, value)|
114
140
  new_key = replace_fqn_in_snapshot_key(snapshot_key) { |fqn| yield fqn }
@@ -122,16 +148,21 @@ module EventStore
122
148
  [new_fqn, sub_key].compact.join(EventStore::SNAPSHOT_KEY_DELIMITER)
123
149
  end
124
150
 
125
- # params are flattened hashes, i.e., [key1, val1, key2, val2, ...]
126
- def update_snapshot_tables(event_ids_array, events_array, replace: false)
151
+ def replace_snapshot_tables(event_ids_array, events_array)
127
152
  @redis.multi do
128
- @redis.del snapshot_event_id_table if replace
129
- @redis.hmset(snapshot_event_id_table, event_ids_array)
130
- @redis.del snapshot_table if replace
131
- @redis.hmset(snapshot_table, events_array)
153
+ delete_snapshot!
154
+ update_snapshot_tables(event_ids_array, events_array)
132
155
  end
133
156
  end
134
157
 
158
+ # params are flattened hashes, i.e., [key1, val1, key2, val2, ...]
159
+ def update_snapshot_tables(event_ids_array, events_array)
160
+ return unless events_array.any?
161
+
162
+ @redis.hmset(snapshot_event_id_table, event_ids_array)
163
+ @redis.hmset(snapshot_table, events_array)
164
+ end
165
+
135
166
  def default_logger
136
167
  Logger.new('/dev/null')
137
168
  end
@@ -1,3 +1,3 @@
1
1
  module EventStore
2
- VERSION = '0.9.1'
2
+ VERSION = '0.10.0'
3
3
  end
@@ -23,66 +23,110 @@ module EventStore
23
23
  end
24
24
 
25
25
  context "with events in the stream" do
26
- let(:client) { EventStore::Client.new(AGGREGATE_ID_TWO) }
26
+ let(:client) { EventStore::Client.new(AGGREGATE_ID_TWO) }
27
+ let(:snapshot) { client.snapshot }
28
+ let(:events) { events_for(AGGREGATE_ID_TWO) }
27
29
 
28
- before do
29
- expect(client.snapshot.count).to eq(0)
30
- client.append events_for(AGGREGATE_ID_TWO)
31
- end
30
+ before {
31
+ expect(snapshot.count).to eq(0)
32
+ client.append events
33
+ }
32
34
 
33
35
  describe "#count" do
34
36
  it "delegates to the snapshot hash" do
35
- expect(client.snapshot.count).to eq(8)
37
+ expect(snapshot.count).to eq(8)
36
38
  end
37
39
  end
38
40
 
39
41
  describe "#update_fqns!" do
40
- let(:original_events) { client.snapshot.to_a }
42
+ let(:original_events) { snapshot.to_a }
41
43
 
42
44
  it "replaces fully qualified names in the snapshot with the value of a block" do
43
- client.snapshot.update_fqns! { |fqn|
45
+ snapshot.update_fqns! { |fqn|
44
46
  fqn =~ /^(e[0-9])/ ? fqn.upcase : fqn
45
47
  }
46
48
 
47
49
  expected_snapshot_events = original_events.map { |serialized_event| serialized_event.fully_qualified_name.upcase }
48
- expect(client.snapshot.map(&:fully_qualified_name).to_set).to eq(expected_snapshot_events.to_set)
50
+ expect(snapshot.map(&:fully_qualified_name).to_set).to eq(expected_snapshot_events.to_set)
49
51
  end
50
52
 
51
53
  it "does not affect the current event id" do
52
- old_event_id = client.snapshot.event_id
54
+ old_event_id = snapshot.event_id
53
55
 
54
- client.snapshot.update_fqns! { |fqn| fqn.upcase }
56
+ snapshot.update_fqns! { |fqn| fqn.upcase }
55
57
 
56
- new_event_id = client.snapshot.event_id
58
+ new_event_id = snapshot.event_id
57
59
 
58
60
  expect(new_event_id).to eq(old_event_id)
59
61
  end
60
62
 
61
63
  it "doesn't affect the fully qualified name when the block returns nil" do
62
64
  old_fqns = original_events.map(&:fully_qualified_name)
63
- client.snapshot.update_fqns! { |_fqn| nil }
65
+ snapshot.update_fqns! { |_fqn| nil }
66
+
67
+ expect(snapshot.map(&:fully_qualified_name).to_set).to eq(old_fqns.to_set)
68
+ end
69
+ end
70
+
71
+ describe "#reject!" do
72
+ it "yields the serialized event to the block" do
73
+ snapshot.reject! { |serialized_event|
74
+ expect(events.map(&:fully_qualified_name)).to include(serialized_event.fully_qualified_name)
75
+ expect(events.map(&:serialized_event)).to include(serialized_event.serialized_event)
76
+ }
77
+ end
78
+
79
+ context "when the block returns true" do
80
+ before(:each) { snapshot.reject! { |serialized_event| serialized_event.fully_qualified_name == 'e1' } }
81
+
82
+ it "removes the event from the snapshot" do
83
+ expect(snapshot.map(&:fully_qualified_name)).not_to include('e1')
84
+ end
85
+
86
+ it "removes the event id from the snapshot" do
87
+ expect(snapshot.event_id_for('e1')).to eq(-1)
88
+ end
89
+ end
90
+
91
+ context "when the block returns false" do
92
+ before(:each) { snapshot.reject! { |serialized_event| serialized_event.fully_qualified_name != 'e1' } }
93
+
94
+ it "retains the event in the snapshot" do
95
+ expect(snapshot.map(&:fully_qualified_name)).to include('e1')
96
+ end
97
+
98
+ it "retains the event id in the snapshot" do
99
+ expect(snapshot.event_id_for('e1')).not_to eq(-1)
100
+ end
101
+ end
102
+
103
+ context "when all events are rejected" do
104
+ before(:each) { snapshot.reject! { true } }
64
105
 
65
- expect(client.snapshot.map(&:fully_qualified_name).to_set).to eq(old_fqns.to_set)
106
+ it "deletes the snapshot out of Redis" do
107
+ expect(EventStore.redis.keys(snapshot.snapshot_table).length).to eq(0)
108
+ expect(EventStore.redis.keys(snapshot.snapshot_event_id_table).length).to eq(0)
109
+ end
66
110
  end
67
111
  end
68
112
 
69
113
  it "rebuilds a snapshot after it is deleted" do
70
- snapshot = client.snapshot
114
+ snapshot = snapshot
71
115
  client.delete_snapshot!
72
116
  client.rebuild_snapshot!
73
- expect(client.snapshot).to eq(snapshot)
117
+ expect(snapshot).to eq(snapshot)
74
118
  end
75
119
 
76
120
  it "automatically rebuilds the snapshot if events exist, but the snapshot is empty" do
77
- snapshot = client.snapshot
121
+ snapshot = snapshot
78
122
  client.delete_snapshot!
79
- expect(client.snapshot).to eq(snapshot)
123
+ expect(snapshot).to eq(snapshot)
80
124
  end
81
125
 
82
126
  it "finds the most recent records for each type" do
83
127
  expected_snapshot_events = %w{e3 e1 e2 e5 e4 e7 e8 e7} #sorted by version no
84
128
  expected_snapshot = serialized_events(expected_snapshot_events)
85
- actual_snapshot = client.snapshot
129
+ actual_snapshot = snapshot
86
130
 
87
131
  expect(client.event_stream.count).to eq(15)
88
132
  expect(actual_snapshot.map(&:fully_qualified_name)).to eq(expected_snapshot_events)
@@ -91,7 +135,7 @@ module EventStore
91
135
  end
92
136
 
93
137
  it "increments the version number of the snapshot when an event is appended" do
94
- expect(client.snapshot.event_id).to eq(client.raw_event_stream.last[:id])
138
+ expect(snapshot.event_id).to eq(client.raw_event_stream.last[:id])
95
139
  end
96
140
  end
97
141
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexia_event_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Saieg, John Colvin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-16 00:00:00.000000000 Z
12
+ date: 2016-03-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler