active_event 0.5.2 → 0.5.3

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +19 -19
  3. data/README.md +9 -9
  4. data/app/models/active_event/event.rb +15 -15
  5. data/app/models/active_event/event_repository.rb +11 -11
  6. data/db/migrate/00_create_domain_events.rb +9 -9
  7. data/lib/active_event/autoload.rb +11 -9
  8. data/lib/active_event/command.rb +35 -39
  9. data/lib/active_event/domain.rb +4 -2
  10. data/lib/active_event/event_server.rb +72 -76
  11. data/lib/active_event/event_source_server.rb +149 -127
  12. data/lib/active_event/event_type.rb +29 -28
  13. data/lib/active_event/replay_server.rb +94 -98
  14. data/lib/active_event/sse.rb +26 -26
  15. data/lib/active_event/support/attr_initializer.rb +76 -74
  16. data/lib/active_event/support/attr_setter.rb +31 -29
  17. data/lib/active_event/support/autoload.rb +46 -44
  18. data/lib/active_event/support/autoloader.rb +41 -38
  19. data/lib/active_event/support/multi_logger.rb +31 -28
  20. data/lib/active_event/validations.rb +68 -68
  21. data/lib/active_event/validations_registry.rb +18 -18
  22. data/lib/active_event/version.rb +1 -1
  23. data/spec/factories/event_factory.rb +9 -9
  24. data/spec/lib/command_spec.rb +14 -14
  25. data/spec/lib/domain_spec.rb +21 -21
  26. data/spec/lib/event_server_spec.rb +29 -29
  27. data/spec/lib/event_type_spec.rb +38 -38
  28. data/spec/lib/replay_server_spec.rb +71 -68
  29. data/spec/lib/support/attr_initializer_spec.rb +55 -55
  30. data/spec/lib/support/attr_setter_spec.rb +61 -61
  31. data/spec/models/event_spec.rb +20 -20
  32. data/spec/spec_helper.rb +1 -1
  33. data/spec/support/active_record.rb +40 -38
  34. metadata +2 -4
  35. data/lib/active_event/support/hash_buffer.rb +0 -24
  36. data/lib/active_event/support/ring_buffer.rb +0 -20
@@ -1,28 +1,29 @@
1
- module ActiveEvent
2
- module EventType
3
- extend ActiveSupport::Concern
4
- include ActiveEvent::Support::AttrInitializer
5
-
6
- def event_type
7
- self.class.name
8
- end
9
-
10
- def self.create_instance(type, data)
11
- Object.const_get(type).new(data)
12
- rescue NameError
13
- require 'ostruct'
14
- OpenStruct.new(data.merge(event_type: type.to_s)).freeze
15
- end
16
-
17
- def add_store_infos(hash)
18
- store_infos.merge! hash
19
- end
20
-
21
- def store_infos
22
- @store_infos ||= {}
23
- end
24
-
25
- private
26
- attr_writer :store_infos
27
- end
28
- end
1
+ module ActiveEvent
2
+ module EventType
3
+ extend ActiveSupport::Concern
4
+ include ActiveEvent::Support::AttrInitializer
5
+
6
+ def event_type
7
+ self.class.name
8
+ end
9
+
10
+ def self.create_instance(type, data)
11
+ Object.const_get(type).new(data)
12
+ rescue NameError
13
+ require 'ostruct'
14
+ OpenStruct.new(data.merge(event_type: type.to_s)).freeze
15
+ end
16
+
17
+ def add_store_infos(hash)
18
+ store_infos.merge! hash
19
+ end
20
+
21
+ def store_infos
22
+ @store_infos ||= {}
23
+ end
24
+
25
+ private
26
+
27
+ attr_writer :store_infos
28
+ end
29
+ end
@@ -1,98 +1,94 @@
1
- require 'singleton'
2
- require 'bunny'
3
- require 'thread'
4
- module ActiveEvent
5
- class ReplayServer
6
- include Singleton
7
-
8
- def self.start(options, id)
9
- instance.options = options
10
- instance.start id
11
- end
12
-
13
- def self.update(id)
14
- instance.queue << id
15
- end
16
-
17
- def start(id)
18
- event_connection.start
19
- @last_id = id
20
- start_republishing
21
- send_done_message
22
- rescue Exception => e
23
- LOGGER.error e.message
24
- LOGGER.error e.backtrace.join("\n")
25
- raise e
26
- end
27
-
28
- def queue
29
- @queue ||= Queue.new
30
- end
31
-
32
- def send_done_message
33
- resend_exchange.publish 'replay_done'
34
- end
35
-
36
- def start_republishing
37
- loop do
38
- @events = EventRepository.after_id(@last_id).to_a
39
- return if @events.empty?
40
- republish_events
41
- end
42
- end
43
-
44
- def republish_events
45
- while has_next_event?
46
- return if new_id?
47
- republish next_event
48
- Thread.pass
49
- end
50
- end
51
-
52
- def new_id?
53
- unless queue.empty?
54
- new_id = queue.pop
55
- if new_id < @last_id
56
- @last_id = new_id
57
- return true
58
- end
59
- end
60
- false
61
- end
62
-
63
- def republish(event)
64
- type = event.event
65
- body = event.data.to_json
66
- resend_exchange.publish body, {type: type, headers: {id: event.id, created_at: event.created_at, replayed: true}}
67
- LOGGER.debug "Republished #{type} with #{body}"
68
- end
69
-
70
- def next_event
71
- e = @events.shift
72
- @last_id = e.id
73
- e
74
- end
75
-
76
- def has_next_event?
77
- @events.length > 0
78
- end
79
-
80
- def event_connection
81
- @event_server ||= Bunny.new URI::Generic.build(options[:event_connection]).to_s
82
- end
83
-
84
- def event_channel
85
- @event_channel ||= event_connection.create_channel
86
- end
87
-
88
- def resend_exchange
89
- @resend_exchange ||= event_channel.fanout "resend_#{options[:event_exchange]}"
90
- end
91
-
92
- def options
93
- @options
94
- end
95
-
96
- attr_writer :options
97
- end
98
- end
1
+ require 'singleton'
2
+ require 'bunny'
3
+ require 'thread'
4
+ module ActiveEvent
5
+ class ReplayServer
6
+ include Singleton
7
+
8
+ def self.start(options, id)
9
+ instance.options = options
10
+ instance.start id
11
+ end
12
+
13
+ def self.update(id)
14
+ instance.queue << id
15
+ end
16
+
17
+ def start(id)
18
+ event_connection.start
19
+ @last_id = id
20
+ start_republishing
21
+ send_done_message
22
+ rescue => e
23
+ LOGGER.error e.message
24
+ LOGGER.error e.backtrace.join("\n")
25
+ raise e
26
+ end
27
+
28
+ def queue
29
+ @queue ||= Queue.new
30
+ end
31
+
32
+ def send_done_message
33
+ resend_exchange.publish 'replay_done'
34
+ end
35
+
36
+ def start_republishing
37
+ loop do
38
+ @events = EventRepository.after_id(@last_id).to_a
39
+ return if @events.empty?
40
+ republish_events
41
+ end
42
+ end
43
+
44
+ def republish_events
45
+ while next_event?
46
+ return if new_id?
47
+ republish next_event
48
+ Thread.pass
49
+ end
50
+ end
51
+
52
+ def new_id?
53
+ unless queue.empty?
54
+ new_id = queue.pop
55
+ if new_id < @last_id
56
+ @last_id = new_id
57
+ return true
58
+ end
59
+ end
60
+ false
61
+ end
62
+
63
+ def republish(event)
64
+ type = event.event
65
+ body = event.data.to_json
66
+ resend_exchange.publish body, type: type, headers: {id: event.id, created_at: event.created_at, replayed: true}
67
+ LOGGER.debug "Republished #{type} with #{body}"
68
+ end
69
+
70
+ def next_event
71
+ e = @events.shift
72
+ @last_id = e.id
73
+ e
74
+ end
75
+
76
+ def next_event?
77
+ @events.length > 0
78
+ end
79
+
80
+ def event_connection
81
+ @event_server ||= Bunny.new URI::Generic.build(options[:event_connection]).to_s
82
+ end
83
+
84
+ def event_channel
85
+ @event_channel ||= event_connection.create_channel
86
+ end
87
+
88
+ def resend_exchange
89
+ @resend_exchange ||= event_channel.fanout "resend_#{options[:event_exchange]}"
90
+ end
91
+
92
+ attr_accessor :options
93
+ end
94
+ end
@@ -1,26 +1,26 @@
1
- require 'json'
2
-
3
- module ActiveEvent
4
- class SSE
5
- def initialize(io)
6
- @io = io
7
- end
8
-
9
- def event(event, data = nil, options = {})
10
- self.data options.merge(event: event, data: JSON.dump(data))
11
- end
12
-
13
- def data(data)
14
- data.each_pair do |key, value|
15
- (value+"\n").split("\n", -1)[0..-2].each do |v|
16
- @io.write "#{key}: #{v}\n"
17
- end
18
- end
19
- @io.write "\n"
20
- end
21
-
22
- def close
23
- @io.close
24
- end
25
- end
26
- end
1
+ require 'json'
2
+
3
+ module ActiveEvent
4
+ class SSE
5
+ def initialize(io)
6
+ @io = io
7
+ end
8
+
9
+ def event(event, data = nil, options = {})
10
+ self.data options.merge(event: event, data: JSON.dump(data))
11
+ end
12
+
13
+ def data(data)
14
+ data.each_pair do |key, value|
15
+ (value + "\n").split("\n", -1)[0..-2].each do |v|
16
+ @io.write "#{key}: #{v}\n"
17
+ end
18
+ end
19
+ @io.write "\n"
20
+ end
21
+
22
+ def close
23
+ @io.close
24
+ end
25
+ end
26
+ end
@@ -1,74 +1,76 @@
1
- module ActiveEvent::Support
2
- class ForbiddenAttributesError < StandardError
3
- end
4
-
5
- class UnknownAttributeError < StandardError
6
- end
7
-
8
- # Allows to initialize attributes with a hash
9
- #
10
- # example:
11
- # class RgbColor
12
- # include ActiveEvent::AttrInitializer
13
- # attributes :r, :g, :b
14
- # end
15
- # green = RgbColor.new r: 250, g: 20, b: 20
16
- module AttrInitializer
17
- extend ActiveSupport::Concern
18
-
19
- def initialize(*args)
20
- hash = (args.last.is_a?(Hash) ? args.pop : {})
21
- super
22
- check_attributes hash
23
- init_attributes hash
24
- end
25
-
26
- def freeze
27
- attributes.freeze
28
- end
29
-
30
- def attributes_except(*args)
31
- attributes.reject { |k,_| args.include? k }
32
- end
33
-
34
- def to_hash
35
- attributes.dup
36
- end
37
-
38
- module ClassMethods
39
- def self.extended(base)
40
- base.attribute_keys = []
41
- end
42
-
43
- attr_accessor :attribute_keys
44
-
45
- def attributes(*args)
46
- self.attribute_keys += args
47
- args.each do |attr|
48
- define_method attr, -> { attributes[attr] }
49
- end
50
- end
51
- end
52
-
53
- protected
54
-
55
- attr_accessor :attributes
56
-
57
- def init_attributes(attributes)
58
- self.attributes = attributes.symbolize_keys
59
- freeze
60
- end
61
-
62
- private
63
-
64
- def check_attributes(attributes)
65
- return if attributes.blank?
66
- if attributes.respond_to?(:permitted?) and not attributes.permitted?
67
- raise ActiveEvent::Support::ForbiddenAttributesError
68
- end
69
- (attributes.keys.map(&:to_sym) - self.class.attribute_keys).each do |k|
70
- raise ActiveEvent::Support::UnknownAttributeError, "unknown attribute: #{k}"
71
- end
72
- end
73
- end
74
- end
1
+ module ActiveEvent
2
+ module Support
3
+ class ForbiddenAttributesError < StandardError
4
+ end
5
+
6
+ class UnknownAttributeError < StandardError
7
+ end
8
+
9
+ # Allows to initialize attributes with a hash
10
+ #
11
+ # example:
12
+ # class RgbColor
13
+ # include ActiveEvent::AttrInitializer
14
+ # attributes :r, :g, :b
15
+ # end
16
+ # green = RgbColor.new r: 250, g: 20, b: 20
17
+ module AttrInitializer
18
+ extend ActiveSupport::Concern
19
+
20
+ def initialize(*args)
21
+ hash = (args.last.is_a?(Hash) ? args.pop : {})
22
+ super
23
+ check_attributes hash
24
+ init_attributes hash
25
+ end
26
+
27
+ def freeze
28
+ attributes.freeze
29
+ end
30
+
31
+ def attributes_except(*args)
32
+ attributes.reject { |k, _| args.include? k }
33
+ end
34
+
35
+ def to_hash
36
+ attributes.dup
37
+ end
38
+
39
+ module ClassMethods
40
+ def self.extended(base)
41
+ base.attribute_keys = []
42
+ end
43
+
44
+ attr_accessor :attribute_keys
45
+
46
+ def attributes(*args)
47
+ self.attribute_keys += args
48
+ args.each do |attr|
49
+ define_method attr, -> { attributes[attr] }
50
+ end
51
+ end
52
+ end
53
+
54
+ protected
55
+
56
+ attr_accessor :attributes
57
+
58
+ def init_attributes(attributes)
59
+ self.attributes = attributes.symbolize_keys
60
+ freeze
61
+ end
62
+
63
+ private
64
+
65
+ def check_attributes(attributes)
66
+ return if attributes.blank?
67
+ if attributes.respond_to?(:permitted?) && !attributes.permitted?
68
+ fail ActiveEvent::Support::ForbiddenAttributesError
69
+ end
70
+ (attributes.keys.map(&:to_sym) - self.class.attribute_keys).each do |k|
71
+ fail ActiveEvent::Support::UnknownAttributeError, "unknown attribute: #{k}"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end