active_projection 0.3.0 → 0.4.1

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: 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