realm-core 0.7.1 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -0
  3. data/Rakefile +19 -0
  4. metadata +25 -44
  5. data/lib/realm-core.rb +0 -6
  6. data/lib/realm.rb +0 -22
  7. data/lib/realm/action_handler.rb +0 -84
  8. data/lib/realm/action_handler/result.rb +0 -32
  9. data/lib/realm/builder.rb +0 -93
  10. data/lib/realm/command_handler.rb +0 -23
  11. data/lib/realm/config.rb +0 -57
  12. data/lib/realm/container.rb +0 -68
  13. data/lib/realm/context.rb +0 -37
  14. data/lib/realm/dependency.rb +0 -24
  15. data/lib/realm/dispatcher.rb +0 -74
  16. data/lib/realm/domain_resolver.rb +0 -59
  17. data/lib/realm/error.rb +0 -62
  18. data/lib/realm/event.rb +0 -56
  19. data/lib/realm/event_factory.rb +0 -53
  20. data/lib/realm/event_handler.rb +0 -102
  21. data/lib/realm/event_router.rb +0 -100
  22. data/lib/realm/event_router/gateway.rb +0 -50
  23. data/lib/realm/event_router/internal_loop_gateway.rb +0 -50
  24. data/lib/realm/health_status.rb +0 -46
  25. data/lib/realm/mixins/aggregate_member.rb +0 -25
  26. data/lib/realm/mixins/context_injection.rb +0 -49
  27. data/lib/realm/mixins/controller.rb +0 -53
  28. data/lib/realm/mixins/decorator.rb +0 -33
  29. data/lib/realm/mixins/dependency_injection.rb +0 -52
  30. data/lib/realm/mixins/reactive.rb +0 -32
  31. data/lib/realm/mixins/repository_helper.rb +0 -43
  32. data/lib/realm/multi_worker.rb +0 -30
  33. data/lib/realm/persistence.rb +0 -54
  34. data/lib/realm/persistence/repository_query_handler_adapter.rb +0 -24
  35. data/lib/realm/plugin.rb +0 -20
  36. data/lib/realm/query_handler.rb +0 -8
  37. data/lib/realm/runtime.rb +0 -61
  38. data/lib/realm/runtime/session.rb +0 -33
  39. data/lib/realm/types.rb +0 -9
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/module/introspection'
4
- require 'active_support/core_ext/class/attribute'
5
-
6
- module Realm
7
- module Mixins
8
- module Controller
9
- def self.included(base)
10
- base.class_attribute(:aggregate_name)
11
- base.extend(ClassMethods)
12
- end
13
-
14
- def domain_runtime
15
- @domain_runtime ||= root_domain_runtime.session(domain_context)
16
- end
17
-
18
- def domain_context
19
- {}
20
- end
21
-
22
- def query(identifier, params = {})
23
- domain_runtime.query(get_dispatchable(identifier), params)
24
- end
25
-
26
- def run(identifier, params = {})
27
- domain_runtime.run(get_dispatchable(identifier), params)
28
- end
29
-
30
- def run_as_job(identifier, params = {})
31
- domain_runtime.run_as_job(get_dispatchable(identifier), params)
32
- end
33
-
34
- private
35
-
36
- def get_dispatchable(identifier)
37
- return identifier if identifier.respond_to?(:call)
38
-
39
- [aggregate_name, identifier].compact.join('.')
40
- end
41
-
42
- def root_domain_runtime
43
- self.class.module_parents[-2].realm
44
- end
45
-
46
- module ClassMethods
47
- def with_aggregate(name)
48
- self.aggregate_name = name
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Realm
4
- module Mixins
5
- module Decorator
6
- def self.[](decorated) # rubocop:disable Metrics/MethodLength
7
- Module.new do
8
- def method_missing(...)
9
- _decorated.send(...)
10
- end
11
-
12
- def respond_to_missing?(...)
13
- _decorated.respond_to?(...)
14
- end
15
-
16
- if decorated.to_s[0] == '@'
17
- define_method :initialize do |value|
18
- instance_variable_set(decorated, value)
19
- end
20
-
21
- define_method :_decorated do
22
- instance_variable_get(decorated)
23
- end
24
- else
25
- define_method :_decorated do
26
- send(decorated)
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'realm/dependency'
4
-
5
- module Realm
6
- module Mixins
7
- module DependencyInjection
8
- def self.included(base)
9
- base.extend(ClassMethods)
10
- end
11
-
12
- module ClassMethods
13
- def new(*args, **kwargs, &block)
14
- instance = allocate
15
- deps.each { |d| define_dependency_method(instance, kwargs, d) }
16
- kwargs_without_dependencies = kwargs.reject { |k, _| deps.any? { |d| d.name == k } }
17
- instance.send(:initialize, *args, **kwargs_without_dependencies, &block)
18
- instance
19
- end
20
-
21
- def inject(*dependables, **options)
22
- deps.concat(dependables.map { |d| Dependency.new(d, **options) })
23
- end
24
-
25
- def dependencies
26
- deps.freeze
27
- end
28
-
29
- private
30
-
31
- def deps
32
- @deps ||= []
33
- end
34
-
35
- def define_dependency_method(instance, kwargs, spec)
36
- dependency = kwargs[spec.name]
37
- instance.singleton_class.class_eval do
38
- define_method(spec.name) do
39
- return dependency unless spec.lazy?
40
-
41
- var = "@#{spec.name}"
42
- return instance_variable_get(var) if instance_variable_defined?(var)
43
-
44
- instance_variable_set(var, dependency.respond_to?(:call) ? dependency.call : dependency)
45
- end
46
- protected spec.name
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'realm/error'
4
-
5
- module Realm
6
- module Mixins
7
- module Reactive
8
- protected
9
-
10
- def run(command, params = {})
11
- parts = command.to_s.split('.')
12
- parts.prepend(aggregate) if parts.size == 1 && respond_to?(:aggregate) && aggregate
13
- @runtime.run(parts.join('.'), params.to_h)
14
- end
15
-
16
- def trigger(event_type, attributes = {})
17
- attributes = attributes.to_h
18
- head = { origin: origin(caller_locations(1, 1)) }.merge(attributes.fetch(:head, {}))
19
- final_attrs = attributes.merge(head: head)
20
- final_attrs[:cause] ||= context[:cause] if context.key?(:cause)
21
- @runtime.trigger(event_type, final_attrs)
22
- end
23
-
24
- private
25
-
26
- # Detects the class and method from which this event is triggered
27
- def origin(backtrace)
28
- [self.class.name, backtrace[0].to_s.match(/`([^']+)'/)&.then { |m| "##{m[1]}" }].join
29
- end
30
- end
31
- end
32
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'realm/error'
4
-
5
- module Realm
6
- module Mixins
7
- module RepositoryHelper
8
- class OnlyOneWriteRepo < Realm::Error['You can have only one read/write repo per handler']; end
9
- class InjectingRepoOutsideAggregate < Realm::Error['Cannot auto inject repository outside of an aggregate']; end
10
-
11
- def self.included(base)
12
- base.extend(ClassMethods)
13
- end
14
-
15
- module ClassMethods
16
- protected
17
-
18
- def use_repo(*names, readonly: self < Realm::QueryHandler)
19
- raise OnlyOneWriteRepo if !readonly && (names.size > 1 || defined?(@write_repo_injected))
20
-
21
- names << default_repo_name if names.empty?
22
- names.each { |name| inject_repo(name, readonly) }
23
- @write_repo_injected = true unless readonly
24
- end
25
-
26
- private
27
-
28
- def inject_repo(name, readonly)
29
- repo_name = "#{name}_repo"
30
- return inject(repo_name) unless readonly
31
-
32
- inject(repo_name) { |repo| repo.respond_to?(:readonly) ? repo.readonly : repo }
33
- end
34
-
35
- def default_repo_name
36
- raise InjectingRepoOutsideAggregate unless respond_to?(:aggregate)
37
-
38
- aggregate
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Realm
4
- class MultiWorker
5
- def initialize(workers = [])
6
- @workers = workers
7
- end
8
-
9
- def start(*args)
10
- @workers.each { |w| w.start(*args) }
11
- self
12
- end
13
-
14
- def stop(timeout: 30)
15
- @workers.each { |w| w.stop(timeout: timeout) }
16
- end
17
-
18
- def join
19
- @workers.each(&:join)
20
- end
21
-
22
- def run
23
- %w[INT TERM].each do |signal|
24
- Signal.trap(signal) { stop }
25
- end
26
- start
27
- join
28
- end
29
- end
30
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/string'
4
- require 'realm/error'
5
-
6
- module Realm
7
- class Persistence
8
- class InvalidPersistanceType < Realm::Error; end
9
- class Conflict < Realm::Error; end
10
-
11
- class RelationIsReadOnly < Realm::Error
12
- def initialize(relation, msg: "Cannot write using read-only relation #{relation.class}")
13
- super(msg)
14
- end
15
- end
16
-
17
- class RepositoryIsReadOnly < Realm::Error
18
- def initialize(repo, msg: "Cannot write using read-only repository #{repo.class}")
19
- super(msg)
20
- end
21
- end
22
-
23
- def self.setup(...)
24
- new(...).setup
25
- end
26
-
27
- def initialize(container, repositories)
28
- @container = container
29
- @repositories = repositories
30
- end
31
-
32
- def setup
33
- register_repos
34
- end
35
-
36
- private
37
-
38
- def gateway
39
- @gateway ||= @container.resolve('persistence.gateway')
40
- end
41
-
42
- def register_repos
43
- @repositories.each do |repo_class|
44
- @container.register_factory(repo_class, gateway, as: "#{repo_class.name.demodulize.underscore}_repo")
45
- end
46
- end
47
-
48
- def constantize(*parts)
49
- return parts[0] unless parts[0].is_a?(String)
50
-
51
- parts.join('::').safe_constantize
52
- end
53
- end
54
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'realm/persistence'
4
- require 'realm/error'
5
-
6
- module Realm
7
- class Persistence
8
- class QueryCannotModifyState < Realm::Error; end
9
-
10
- class RepositoryQueryHandlerAdapter
11
- def initialize(repo)
12
- @repo = repo.respond_to?(:readonly) ? repo.readonly : repo
13
- end
14
-
15
- def call(action:, params: {}, **)
16
- raise CannotHandleAction.new(self, action) unless @repo.respond_to?(action)
17
-
18
- @repo.send(action, **params)
19
- rescue RepositoryIsReadOnly
20
- raise QueryCannotModifyState
21
- end
22
- end
23
- end
24
- end
data/lib/realm/plugin.rb DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/class'
4
- require 'active_support/core_ext/string'
5
-
6
- module Realm
7
- class Plugin
8
- class << self
9
- def plugin_name(value = :not_provided)
10
- @plugin_name = value.to_sym unless value == :not_provided
11
- @plugin_name = name.split('::')[-2].underscore.to_sym unless defined?(@plugin_name)
12
- @plugin_name
13
- end
14
-
15
- def setup(_config, _container)
16
- raise NotImplementedError
17
- end
18
- end
19
- end
20
- end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'realm/action_handler'
4
-
5
- module Realm
6
- class QueryHandler < Realm::ActionHandler
7
- end
8
- end
data/lib/realm/runtime.rb DELETED
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/module/delegation'
4
- require 'active_support/core_ext/object/try'
5
- require 'realm/context'
6
- require 'realm/container'
7
- require 'realm/dispatcher'
8
- require 'realm/event_router'
9
- require 'realm/multi_worker'
10
- require 'realm/health_status'
11
- require 'realm/runtime/session'
12
-
13
- module Realm
14
- class Runtime
15
- delegate :query, :run, :run_as_job, :wait_for_jobs, to: :dispatcher
16
- delegate :trigger, :add_listener, to: :event_router
17
- delegate :[], to: :context
18
- attr_reader :container
19
-
20
- def initialize(container = Container.new)
21
- @container = Container[container]
22
- end
23
-
24
- def context
25
- @context ||= Context.new(@container)
26
- end
27
-
28
- def session(context = {})
29
- context.blank? ? self : Session.new(self, context)
30
- end
31
-
32
- def worker(*args)
33
- MultiWorker.new(event_router.try(:workers, *args) || [])
34
- end
35
-
36
- def health
37
- component_statuses = container.each_with_object({}) do |(name, component), map|
38
- map[name] = component.health if component.respond_to?(:health) && !component.is_a?(Runtime)
39
- end
40
- HealthStatus.combine(component_statuses)
41
- end
42
-
43
- # Get all active messaging queues. For maintenance purpose only.
44
- # TODO: Introduce component container and allow to call those method directly on components instead of
45
- # polluting runtime
46
- # Example: engine.realm.components.find(type: Realm::EventRouter::SNSGateway).try(:active_queues)
47
- def active_queues
48
- event_router.try(:active_queues) || []
49
- end
50
-
51
- private
52
-
53
- def dispatcher
54
- @dispatcher ||= container.create(Dispatcher, self)
55
- end
56
-
57
- def event_router
58
- @container[EventRouter]
59
- end
60
- end
61
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'realm/dispatcher'
4
-
5
- module Realm
6
- class Runtime
7
- class Session
8
- delegate :query, :run, :run_as_job, :wait_for_jobs, to: :dispatcher
9
- delegate :add_listener, :trigger, :worker, to: :@runtime
10
- delegate :[], to: :context
11
- attr_reader :context
12
-
13
- def initialize(runtime, context)
14
- @runtime = runtime
15
- @context = runtime.context.merge(context)
16
- end
17
-
18
- def session(context = {})
19
- context.blank? ? self : self.class.new(self, context)
20
- end
21
-
22
- def container
23
- @runtime.container
24
- end
25
-
26
- private
27
-
28
- def dispatcher
29
- @dispatcher ||= container.create(Dispatcher, self)
30
- end
31
- end
32
- end
33
- end