require 'legion/transport/messages/lex_register' module Legion module Extension # New magical extension loader class Loader attr_reader :loaded_extensions def initialize(supervision, _extensions = Legion::Settings[:legion][:extensions]) @loaded_extensions = [] @supervision = supervision end def load_extensions(extensions = Legion::Settings[:legion][:extensions]) extensions.each do |extension, values| Legion::Logging.debug "Skipping #{extension} because it's disabled" unless values[:enabled] next unless values[:enabled] result = load_extension(extension, values) Legion::Logging.info("#{extension} was loaded") if result Legion::Logging.warn("#{extension} failed to load") unless result @loaded_extensions.push(extension) if result end end def load_actor_pool(klass, name, size = 1) @supervision.supervision_group.pool(klass, as: name, size: size) end def register_lex(_extension, lex_methods) lex_methods.each do |namespace| namespace[:class_methods].each do |class_method, _attrs| options = { namespace: {}, method: {} } options[:namespace][:queue] = namespace[:queue] unless namespace[:queue].nil? options[:namespace][:uri] = namespace[:uri] unless namespace[:uri].nil? Legion::Transport::Messages::LexRegister.new(namespace[:namespace], class_method, options).publish end end end def load_extension(extension, values) # rubocop:disable Metrics/AbcSize Legion::Logging.debug "Skipping #{extension} because it's disabled" unless values[:enabled] return false unless values[:enabled] unless gem_load(extension) Legion::Logging.warn "#{extension} failed to load gem path" return false end klass = Kernel.const_get(values[:class]) klass.autobuild register_lex(extension, klass.lex_methods) klass.actors.each do |actor| load_actor_pool(actor[:class], actor[:group_name], 1) end true rescue Sequel::DatabaseConnectionError => exception Legion::Logging.fatal("Legion::Extension #{extension} requires a database connection but failed") Legion::Logging.debug("Extension failed with #{exception.message}") Legion::Logging.debug("Backtrace: #{exception.backtrace}") false rescue NameError => exception Legion::Logging.fatal("Legion::Extension #{extension} failed to load, moving on without it") Legion::Logging.warn("Extension failed with #{exception.message}") Legion::Logging.warn("Backtrace: #{exception.backtrace}") false rescue LoadError => exception Legion::Logging.fatal("Legion::Extension #{extension} failed to load, moving on without it") Legion::Logging.warn("Extension failed with #{exception.message}") Legion::Logging.warn("Backtrace: #{exception.backtrace}") false rescue StandardError => exception Legion::Logging.fatal("Legion::Extension #{extension} failed to load, moving on without it") Legion::Logging.fatal("#{extension} was caught by default") Legion::Logging.warn("Extension failed with #{exception.message}") Legion::Logging.warn("Backtrace: #{exception.backtrace}") false end def gem_load(name) search_name = 'lex-' + name.to_s Legion::Logging.unknown search_name gem_dir = Gem::Specification.find_by_name(search_name).gem_dir Legion::Logging.unknown gem_dir require "#{gem_dir}/lib/legion/extensions/#{name}" true rescue LoadError => ex Legion::Logging.unknown ex.message Legion::Logging.unknown ex.backtrace Legion::Logging.warn "gem path: #{gem_dir}/lib/legion/extensions/#{name}" false end end end end