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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d04daf5b2d0f61f27d69a4ee07cd8795314cbd1e
4
- data.tar.gz: 3d000e3af7022bd4dd3061c22256e71fcec01166
3
+ metadata.gz: a6b4b40f0225e31820939e9bfe3148ea9f212e47
4
+ data.tar.gz: 0aa40406e3d1bb73fcf2073290b9154e67ed7e94
5
5
  SHA512:
6
- metadata.gz: f47dc81d8f06d792f877698e998dfe0b97db32661847d3d8a3eeca8ca988a55f265564f4afbf9c133993106e35996531ed3a19300ddcf5caf6729223485e128f
7
- data.tar.gz: 6aeafd1c50a34162ffeda836e4fe4ed16ce92005b7e23dac2db737bc9fadb1303d3ab9a2e29e8a4d4d35a2f5ef7efa2ae10b793a12fe95477a3c87711258d7bc
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, build_event(properties.type, JSON.parse(body))
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
- event_type = method_name.to_s.camelcase.to_sym
17
- raise WrongArgumentsCountError if 1 != method.arity
18
- handlers[event_type] << method.name
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 ProjectionRepository.solid? projection_id || headers[:replayed]# process only replayed events if projection is broken
24
- last_id = ProjectionRepository.get_last_id projection_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 == headers[:store_id] #process incoming event
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 >= headers[:store_id] #incoming event already processed
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 < headers[:store_id] #incoming event is in future, so we are missing some
34
- puts "events are missing"
35
- ProjectionRepository.set_broken projection_id
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
- event_type = event.class.name.split('::').last.to_sym
42
- return unless handlers.has_key? event_type
43
- handlers[event_type].each do |method|
44
- self.send method, event
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 event if projection.evaluate headers
18
+ projection.invoke(event, headers) if projection.evaluate headers
19
19
  end
20
20
  end
21
21
  end
@@ -1,7 +1,7 @@
1
1
  module ActiveProjection
2
2
  # Returns the version of the currently loaded ActiveProjection as a Gem::Version
3
3
  def self.version
4
- Gem::Version.new '0.3.0'
4
+ Gem::Version.new '0.4.1'
5
5
  end
6
6
 
7
7
  module VERSION #:nodoc:
@@ -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('test').and_return(true)
19
- expect_any_instance_of(TestProjection).to receive(:invoke).with(event)
20
- ActiveProjection::ProjectionTypeRegistry.process('test', event)
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({store_id: 1})
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(ActiveProjection::ProjectionRepository).to receive(:set_last_id).with(0, 6)
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({store_id: 3})).to be_false
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({store_id: 7})).to be_false
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(:dummy_event)
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.3.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-10-15 00:00:00.000000000 Z
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.3.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.3.0
26
+ version: 0.4.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement