active_projection 0.3.0 → 0.4.1
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/active_projection/event_client.rb +10 -1
- data/lib/active_projection/projection_type.rb +48 -18
- data/lib/active_projection/projection_type_registry.rb +1 -1
- data/lib/active_projection/version.rb +1 -1
- data/spec/lib/projection_type_registry_spec.rb +4 -3
- data/spec/lib/projecton_type_spec.rb +8 -8
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6b4b40f0225e31820939e9bfe3148ea9f212e47
|
4
|
+
data.tar.gz: 0aa40406e3d1bb73fcf2073290b9154e67ed7e94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6488612d653cdbba05c73f17276e73c534a1fdcb6d35c1740c536bdf87b3c950ffc5941a0059bd9f0afbea120db2d9be290c47c84df5b07cfa8a750c71de5a9
|
7
|
+
data.tar.gz: 49c4483a2904602e73395a14d5ad1ef731c53e5dba486e272caddbf9924a076480e137fbc6bac06e7b8a93fc4b7363eb9e4533625aedc5deb342ea457b620d05
|
@@ -21,6 +21,7 @@ module ActiveProjection
|
|
21
21
|
def listen_for_events
|
22
22
|
subscribe_to event_queue do |delivery_info, properties, body|
|
23
23
|
event_received properties, body
|
24
|
+
send_browser_notification properties.headers[:id]
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -35,6 +36,10 @@ module ActiveProjection
|
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
39
|
+
def send_browser_notification(id)
|
40
|
+
server_side_events_exchange.publish id.to_s
|
41
|
+
end
|
42
|
+
|
38
43
|
def send_request_for(id)
|
39
44
|
resend_request_exchange.publish id.to_s, routing_key: 'resend_request'
|
40
45
|
end
|
@@ -51,7 +56,7 @@ module ActiveProjection
|
|
51
56
|
def event_received(properties, body)
|
52
57
|
RELOADER.execute_if_updated
|
53
58
|
puts "Received #{properties.type} with #{body}"
|
54
|
-
ProjectionTypeRegistry.process properties.headers.deep_symbolize_keys
|
59
|
+
ProjectionTypeRegistry.process properties.headers.deep_symbolize_keys!, build_event(properties.type, JSON.parse(body))
|
55
60
|
end
|
56
61
|
|
57
62
|
def build_event(type, data)
|
@@ -94,6 +99,10 @@ module ActiveProjection
|
|
94
99
|
@resend_request_exchange ||= event_channel.direct "resend_request_#{options[:event_exchange]}"
|
95
100
|
end
|
96
101
|
|
102
|
+
def server_side_events_exchange
|
103
|
+
@server_side_events_exchange ||= event_channel.fanout "server_side_#{options[:event_exchange]}"
|
104
|
+
end
|
105
|
+
|
97
106
|
def options
|
98
107
|
@options
|
99
108
|
end
|
@@ -13,44 +13,74 @@ module ActiveProjection
|
|
13
13
|
end
|
14
14
|
self.class.public_instance_methods(false).each do |method_name|
|
15
15
|
method = self.class.instance_method method_name
|
16
|
-
|
17
|
-
|
18
|
-
handlers[event_type] << method.
|
16
|
+
raise WrongArgumentsCountError if 2 < method.arity or method.arity < 1
|
17
|
+
event_type = ProjectionType.method_name_to_event_type method_name
|
18
|
+
handlers[event_type] << [method_name, method.arity]
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def evaluate(headers)
|
23
|
-
return false unless
|
24
|
-
last_id =
|
23
|
+
return false unless solid? || headers[:replayed]
|
24
|
+
last_id = fetch_last_id
|
25
|
+
event_id = headers[:id]
|
25
26
|
case
|
26
|
-
when last_id + 1 ==
|
27
|
-
ProjectionRepository.set_last_id projection_id, headers[:store_id]
|
28
|
-
puts "process this event"
|
27
|
+
when last_id + 1 == event_id
|
29
28
|
true
|
30
|
-
when last_id >=
|
31
|
-
puts "event already processed"
|
29
|
+
when last_id >= event_id
|
30
|
+
puts "[#{self.class.name}] event #{event_id} already processed"
|
32
31
|
false
|
33
|
-
when last_id <
|
34
|
-
|
35
|
-
|
32
|
+
when last_id < event_id
|
33
|
+
set_broken
|
34
|
+
puts "[#{self.class.name}] #{event_id - last_id} events are missing"
|
36
35
|
false
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
40
|
-
def invoke(event)
|
41
|
-
|
42
|
-
|
43
|
-
handlers[event_type].each do |method|
|
44
|
-
|
39
|
+
def invoke(event, headers)
|
40
|
+
event_id = headers[:id]
|
41
|
+
event_type = event.class.name.to_sym
|
42
|
+
handlers[event_type].each do |method, arity|
|
43
|
+
begin
|
44
|
+
if 1 == arity
|
45
|
+
self.send method, event
|
46
|
+
else
|
47
|
+
self.send method, event, headers
|
48
|
+
end
|
49
|
+
rescue Exception
|
50
|
+
puts "[#{self.class.name}] error processing #{event_type}[#{event_id}]"
|
51
|
+
raise
|
52
|
+
end
|
45
53
|
end
|
54
|
+
update_last_id event_id
|
55
|
+
puts "[#{self.class.name}] sucessfully processed #{event_type}[#{event_id}]"
|
46
56
|
end
|
47
57
|
|
48
58
|
private
|
49
59
|
attr_accessor :handlers
|
50
60
|
attr_writer :projection_id
|
51
61
|
|
62
|
+
def self.method_name_to_event_type(method_name)
|
63
|
+
method_name.to_s.gsub('__', '/').camelcase.to_sym
|
64
|
+
end
|
65
|
+
|
52
66
|
def projection_id
|
53
67
|
@projection_id ||= ProjectionRepository.create_or_get(self.class.name).id
|
54
68
|
end
|
69
|
+
|
70
|
+
def solid?
|
71
|
+
ProjectionRepository.solid? projection_id
|
72
|
+
end
|
73
|
+
|
74
|
+
def fetch_last_id
|
75
|
+
ProjectionRepository.get_last_id projection_id
|
76
|
+
end
|
77
|
+
|
78
|
+
def set_broken
|
79
|
+
ProjectionRepository.set_broken projection_id
|
80
|
+
end
|
81
|
+
|
82
|
+
def update_last_id(id)
|
83
|
+
ProjectionRepository.set_last_id projection_id, id
|
84
|
+
end
|
55
85
|
end
|
56
86
|
end
|
@@ -15,7 +15,7 @@ module ActiveProjection
|
|
15
15
|
def process(headers, event)
|
16
16
|
projections.each do |projection|
|
17
17
|
ActiveRecord::Base.transaction do
|
18
|
-
projection.invoke
|
18
|
+
projection.invoke(event, headers) if projection.evaluate headers
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -14,9 +14,10 @@ describe ActiveProjection::ProjectionTypeRegistry do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'invokes event handlers' do
|
17
|
+
headers = {}
|
17
18
|
event = TestEvent.new
|
18
|
-
expect_any_instance_of(TestProjection).to receive(:evaluate).with(
|
19
|
-
expect_any_instance_of(TestProjection).to receive(:invoke).with(event)
|
20
|
-
ActiveProjection::ProjectionTypeRegistry.process(
|
19
|
+
expect_any_instance_of(TestProjection).to receive(:evaluate).with(headers).and_return(true)
|
20
|
+
expect_any_instance_of(TestProjection).to receive(:invoke).with(event, headers)
|
21
|
+
ActiveProjection::ProjectionTypeRegistry.process(headers, event)
|
21
22
|
end
|
22
23
|
end
|
@@ -12,7 +12,7 @@ describe ActiveProjection::ProjectionType do
|
|
12
12
|
end
|
13
13
|
describe 'instance' do
|
14
14
|
class TestProjection
|
15
|
-
def test_event(event)
|
15
|
+
def test_event(event, headers)
|
16
16
|
end
|
17
17
|
|
18
18
|
def dummy_event(event)
|
@@ -40,7 +40,7 @@ describe ActiveProjection::ProjectionType do
|
|
40
40
|
it 'rejects processing, if projection is broken' do
|
41
41
|
expect(ActiveProjection::ProjectionRepository).to receive(:solid?).and_return(false)
|
42
42
|
expect(ActiveProjection::ProjectionRepository).to_not receive(:get_last_id)
|
43
|
-
@projection.evaluate({
|
43
|
+
@projection.evaluate({id: 1})
|
44
44
|
end
|
45
45
|
|
46
46
|
describe 'with solid projection' do
|
@@ -50,25 +50,25 @@ describe ActiveProjection::ProjectionType do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'processes event with the correct id' do
|
53
|
-
expect(
|
54
|
-
expect(@projection.evaluate({store_id: 6})).to be_true
|
53
|
+
expect(@projection.evaluate({id: 6})).to be_true
|
55
54
|
end
|
56
55
|
|
57
56
|
it 'rejects event with last id smaller event id' do
|
58
|
-
expect(@projection.evaluate({
|
57
|
+
expect(@projection.evaluate({id: 3})).to be_false
|
59
58
|
end
|
60
59
|
|
61
60
|
it 'rejects event with last greater equal event id' do
|
62
61
|
expect(ActiveProjection::ProjectionRepository).to receive(:set_broken).with(0)
|
63
|
-
expect(@projection.evaluate({
|
62
|
+
expect(@projection.evaluate({id: 7})).to be_false
|
64
63
|
end
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
67
|
it 'invokes all handler' do
|
68
|
+
expect(ActiveProjection::ProjectionRepository).to receive(:set_last_id).with(1, 6)
|
69
69
|
expect(@projection).to receive(:test_event)
|
70
|
-
expect(@projection).to_not receive(:
|
71
|
-
@projection.invoke(TestEvent.new)
|
70
|
+
expect(@projection).to_not receive(:dummy)
|
71
|
+
@projection.invoke(TestEvent.new, {id: 6})
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_projection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Reischuck
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_event
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.4.1
|
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.
|
26
|
+
version: 0.4.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|