evil_events 0.3.1 → 0.4.0

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 (76) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +10 -1
  4. data/.travis.yml +4 -5
  5. data/CHANGELOG.md +73 -0
  6. data/evil_events.gemspec +6 -3
  7. data/lib/evil_events.rb +3 -0
  8. data/lib/evil_events/core/broadcasting.rb +1 -0
  9. data/lib/evil_events/core/broadcasting/emitter.rb +19 -13
  10. data/lib/evil_events/core/broadcasting/emitter/adapter_proxy.rb +46 -0
  11. data/lib/evil_events/core/config.rb +37 -40
  12. data/lib/evil_events/core/events.rb +34 -3
  13. data/lib/evil_events/core/events/abstract_event.rb +4 -6
  14. data/lib/evil_events/core/events/event_extensions/class_signature.rb +13 -0
  15. data/lib/evil_events/core/events/event_extensions/class_signature/equalizer.rb +0 -2
  16. data/lib/evil_events/core/events/event_extensions/dispatchable.rb +74 -0
  17. data/lib/evil_events/core/events/event_extensions/observable.rb +2 -0
  18. data/lib/evil_events/core/events/event_extensions/serializable.rb +22 -2
  19. data/lib/evil_events/core/events/manager.rb +1 -1
  20. data/lib/evil_events/core/events/manager_registry.rb +16 -0
  21. data/lib/evil_events/core/events/manager_registry/scoped_event_type_matcher.rb +177 -0
  22. data/lib/evil_events/core/events/notifier/sequential.rb +2 -2
  23. data/lib/evil_events/core/events/serializers.rb +13 -2
  24. data/lib/evil_events/core/events/serializers/base.rb +56 -13
  25. data/lib/evil_events/core/events/serializers/base/abstract_engine.rb +47 -0
  26. data/lib/evil_events/core/events/serializers/base/abstract_factory.rb +60 -0
  27. data/lib/evil_events/core/events/serializers/base/data_transformer.rb +57 -0
  28. data/lib/evil_events/core/events/serializers/base/event_serialization_state.rb +80 -0
  29. data/lib/evil_events/core/events/serializers/base/generic_config.rb +7 -0
  30. data/lib/evil_events/core/events/serializers/hash.rb +3 -73
  31. data/lib/evil_events/core/events/serializers/hash/config.rb +11 -0
  32. data/lib/evil_events/core/events/serializers/hash/engines.rb +10 -0
  33. data/lib/evil_events/core/events/serializers/hash/engines/native.rb +60 -0
  34. data/lib/evil_events/core/events/serializers/hash/factory.rb +65 -0
  35. data/lib/evil_events/core/events/serializers/hash/packer.rb +26 -0
  36. data/lib/evil_events/core/events/serializers/hash/unpacker.rb +24 -0
  37. data/lib/evil_events/core/events/serializers/json.rb +3 -59
  38. data/lib/evil_events/core/events/serializers/json/config.rb +11 -0
  39. data/lib/evil_events/core/events/serializers/json/engines.rb +10 -0
  40. data/lib/evil_events/core/events/serializers/json/engines/native.rb +43 -0
  41. data/lib/evil_events/core/events/serializers/json/factory.rb +65 -0
  42. data/lib/evil_events/core/events/serializers/json/packer.rb +26 -0
  43. data/lib/evil_events/core/events/serializers/json/unpacker.rb +31 -0
  44. data/lib/evil_events/core/events/serializers/message_pack.rb +7 -0
  45. data/lib/evil_events/core/events/serializers/message_pack/config.rb +17 -0
  46. data/lib/evil_events/core/events/serializers/message_pack/engines.rb +10 -0
  47. data/lib/evil_events/core/events/serializers/message_pack/engines/mpacker.rb +81 -0
  48. data/lib/evil_events/core/events/serializers/message_pack/factory.rb +65 -0
  49. data/lib/evil_events/core/events/serializers/message_pack/packer.rb +26 -0
  50. data/lib/evil_events/core/events/serializers/message_pack/unpacker.rb +24 -0
  51. data/lib/evil_events/core/events/serializers/xml.rb +7 -0
  52. data/lib/evil_events/core/events/serializers/xml/config.rb +11 -0
  53. data/lib/evil_events/core/events/serializers/xml/engines.rb +10 -0
  54. data/lib/evil_events/core/events/serializers/xml/engines/ox.rb +31 -0
  55. data/lib/evil_events/core/events/serializers/xml/factory.rb +65 -0
  56. data/lib/evil_events/core/events/serializers/xml/packer.rb +26 -0
  57. data/lib/evil_events/core/events/serializers/xml/unpacker.rb +24 -0
  58. data/lib/evil_events/core/events/subscriber/mixin.rb +26 -3
  59. data/lib/evil_events/core/system.rb +28 -2
  60. data/lib/evil_events/core/system/broadcaster.rb +11 -5
  61. data/lib/evil_events/core/system/event_builder.rb +98 -34
  62. data/lib/evil_events/core/system/event_manager.rb +12 -0
  63. data/lib/evil_events/core/system/mock.rb +30 -2
  64. data/lib/evil_events/emitter.rb +4 -2
  65. data/lib/evil_events/error.rb +21 -1
  66. data/lib/evil_events/serializer.rb +14 -0
  67. data/lib/evil_events/shared.rb +1 -3
  68. data/lib/evil_events/shared/any_config.rb +60 -0
  69. data/lib/evil_events/version.rb +2 -2
  70. metadata +85 -14
  71. data/.jrubyrc +0 -1
  72. data/lib/evil_events/core/events/event_extensions/adapter_customizable.rb +0 -49
  73. data/lib/evil_events/core/events/event_extensions/emittable.rb +0 -41
  74. data/lib/evil_events/shared/combined_context.rb +0 -124
  75. data/lib/evil_events/shared/combined_context/mixin.rb +0 -43
  76. data/lib/evil_events/shared/configurable.rb +0 -7
@@ -14,19 +14,17 @@ module EvilEvents::Core::Events
14
14
  # @since 0.1.0
15
15
  include EventExtensions::Observable
16
16
  # @since 0.1.0
17
- include EventExtensions::AdapterCustomizable
18
- # @since 0.1.0
19
17
  include EventExtensions::Serializable
20
18
  # @since 0.1.0
21
- include EventExtensions::Emittable
22
- # @since 0.1.0
23
19
  include EventExtensions::MetadataExtendable
24
20
  # @sicne 0.2.0
25
21
  include EventExtensions::ClassSignature
26
22
  # @since 0.3.0
27
23
  include EventExtensions::Hookable
28
- # @since 0.1.0
29
- extend EvilEvents::Shared::CombinedContext::Mixin
24
+ # @since 0.4.0
25
+ include EventExtensions::Dispatchable
26
+ # @since 0.4.0
27
+ extend Symbiont::Context
30
28
 
31
29
  # @return [String]
32
30
  #
@@ -17,6 +17,19 @@ module EvilEvents::Core::Events::EventExtensions
17
17
  end
18
18
  end
19
19
 
20
+ # @param another_event [Object]
21
+ # @return [Boolean]
22
+ #
23
+ # @since 0.4.0
24
+ def similar_to?(another_event)
25
+ id == another_event.id &&
26
+ type == another_event.type &&
27
+ payload == another_event.payload &&
28
+ metadata == another_event.metadata
29
+ rescue NoMethodError
30
+ false
31
+ end
32
+
20
33
  # @since 0.2.0
21
34
  module ClassMethods
22
35
  # @return [Signature]
@@ -69,14 +69,12 @@ module EvilEvents::Core::Events::EventExtensions::ClassSignature
69
69
  #
70
70
  # @since 0.2.0
71
71
  def similar_signatures?
72
- # rubocop:disable Layout/MultilineOperationIndentation
73
72
  equal_type_alias? &&
74
73
  equal_class? &&
75
74
  equal_payload? &&
76
75
  equal_metadata? &&
77
76
  equal_delegator? &&
78
77
  equal_adapter?
79
- # rubocop:enable Layout/MultilineOperationIndentation
80
78
  end
81
79
  end
82
80
  end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions
4
+ # @api private
5
+ # @since 0.4.0
6
+ module Dispatchable
7
+ class << self
8
+ # @param base_class [Class{AbstractEvent}]
9
+ #
10
+ # @api private
11
+ # @since 0.4.0
12
+ def included(base_class)
13
+ base_class.extend(ClassMethods)
14
+ end
15
+ end
16
+
17
+ # @return [EvilEvents::Core::Broadcasting::Dispatcher::Mixin]
18
+ #
19
+ # @since 0.4.0
20
+ def adapter
21
+ self.class.adapter
22
+ end
23
+
24
+ # @return [EvilEvents::Core::Broadcasting::Dispatcher::Mixin]
25
+ #
26
+ # @since 0.4.0
27
+ def adapter_name
28
+ self.class.adapter_name
29
+ end
30
+
31
+ # @option adapter [Symbol,NilClass]
32
+ # @return [void]
33
+ #
34
+ # @api public
35
+ # @since 0.4.0
36
+ def emit!(adapter: nil)
37
+ EvilEvents::Core::Bootstrap[:event_system].emit(self, adapter: adapter)
38
+ end
39
+
40
+ # @since 0.4.0
41
+ module ClassMethods
42
+ # @param identifier [Symbol,String,NilClass]
43
+ # @return [EvilEvents::Core::Broadcasting::Dispatcher::Dispatchable]
44
+ #
45
+ # @since 0.4.0
46
+ def adapter(identifier = nil)
47
+ @adapter_identifier = identifier if identifier
48
+ EvilEvents::Core::Bootstrap[:event_system].resolve_adapter(adapter_name)
49
+ end
50
+
51
+ # @return [Symbol, String]
52
+ #
53
+ # @since 0.4.0
54
+ def adapter_name
55
+ @adapter_identifier || EvilEvents::Core::Bootstrap[:config].adapter.default
56
+ end
57
+
58
+ # @option id [NilClass,Object]
59
+ # @option payload [Hash]
60
+ # @option metadata [Hash]
61
+ # @option adapter [Symbol,NilClass]
62
+ # @return [void]
63
+ #
64
+ # @see EvilEvents::Core::Events::AbstractEvent#initialize
65
+ # @see EvilEvents::Core::Events::EventExtensions::Emittable#emit!
66
+ #
67
+ # @api public
68
+ # @since 0.4.0
69
+ def emit!(id: nil, payload: {}, metadata: {}, adapter: nil)
70
+ new(id: id, payload: payload, metadata: metadata).emit!(adapter: adapter)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -19,6 +19,7 @@ module EvilEvents::Core::Events::EventExtensions
19
19
  def observers
20
20
  self.class.observers
21
21
  end
22
+ alias_method :subscribers, :observers
22
23
 
23
24
  # @since 0.1.0
24
25
  module ClassMethods
@@ -44,6 +45,7 @@ module EvilEvents::Core::Events::EventExtensions
44
45
  def observers
45
46
  EvilEvents::Core::Bootstrap[:event_system].observers(self)
46
47
  end
48
+ alias_method :subscribers, :observers
47
49
  end
48
50
  end
49
51
  end
@@ -6,18 +6,38 @@ module EvilEvents::Core::Events::EventExtensions
6
6
  module Serializable
7
7
  # @return [Hash]
8
8
  #
9
+ # @api private
9
10
  # @since 0.1.0
10
11
  def serialize_to_hash
11
- EvilEvents::Core::Events::Serializers[:hash].serialize(self)
12
+ EvilEvents::Core::Bootstrap[:event_system].serialize_to_hash(self)
12
13
  end
13
14
  alias_method :dump_to_hash, :serialize_to_hash
14
15
 
15
16
  # @return [String]
16
17
  #
18
+ # @api private
17
19
  # @since 0.1.0
18
20
  def serialize_to_json
19
- EvilEvents::Core::Events::Serializers[:json].serialize(self)
21
+ EvilEvents::Core::Bootstrap[:event_system].serialize_to_json(self)
20
22
  end
21
23
  alias_method :dump_to_json, :serialize_to_json
24
+
25
+ # @return [String]
26
+ #
27
+ # @api private
28
+ # @since 0.4.0
29
+ def serialize_to_xml
30
+ EvilEvents::Core::Bootstrap[:event_system].serialize_to_xml(self)
31
+ end
32
+ alias_method :dump_to_xml, :serialize_to_xml
33
+
34
+ # @return [String]
35
+ #
36
+ # @api private
37
+ # @since 0.4.0
38
+ def serialize_to_msgpack
39
+ EvilEvents::Core::Bootstrap[:event_system].serialize_to_msgpack(self)
40
+ end
41
+ alias_method :dump_to_msgpack, :serialize_to_msgpack
22
42
  end
23
43
  end
@@ -39,7 +39,7 @@ module EvilEvents::Core::Events
39
39
 
40
40
  # @param event [EvilEvents::Core::Events::AbstractEvent]
41
41
  # @raise [EvilEvents::InconsistentEventClassError]
42
- # @raise [EvilEvents::FailedNotifiedSubscribersError]
42
+ # @raise [EvilEvents::FailingSubscribersError]
43
43
  #
44
44
  # @return void
45
45
  #
@@ -43,6 +43,22 @@ module EvilEvents::Core::Events
43
43
  manager_of_event(event_class)
44
44
  end
45
45
 
46
+ # @param scoped_event_type [String]
47
+ # @raise [EvilEvents::NonManagedEventClassError]
48
+ # @return [Array<EvilEvents::Core::Events::Manager>]
49
+ #
50
+ # @api private
51
+ # @since 0.4.0
52
+ def managers_of_scoped_event_type(scoped_event_type)
53
+ scope_matcher = ScopedEventTypeMatcher.new(scoped_event_type)
54
+
55
+ event_classes = managed_events.select do |managed_event|
56
+ scope_matcher.match?(managed_event.type)
57
+ end
58
+
59
+ event_classes.map { |event_class| manager_of_event(event_class) }
60
+ end
61
+
46
62
  # @param event_pattern [Regexp]
47
63
  # @return [Array<EvilEvents::Core::Events::Manager>]
48
64
  #
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EvilEvents::Core::Events::ManagerRegistry
4
+ # @api private
5
+ # @since 0.4.0
6
+ class ScopedEventTypeMatcher
7
+ # @return [String]
8
+ #
9
+ # @api private
10
+ # @since 0.4.0
11
+ EVENT_SCOPE_SPLITTER = '.'
12
+
13
+ # @return [String]
14
+ #
15
+ # @api private
16
+ # @since 0.4.0
17
+ MATCHER_SCOPE_SPLITTER = '\.'
18
+
19
+ # @return [String]
20
+ #
21
+ # @api private
22
+ # @since 0.4.0
23
+ GENERIC_PART_PATTERN = '*'
24
+
25
+ # @return [String]
26
+ #
27
+ # @api private
28
+ # @since 0.4.0
29
+ GENERIC_REGEXP_PATTERN = '[^\.]+\.'
30
+
31
+ # @return [String]
32
+ #
33
+ # @api private
34
+ # @since 0.4.0
35
+ INFINITE_PART_PATTERN = '#'
36
+
37
+ # @return [String]
38
+ #
39
+ # @api private
40
+ # @since 0.4.0
41
+ INFINITE_REGEXP_PATTERN = '\.*.*'
42
+
43
+ # @param scope_pattern [String]
44
+ # @raise [EvilEvents::ArgimentError]
45
+ #
46
+ # @api private
47
+ # @since 0.4.0
48
+ def initialize(scope_pattern)
49
+ raise EvilEvents::ArgumentError unless scope_pattern.is_a?(String)
50
+
51
+ @scope_pattern = scope_pattern
52
+ @scope_pattern_size = count_scope_pattern_size(scope_pattern)
53
+ @pattern_matcher = build_pattern_matcher(scope_pattern)
54
+ end
55
+
56
+ # @param event_type [String]
57
+ # @return [Boolean]
58
+ #
59
+ # @api private
60
+ # @since 0.4.0
61
+ def match?(event_type)
62
+ return false unless comparable_event_scopes?(event_type)
63
+ !!pattern_matcher.match(event_type)
64
+ end
65
+
66
+ private
67
+
68
+ # @return [Regexp]
69
+ #
70
+ # @api private
71
+ # @since 0.4.0
72
+ attr_reader :pattern_matcher
73
+
74
+ # @return [String]
75
+ #
76
+ # @api private
77
+ # @since 0.4.0
78
+ attr_reader :scope_pattern
79
+
80
+ # @return [Integer,Float::INFINITY]
81
+ #
82
+ # @api private
83
+ # @since 0.4.0
84
+ attr_reader :scope_pattern_size
85
+
86
+ # @param scope_pattern [String]
87
+ # @return [Integer,Float::INFINITY]
88
+ #
89
+ # @api private
90
+ # @since 0.4.0
91
+ def count_scope_pattern_size(scope_pattern)
92
+ return Float::INFINITY if scope_pattern == INFINITE_PART_PATTERN
93
+ return Float::INFINITY if scope_pattern.include?('.#')
94
+ return Float::INFINITY if scope_pattern.include?('#.')
95
+ return Float::INFINITY if scope_pattern.include?('.#.')
96
+
97
+ scope_pattern.split(EVENT_SCOPE_SPLITTER).size
98
+ end
99
+
100
+ # @param event_type [String]
101
+ # @return [Integer]
102
+ #
103
+ # @api private
104
+ # @since 0.4.0
105
+ def count_event_type_size(event_type)
106
+ event_type.split(EVENT_SCOPE_SPLITTER).size
107
+ end
108
+
109
+ # @param event_type [String]
110
+ # @return [Boolean]
111
+ #
112
+ # @api private
113
+ # @since 0.4.0
114
+ def comparable_event_scopes?(event_type)
115
+ # NOTE: Integer#finite?, Integer#infinite?, Float#finite?, Float#nfinite?
116
+ # Cant be used (backward compatability with old ruby versions)
117
+ return true if scope_pattern_size == Float::INFINITY
118
+ scope_pattern_size == count_event_type_size(event_type)
119
+ end
120
+
121
+ # @param pattern [String,NilClass]
122
+ # @return [Boolean]
123
+ #
124
+ # @api private
125
+ # @since 0.4.0
126
+ def non_generic_pattern?(pattern = nil)
127
+ return false unless pattern
128
+ pattern != GENERIC_REGEXP_PATTERN && pattern != INFINITE_REGEXP_PATTERN
129
+ end
130
+
131
+ # "\.test\.created\.today\." => "test\.created\.today"
132
+ #
133
+ # @param regexp_string [String]
134
+ # @option left [Boolean]
135
+ # @option right [Boolean]
136
+ # @return [String]
137
+ #
138
+ # @api private
139
+ # @since 0.4.0
140
+ def strip_regexp_string(regexp_string, left: false, right: false)
141
+ pattern = regexp_string
142
+ pattern = pattern[2..-1] if left && pattern[0..1] == MATCHER_SCOPE_SPLITTER
143
+ pattern = pattern[0..-3] if right && pattern[-2..-1] == MATCHER_SCOPE_SPLITTER
144
+ pattern
145
+ end
146
+
147
+ # @param scope_pattern [String]
148
+ # @return [Regexp]
149
+ #
150
+ # @api private
151
+ # @since 0.4.0
152
+ # rubocop:disable Metrics/AbcSize
153
+ def build_pattern_matcher(scope_pattern)
154
+ routing_parts = scope_pattern.split(EVENT_SCOPE_SPLITTER)
155
+
156
+ regexp_string = routing_parts.each_with_object([]) do |routing_part, regexp_parts|
157
+ case routing_part
158
+ when GENERIC_PART_PATTERN
159
+ regexp_parts << GENERIC_REGEXP_PATTERN
160
+ when INFINITE_PART_PATTERN
161
+ if non_generic_pattern?(regexp_parts.last)
162
+ regexp_parts[-1] = strip_regexp_string(regexp_parts.last, right: true)
163
+ end
164
+
165
+ regexp_parts << INFINITE_REGEXP_PATTERN
166
+ else
167
+ regexp_parts << (Regexp.escape(routing_part) + MATCHER_SCOPE_SPLITTER)
168
+ end
169
+ end.join
170
+
171
+ regexp_string = strip_regexp_string(regexp_string, left: true, right: true)
172
+
173
+ Regexp.new('\A' + regexp_string + '\z')
174
+ end
175
+ # rubocop:enable Metrics/AbcSize
176
+ end
177
+ end
@@ -9,13 +9,13 @@ module EvilEvents::Core::Events::Notifier
9
9
 
10
10
  # @param manager [EvilEvents::Core::Events::Manager]
11
11
  # @param event [EvilEvents::Core::Events::AbstractEvent]
12
- # @raise [EvilEvents::FailedNotifiedSubscribersError]
12
+ # @raise [EvilEvents::FailingSubscribersError]
13
13
  # @return void
14
14
  #
15
15
  # @api private
16
16
  # @since 0.3.0
17
17
  def notify(manager, event)
18
- errors_stack = EvilEvents::FailedNotifiedSubscribersError.new
18
+ errors_stack = EvilEvents::FailingSubscribersError.new
19
19
 
20
20
  event.__call_before_hooks__
21
21
 
@@ -4,7 +4,18 @@ module EvilEvents::Core::Events
4
4
  # @api private
5
5
  # @since 0.1.0
6
6
  class Serializers
7
- # @since 0.1.0
8
- extend EvilEvents::Shared::DependencyContainer::Mixin
7
+ # @since 0.4.0
8
+ include EvilEvents::Shared::DependencyContainer::Mixin
9
+
10
+ # @return void
11
+ #
12
+ # @api private
13
+ # @since 0.4.0
14
+ def register_core_serializers!
15
+ register(:json, memoize: true) { JSON::Factory.new.create! }
16
+ register(:hash, memoize: true) { Hash::Factory.new.create! }
17
+ register(:msgpack, memoize: true) { MessagePack::Factory.new.create! }
18
+ register(:xml, memoize: true) { XML::Factory.new.create! }
19
+ end
9
20
  end
10
21
  end
@@ -2,21 +2,64 @@
2
2
 
3
3
  class EvilEvents::Core::Events::Serializers
4
4
  # @api private
5
- # @since 0.1.1
6
- module Base
7
- # @option type [String]
8
- # @option id [String, Object]
9
- # @option payload [Hash]
10
- # @option metadata [Hash]
11
- # @return [EvilEvents::Core::Events::AbstractEvent]
5
+ # @since 0.4.0
6
+ class Base
7
+ # @param engine [Engines::Abstract]
8
+ # @param config [GenericConfig]
9
+ # @param packer [DataTransformer]
10
+ # @param unpacker [DataTransformer]
11
+ #
12
+ # @api private
13
+ # @since 0.4.0
14
+ def initialize(engine, config, packer, unpacker)
15
+ @engine = engine
16
+ @config = config
17
+ @packer = packer
18
+ @unpacker = unpacker
19
+ end
20
+
21
+ # @param event [EvilEvents::Core::Events::AbstractEvent]
22
+ # @return [Object]
12
23
  #
13
- # @since 0.1.1
14
- def restore_event_instance(type:, id:, payload:, metadata:)
15
- event_class = EvilEvents::Core::Bootstrap[:event_system].resolve_event_class(type)
24
+ # @api private
25
+ # @since 0.4.0
26
+ def serialize(event)
27
+ packer.call(event)
28
+ end
16
29
 
17
- EvilEvents::Core::Events::EventFactory.restore_instance(
18
- event_class, id: id, payload: payload, metadata: metadata
19
- )
30
+ # @param data [Object]
31
+ # @return [EvilEvents::Core::Events::AbstractEvent]
32
+ #
33
+ # @api private
34
+ # @since 0.4.0
35
+ def deserialize(data)
36
+ unpacker.call(data)
20
37
  end
38
+
39
+ private
40
+
41
+ # @return [DataTransformer]
42
+ #
43
+ # @api private
44
+ # @since 0.4.0
45
+ attr_reader :packer
46
+
47
+ # @return [DataTransformer]
48
+ #
49
+ # @api private
50
+ # @since 0.4.0
51
+ attr_reader :unpacker
52
+
53
+ # @return [Engines::Abstract]
54
+ #
55
+ # @api private
56
+ # @since 0.4.0
57
+ attr_reader :engine
58
+
59
+ # @return [GenericConfig]
60
+ #
61
+ # @api private
62
+ # @since 0.4.0
63
+ attr_reader :config
21
64
  end
22
65
  end