synapse-core 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/lib/synapse/auditing/audit_logger.rb +8 -4
  2. data/lib/synapse/auditing/correlation_data_provider.rb +4 -1
  3. data/lib/synapse/auditing/data_provider.rb +3 -1
  4. data/lib/synapse/command/command_bus.rb +14 -6
  5. data/lib/synapse/command/command_filter.rb +5 -3
  6. data/lib/synapse/command/command_handler.rb +5 -3
  7. data/lib/synapse/command/dispatch_interceptor.rb +5 -3
  8. data/lib/synapse/command/duplication.rb +3 -3
  9. data/lib/synapse/command/mapping.rb +1 -1
  10. data/lib/synapse/command/rollback_policy.rb +6 -4
  11. data/lib/synapse/domain/simple_stream.rb +2 -0
  12. data/lib/synapse/domain/stream.rb +10 -6
  13. data/lib/synapse/event_bus/clustering/cluster.rb +10 -0
  14. data/lib/synapse/event_bus/clustering/event_bus.rb +55 -0
  15. data/lib/synapse/event_bus/clustering/selector.rb +14 -0
  16. data/lib/synapse/event_bus/event_bus.rb +9 -3
  17. data/lib/synapse/event_bus/event_listener.rb +5 -3
  18. data/lib/synapse/event_bus/mapping.rb +7 -4
  19. data/lib/synapse/event_sourcing/aggregate_factory.rb +6 -2
  20. data/lib/synapse/event_sourcing/conflict_resolver.rb +11 -0
  21. data/lib/synapse/event_sourcing/member.rb +1 -1
  22. data/lib/synapse/event_sourcing/snapshot/policy.rb +3 -1
  23. data/lib/synapse/event_sourcing/snapshot/taker.rb +3 -1
  24. data/lib/synapse/event_store/event_store.rb +12 -6
  25. data/lib/synapse/event_store/in_memory.rb +2 -2
  26. data/lib/synapse/mapping/mapping.rb +8 -2
  27. data/lib/synapse/process_manager/correlation.rb +2 -2
  28. data/lib/synapse/process_manager/correlation_resolver.rb +5 -3
  29. data/lib/synapse/process_manager/mapping/process.rb +4 -5
  30. data/lib/synapse/process_manager/pessimistic_lock_manager.rb +2 -2
  31. data/lib/synapse/process_manager/process.rb +3 -1
  32. data/lib/synapse/process_manager/process_factory.rb +6 -2
  33. data/lib/synapse/process_manager/process_manager.rb +6 -2
  34. data/lib/synapse/process_manager/process_repository.rb +14 -6
  35. data/lib/synapse/repository/lock_manager.rb +17 -3
  36. data/lib/synapse/repository/locking.rb +3 -1
  37. data/lib/synapse/repository/repository.rb +15 -5
  38. data/lib/synapse/serialization/converter.rb +3 -1
  39. data/lib/synapse/serialization/message/serialization_aware.rb +6 -2
  40. data/lib/synapse/serialization/revision_resolver.rb +3 -1
  41. data/lib/synapse/serialization/serializer.rb +9 -3
  42. data/lib/synapse/uow/nesting.rb +18 -6
  43. data/lib/synapse/uow/transaction_manager.rb +11 -5
  44. data/lib/synapse/upcasting/single_upcaster.rb +15 -16
  45. data/lib/synapse/upcasting/upcaster.rb +20 -17
  46. data/lib/synapse/upcasting/upcaster_chain.rb +2 -2
  47. data/lib/synapse/version.rb +1 -1
  48. data/test/auditing/data_provider_test.rb +9 -1
  49. data/test/command/mapping_test.rb +8 -2
  50. data/test/event_bus/mapping_test.rb +7 -2
  51. data/test/event_sourcing/repository_test.rb +1 -1
  52. data/test/repository/locking_test.rb +3 -0
  53. data/test/upcasting/fixtures.rb +3 -8
  54. metadata +5 -2
@@ -10,7 +10,9 @@ module Synapse
10
10
  # @param [Object] return_value
11
11
  # @param [Array<EventMessage>] events
12
12
  # @return [undefined]
13
- def on_success(command, return_value, events); end
13
+ def on_success(command, return_value, events)
14
+ raise NotImplementedError
15
+ end
14
16
 
15
17
  # Called when a command execution results in an exception being raised
16
18
  #
@@ -22,7 +24,9 @@ module Synapse
22
24
  # @param [Exception] exception
23
25
  # @param [Array<EventMessage>] events
24
26
  # @return [undefined]
25
- def on_failure(command, exception, events); end
26
- end
27
- end
27
+ def on_failure(command, exception, events)
28
+ raise NotImplementedError
29
+ end
30
+ end # AuditLogger
31
+ end # Auditing
28
32
  end
@@ -3,9 +3,12 @@ module Synapse
3
3
  # Implementation of an audit provider that attaches a command's identifier to each event
4
4
  # produced as a result of the execution of that command
5
5
  class CorrelationDataProvider < AuditDataProvider
6
+ # Key that will be used by default
7
+ DEFAULT_CORRELATION_KEY = :command_id
8
+
6
9
  # @param [Symbol] correlation_key
7
10
  # @return [undefined]
8
- def initialize(correlation_key)
11
+ def initialize(correlation_key = DEFAULT_CORRELATION_KEY)
9
12
  @correlation_key = correlation_key
10
13
  end
11
14
 
@@ -8,7 +8,9 @@ module Synapse
8
8
  # @abstract
9
9
  # @param [CommandMessage] command
10
10
  # @return [Hash]
11
- def provide_data_for(command); end
11
+ def provide_data_for(command)
12
+ raise NotImplementedError
13
+ end
12
14
  end # AuditDataProvider
13
15
  end # Auditing
14
16
  end
@@ -14,7 +14,9 @@ module Synapse
14
14
  # @abstract
15
15
  # @param [CommandMessage] command
16
16
  # @return [undefined]
17
- def dispatch(command); end
17
+ def dispatch(command)
18
+ raise NotImplementedError
19
+ end
18
20
 
19
21
  # Dispatches the given command to the handler subscribed to its type and notifies the
20
22
  # given callback of the outcome of the dispatch
@@ -23,7 +25,9 @@ module Synapse
23
25
  # @param [CommandMessage] command
24
26
  # @param [CommandCallback] callback
25
27
  # @return [undefined]
26
- def dispatch_with_callback(command, callback); end
28
+ def dispatch_with_callback(command, callback)
29
+ raise NotImplementedError
30
+ end
27
31
 
28
32
  # Subscribes the given handler to the given command type, replacing the currently subscribed
29
33
  # handler, if any.
@@ -31,7 +35,9 @@ module Synapse
31
35
  # @param [Class] command_type
32
36
  # @param [CommandHandler] handler
33
37
  # @return [undefined]
34
- def subscribe(command_type, handler); end
38
+ def subscribe(command_type, handler)
39
+ raise NotImplementedError
40
+ end
35
41
 
36
42
  # Unsubscribes the given handler from the given command type, if it is currently subscribed
37
43
  # to the given command type.
@@ -39,7 +45,9 @@ module Synapse
39
45
  # @param [Class] command_type
40
46
  # @param [CommandHandler] handler
41
47
  # @return [undefined]
42
- def unsubscribe(command_type, handler); end
43
- end
44
- end
48
+ def unsubscribe(command_type, handler)
49
+ raise NotImplementedError
50
+ end
51
+ end # CommandBus
52
+ end # Command
45
53
  end
@@ -11,7 +11,9 @@ module Synapse
11
11
  # @abstract
12
12
  # @param [CommandMessage] command
13
13
  # @return [CommandMessage] The command to dispatch on the bus
14
- def filter(command); end
15
- end
16
- end
14
+ def filter(command)
15
+ raise NotImplementedError
16
+ end
17
+ end # CommandFilter
18
+ end # Command
17
19
  end
@@ -9,7 +9,9 @@ module Synapse
9
9
  # @param [CommandMessage] command
10
10
  # @param [UnitOfWork] current_unit Current unit of work
11
11
  # @return [Object] The result of handling the given command
12
- def handle(command, current_unit); end
13
- end
14
- end
12
+ def handle(command, current_unit)
13
+ raise NotImplementedError
14
+ end
15
+ end # CommandHandler
16
+ end # Command
15
17
  end
@@ -10,7 +10,9 @@ module Synapse
10
10
  # @param [UnitOfWork] unit The current unit of work for this command dispatch
11
11
  # @param [InterceptorChain] chain
12
12
  # @return [Object] The result of the execution of the command
13
- def intercept(command, unit, chain); end
14
- end
15
- end
13
+ def intercept(command, unit, chain)
14
+ raise NotImplementedError
15
+ end
16
+ end # DispatchInterceptor
17
+ end # Command
16
18
  end
@@ -14,7 +14,7 @@ module Synapse
14
14
  @recorder.record command
15
15
  command
16
16
  end
17
- end
17
+ end # DuplicationFilter
18
18
 
19
19
  # Interceptor that removes commands from the duplication recorder if their execution results
20
20
  # in a transient error (like concurrency error) being raised. This way, the same command can
@@ -38,6 +38,6 @@ module Synapse
38
38
  raise
39
39
  end
40
40
  end
41
- end
42
- end
41
+ end # DuplicationCleanupInterceptor
42
+ end # Command
43
43
  end
@@ -44,7 +44,7 @@ module Synapse
44
44
  raise ArgumentError, 'Not capable of handling [%s] commands' % command.payload_type
45
45
  end
46
46
 
47
- mapping.invoke self, command.payload
47
+ mapping.invoke self, command.payload, command, current_unit
48
48
  end
49
49
 
50
50
  # Subscribes this handler to the given command bus for any types that have been mapped
@@ -7,8 +7,10 @@ module Synapse
7
7
  #
8
8
  # @param [Exception] exception
9
9
  # @return [Boolean]
10
- def should_rollback(exception); end
11
- end
10
+ def should_rollback(exception)
11
+ raise NotImplementedError
12
+ end
13
+ end # RollbackPolicy
12
14
 
13
15
  # Implementation of a rollback policy that performs a rollback on any exception
14
16
  class RollbackOnAnyExceptionPolicy < RollbackPolicy
@@ -17,6 +19,6 @@ module Synapse
17
19
  def should_rollback(exception)
18
20
  true
19
21
  end
20
- end
21
- end
22
+ end # RollbackOnAnyExceptionPolicy
23
+ end # Command
22
24
  end
@@ -2,6 +2,8 @@ module Synapse
2
2
  module Domain
3
3
  # Implementation of a domain event stream that holds a stream of events in memory
4
4
  class SimpleDomainEventStream < DomainEventStream
5
+ # @param [EventMessage...] events
6
+ # @return [undefined]
5
7
  def initialize(*events)
6
8
  @events = events.flatten
7
9
  @next_index = 0
@@ -21,20 +21,24 @@ module Synapse
21
21
  # @abstract
22
22
  # @return [Boolean]
23
23
  def end?
24
- true
24
+ raise NotImplementedError
25
25
  end
26
26
 
27
27
  # Returns the next event in the stream and moves the stream's pointer forward
28
28
  #
29
29
  # @abstract
30
30
  # @return [DomainEventMessage]
31
- def next_event; end
31
+ def next_event
32
+ raise NotImplementedError
33
+ end
32
34
 
33
35
  # Returns the next event in the stream without moving the stream's pointer forward
34
36
  #
35
37
  # @abstract
36
38
  # @return [DomainEventMessage]
37
- def peek; end
39
+ def peek
40
+ raise NotImplementedError
41
+ end
38
42
 
39
43
  # Yields the next domain events in the stream until the end of the stream has been reached
40
44
  #
@@ -59,10 +63,10 @@ module Synapse
59
63
 
60
64
  protected
61
65
 
66
+ # @raise [EndOfStreamError] If at the end of the stream
67
+ # @return [undefined]
62
68
  def assert_valid
63
- if end?
64
- raise EndOfStreamError
65
- end
69
+ raise EndOfStreamError if end?
66
70
  end
67
71
  end # DomainEventStream
68
72
  end # Domain
@@ -0,0 +1,10 @@
1
+ module Synapse
2
+ module EventBus
3
+ # Represents a group of event listeners
4
+ #
5
+ # Clusters allow attributes and behaviors to be applied across an entire group of listeners,
6
+ # such as asynchronous processing, event replay, transaction management and distribution.
7
+ class Cluster
8
+ end # Cluster
9
+ end # EventBus
10
+ end
@@ -0,0 +1,55 @@
1
+ module Synapse
2
+ module EventBus
3
+ class ClusteringEventBus
4
+ # @param [ClusterSelector] cluster_selector
5
+ # @return [undefined]
6
+ def initialize(cluster_selector)
7
+ @cluster_selector = cluster_selector
8
+ @clusters = Set.new
9
+ end
10
+
11
+ # @api public
12
+ # @param [EventMessage...] events
13
+ # @return [undefined]
14
+ def publish(*events)
15
+ events.flatten!
16
+
17
+ @clusters.each do |cluster|
18
+ cluster.publish events
19
+ end
20
+ end
21
+
22
+ # @api public
23
+ # @raise [SubscriptionFailedError] If subscription of an event listener failed
24
+ # @param [EventListener] listener
25
+ # @return [undefined]
26
+ def subscribe(listener)
27
+ select_cluster(listener).subscribe(listener)
28
+ end
29
+
30
+ # @api public
31
+ # @param [EventListener] listener
32
+ # @return [undefined]
33
+ def unsubscribe(listener)
34
+ select_cluster(listener).unsubscribe(listener)
35
+ end
36
+
37
+ private
38
+
39
+ # @raise [SubscriptionFailedError] If no suitable cluster for listener
40
+ # @param [EventListener] listener
41
+ # @return [Cluster]
42
+ def select_cluster(listener)
43
+ cluster = @cluster_selector.select_cluster listener
44
+
45
+ unless cluster
46
+ raise SubscriptionFailedError, 'Unable to find suitable cluster for [%s]' % listener.class
47
+ end
48
+
49
+ @clusters.add cluster
50
+
51
+ cluster
52
+ end
53
+ end # ClusteringEventBus
54
+ end # EventBus
55
+ end
@@ -0,0 +1,14 @@
1
+ module Synapse
2
+ module EventBus
3
+ # Represents a mechanism for assigning event listeners to clusters
4
+ # @abstract
5
+ class ClusterSelector
6
+ # Selects and returns a suitable cluster for the given event listener
7
+ #
8
+ # @abstract
9
+ # @param [EventListener] listener
10
+ # @return [Cluster] Returns nil if no suitable cluster
11
+ def select_cluster(listener); end
12
+ end # ClusterSelector
13
+ end # EventBus
14
+ end
@@ -15,7 +15,9 @@ module Synapse
15
15
  # @abstract
16
16
  # @param [EventMessage...] events
17
17
  # @return [undefined]
18
- def publish(*events); end
18
+ def publish(*events)
19
+ raise NotImplementedError
20
+ end
19
21
 
20
22
  # Subscribes the given listener to this event bus
21
23
  #
@@ -23,14 +25,18 @@ module Synapse
23
25
  # @raise [SubscriptionFailedError] If subscription of an event listener failed
24
26
  # @param [EventListener] listener
25
27
  # @return [undefined]
26
- def subscribe(listener); end
28
+ def subscribe(listener)
29
+ raise NotImplementedError
30
+ end
27
31
 
28
32
  # Unsubscribes the given listener from this event bus
29
33
  #
30
34
  # @abstract
31
35
  # @param [EventListener] listener
32
36
  # @return [undefined]
33
- def unsubscribe(listener); end
37
+ def unsubscribe(listener)
38
+ raise NotImplementedError
39
+ end
34
40
  end
35
41
 
36
42
  # Raised when the subscription of an event listener has not succeeded. Generally, this means that
@@ -12,7 +12,9 @@ module Synapse
12
12
  # @abstract
13
13
  # @param [EventMessage] event
14
14
  # @return [undefined]
15
- def notify(event); end
16
- end
17
- end
15
+ def notify(event)
16
+ raise NotImplementedError
17
+ end
18
+ end # EventListener
19
+ end # EventBus
18
20
  end
@@ -10,6 +10,10 @@ module Synapse
10
10
  # # ...
11
11
  # end
12
12
  #
13
+ # map_event UserProfileUpdated do |event, message|
14
+ # # ...
15
+ # end
16
+ #
13
17
  # map_event UserBanned, :to => :on_banned
14
18
  # end
15
19
  module MappingEventListener
@@ -37,10 +41,9 @@ module Synapse
37
41
  # @return [undefined]
38
42
  def notify(event)
39
43
  mapping = event_mapper.mapping_for event.payload_type
40
-
41
- return unless mapping
42
-
43
- mapping.invoke self, event.payload
44
+ if mapping
45
+ mapping.invoke self, event.payload, event
46
+ end
44
47
  end
45
48
  end # MappingEventListener
46
49
  end # EventBus
@@ -16,11 +16,15 @@ module Synapse
16
16
 
17
17
  # @abstract
18
18
  # @return [Class] Type of aggregate being created by this factory
19
- def aggregate_type; end
19
+ def aggregate_type
20
+ raise NotImplementedError
21
+ end
20
22
 
21
23
  # @abstract
22
24
  # @return [String] Type identifier used to store the aggregate in the event store
23
- def type_identifier; end
25
+ def type_identifier
26
+ raise NotImplementedError
27
+ end
24
28
  end # AggregateFactory
25
29
 
26
30
  # Aggregate factory that uses a convention to create instances of aggregates
@@ -10,6 +10,17 @@ module Synapse
10
10
  # an exception. Otherwise, the changes will be applied.
11
11
  #
12
12
  # @abstract
13
+ # @raise [ConflictingModificationException] If any conflicts were detected
14
+ # @param [Array] applied_changes List of changes applied to the aggregate
15
+ # @param [Array] committed_changes List of events that were unexpected by the command handler
16
+ # @return [undefined]
17
+ def resolve_conflicts(applied_changes, committed_changes)
18
+ raise NotImplementedError
19
+ end
20
+ end
21
+
22
+ # Conflict resolver that accepts any unseen changes to an aggregate
23
+ class AcceptAllConflictResolver < ConflictResolver
13
24
  # @raise [ConflictingModificationException] If any conflicts were detected
14
25
  # @param [Array] applied_changes List of changes applied to the aggregate
15
26
  # @param [Array] committed_changes List of events that were unexpected by the command handler
@@ -77,7 +77,7 @@ module Synapse
77
77
  def handle_event(event)
78
78
  mapping = self.event_mapper.mapping_for event.payload_type
79
79
  if mapping
80
- mapping.invoke self, event.payload
80
+ mapping.invoke self, event.payload, event
81
81
  end
82
82
  end
83
83
 
@@ -6,7 +6,9 @@ module Synapse
6
6
  #
7
7
  # @param [AggregateRoot] aggregate
8
8
  # @return [Boolean]
9
- def should_snapshot?(aggregate); end
9
+ def should_snapshot?(aggregate)
10
+ raise NotImplementedError
11
+ end
10
12
  end # SnapshotPolicy
11
13
 
12
14
  # Snapshot policy that takes a snapshot if the number of events committed in an aggregate since
@@ -43,7 +43,9 @@ module Synapse
43
43
  # @param [Object] aggregate_id
44
44
  # @param [DomainEventStream] stream
45
45
  # @return [DomainEventMessage]
46
- def create_snapshot(type_identifier, aggregate_id, stream); end
46
+ def create_snapshot(type_identifier, aggregate_id, stream)
47
+ raise NotImplementedError
48
+ end
47
49
  end # SnapshotTaker
48
50
  end # EventSourcing
49
51
  end
@@ -15,7 +15,9 @@ module Synapse
15
15
  # @param [String] type_identifier Type descriptor of the aggregate to retrieve
16
16
  # @param [Object] aggregate_id
17
17
  # @return [DomainEventStream]
18
- def read_events(type_identifier, aggregate_id); end
18
+ def read_events(type_identifier, aggregate_id)
19
+ raise NotImplementedError
20
+ end
19
21
 
20
22
  # Appends the domain events in the given stream to the event store
21
23
  #
@@ -24,8 +26,10 @@ module Synapse
24
26
  # @param [String] type_identifier Type descriptor of the aggregate to append to
25
27
  # @param [DomainEventStream] stream
26
28
  # @return [undefined]
27
- def append_events(type_identifier, stream); end
28
- end
29
+ def append_events(type_identifier, stream)
30
+ raise NotImplementedError
31
+ end
32
+ end # EventStore
29
33
 
30
34
  # Represents an event store with the capability to manage aggregate snapshots
31
35
  # @abstract
@@ -37,7 +41,9 @@ module Synapse
37
41
  # @param [String] type_identifier Type descriptor of the aggregate to append to
38
42
  # @param [DomainEventMessage] snapshot_event
39
43
  # @return [undefined]
40
- def append_snapshot_event(type_identifier, snapshot_event); end
41
- end
42
- end
44
+ def append_snapshot_event(type_identifier, snapshot_event)
45
+ raise NotImplementedError
46
+ end
47
+ end # SnapshotEventStore
48
+ end # EventStore
43
49
  end
@@ -54,6 +54,6 @@ module Synapse
54
54
 
55
55
  @streams.store aggregate_id, Array.new
56
56
  end
57
- end
58
- end
57
+ end # InMemoryEventStore
58
+ end # EventStore
59
59
  end
@@ -29,9 +29,15 @@ module Synapse
29
29
  # @return [Object] The result of the handler invocation
30
30
  def invoke(target, *args)
31
31
  if @handler.is_a? Symbol
32
- target.send(@handler, *args)
32
+ method = target.method @handler
33
+
34
+ if method.arity > args.size || method.arity == 0
35
+ raise ArgumentError, 'Method signature is invalid'
36
+ end
37
+
38
+ method.call(*args.slice(0, method.arity))
33
39
  else
34
- target.instance_exec(*args, &@handler)
40
+ target.instance_exec *args, &@handler
35
41
  end
36
42
  end
37
43
 
@@ -27,6 +27,6 @@ module Synapse
27
27
  def hash
28
28
  @key.hash ^ @value.hash
29
29
  end
30
- end
31
- end
30
+ end # Correlation
31
+ end # ProcessManager
32
32
  end
@@ -8,7 +8,9 @@ module Synapse
8
8
  # @abstract
9
9
  # @param [EventMessage] event
10
10
  # @return [Correlation]
11
- def resolve(event); end
12
- end
13
- end
11
+ def resolve(event)
12
+ raise NotImplementedError
13
+ end
14
+ end # CorrelationResolver
15
+ end # ProcessManager
14
16
  end
@@ -33,11 +33,10 @@ module Synapse
33
33
  return unless @active
34
34
 
35
35
  mapping = event_mapper.mapping_for event.payload_type
36
-
37
- return unless mapping
38
-
39
- mapping.invoke self, event.payload
40
- finish if mapping.options[:finish]
36
+ if mapping
37
+ mapping.invoke self, event.payload, event
38
+ finish if mapping.options[:finish]
39
+ end
41
40
  end
42
41
  end # MappingProcess
43
42
  end # ProcessManager
@@ -18,6 +18,6 @@ module Synapse
18
18
  def release_lock(process_id)
19
19
  @lock.release_lock process_id
20
20
  end
21
- end
22
- end
21
+ end # PessimisticLockManager
22
+ end # ProcessManager
23
23
  end
@@ -43,7 +43,9 @@ module Synapse
43
43
  # @abstract
44
44
  # @param [EventMessage] event
45
45
  # @return [undefined]
46
- def handle(event); end
46
+ def handle(event)
47
+ raise NotImplementedError
48
+ end
47
49
 
48
50
  protected
49
51
 
@@ -11,14 +11,18 @@ module Synapse
11
11
  # @abstract
12
12
  # @param [Class] process_type
13
13
  # @return [Process]
14
- def create(process_type); end
14
+ def create(process_type)
15
+ raise NotImplementedError
16
+ end
15
17
 
16
18
  # Returns true if processes of the given type can be created by this factory
17
19
  #
18
20
  # @abstract
19
21
  # @param [Class] process_type
20
22
  # @return [Boolean]
21
- def supports(process_type); end
23
+ def supports(process_type)
24
+ raise NotImplementedError
25
+ end
22
26
  end # ProcessFactory
23
27
 
24
28
  # Generic implementation of a process factory that supports any process implementations that
@@ -52,13 +52,17 @@ module Synapse
52
52
  # @param [Class] process_type
53
53
  # @param [EventMessage] event
54
54
  # @return [Symbol]
55
- def creation_policy_for(process_type, event); end
55
+ def creation_policy_for(process_type, event)
56
+ raise NotImplementedError
57
+ end
56
58
 
57
59
  # @abstract
58
60
  # @param [Class] process_type
59
61
  # @param [EventMessage] event
60
62
  # @return [Correlation] Returns nil if no correlation could be extracted
61
- def extract_correlation(process_type, event); end
63
+ def extract_correlation(process_type, event)
64
+ raise NotImplementedError
65
+ end
62
66
 
63
67
  # Determines whether or not a new process should be started, based off of existing processes
64
68
  # and the creation policy for the event and process