class Dynflow::Rails::Configuration

Attributes

db_pool_size[RW]

the size of db connection pool, if not set, it's calculated from the amount of workers in the pool

disable_active_record_actions[RW]

if true, the ForemanTasks::Concerns::ActionTriggering will make no effect. Useful for testing, where we mignt not want to execute the orchestration tied to the models.

eager_load_paths[RW]
lazy_initialization[RW]
pool_size[RW]

the number of threads in the pool handling the execution

rake_tasks_with_executor[RW]

what rake tasks should run their own executor, not depending on the external one

remote[RW]

set true if the executor runs externally (by default true in procution, othewise false)

remote?[RW]

set true if the executor runs externally (by default true in procution, othewise false)

transaction_adapter[RW]

what transaction adapater should be used, by default, it uses the ActiveRecord based adapter, expecting ActiveRecord is used as ORM in the application

Public Class Methods

new() click to toggle source
# File lib/dynflow/rails/configuration.rb, line 35
def initialize
  self.pool_size                = 5
  self.remote                   = ::Rails.env.production?
  self.transaction_adapter      = ::Dynflow::TransactionAdapters::ActiveRecord.new
  self.eager_load_paths         = []
  self.lazy_initialization      = !::Rails.env.production?
  self.rake_tasks_with_executor = %w(db:migrate db:seed)

  @on_init            = []
  @on_executor_init   = []
  @post_executor_init = []
end

Public Instance Methods

action_logger() click to toggle source

Action related info such as exceptions raised inside the actions' methods To be overridden in the Rails application

# File lib/dynflow/rails/configuration.rb, line 50
def action_logger
  ::Rails.logger
end
calculate_db_pool_size(world) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 106
def calculate_db_pool_size(world)
  return self.db_pool_size if self.db_pool_size

  base_value = 5
  if defined?(::Sidekiq)
    Sidekiq.options[:concurrency] + base_value
  else
    world.config.queues.values.inject(base_value) do |pool_size, pool_options|
      pool_size += pool_options[:pool_size]
    end
  end
end
dynflow_logger() click to toggle source

Dynflow related info about the progress of the execution To be overridden in the Rails application

# File lib/dynflow/rails/configuration.rb, line 56
def dynflow_logger
  ::Rails.logger
end
increase_db_pool_size(world = nil) click to toggle source

To avoid pottential timeouts on db connection pool, make sure we have the pool bigger than the thread pool

# File lib/dynflow/rails/configuration.rb, line 121
def increase_db_pool_size(world = nil)
  if world.nil?
    warn 'Deprecated: using `increase_db_pool_size` outside of Dynflow code is not needed anymore'
    return
  end
  if increase_db_pool_size?
    db_pool_size = calculate_db_pool_size(world)
    ::ActiveRecord::Base.connection_pool.disconnect!

    base_config = ::ActiveRecord::Base.configurations.configs_for(env_name: ::Rails.env)[0]
    config = if base_config.respond_to?(:configuration_hash)
               ::Dynflow::Utils::IndifferentHash.new(base_config.configuration_hash.dup)
             else
               base_config.config.dup
             end
    config['pool'] = db_pool_size if config['pool'].to_i < db_pool_size
    ::ActiveRecord::Base.establish_connection(config)
  end
end
increase_db_pool_size?() click to toggle source
# File lib/dynflow/rails/configuration.rb, line 98
def increase_db_pool_size?
  !::Rails.env.test? && (!remote? || sidekiq_worker?)
end
initialize_world(world_class = ::Dynflow::World) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 78
def initialize_world(world_class = ::Dynflow::World)
  world_class.new(world_config)
end
on_init(executor = true, &block) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 60
def on_init(executor = true, &block)
  destination = executor ? @on_executor_init : @on_init
  destination << block
end
post_executor_init(&block) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 70
def post_executor_init(&block)
  @post_executor_init << block
end
queues() click to toggle source

expose the queues definition to Rails developers

# File lib/dynflow/rails/configuration.rb, line 162
def queues
  world_config.queues
end
rake_task_with_executor?() click to toggle source
# File lib/dynflow/rails/configuration.rb, line 90
def rake_task_with_executor?
  return false unless defined?(::Rake) && ::Rake.respond_to?(:application)

  ::Rake.application.top_level_tasks.any? do |rake_task|
    rake_tasks_with_executor.include?(rake_task)
  end
end
run_on_init_hooks(executor, world) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 65
def run_on_init_hooks(executor, world)
  source = executor ? @on_executor_init : @on_init
  source.each { |init| init.call(world) }
end
run_post_executor_init_hooks(world) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 74
def run_post_executor_init_hooks(world)
  @post_executor_init.each { |init| init.call(world) }
end
sidekiq_worker?() click to toggle source
# File lib/dynflow/rails/configuration.rb, line 102
def sidekiq_worker?
  defined?(::Sidekiq) && ::Sidekiq.options[:queues].any?
end
world_config() click to toggle source

generates the options hash consumable by the Dynflow's world

# File lib/dynflow/rails/configuration.rb, line 142
def world_config
  @world_config ||= ::Dynflow::Config.new.tap do |config|
    config.auto_rescue         = true
    config.logger_adapter      = ::Dynflow::LoggerAdapters::Delegator.new(action_logger, dynflow_logger)
    config.pool_size           = self.pool_size
    config.persistence_adapter = ->(world, _) { initialize_persistence(world) }
    config.transaction_adapter = transaction_adapter
    config.executor            = ->(world, _) { initialize_executor(world) }
    config.connector           = ->(world, _) { initialize_connector(world) }

    # we can't do any operation until the Rails.application.dynflow.world is set
    config.auto_execute        = false
    config.auto_validity_check = false
    if sidekiq_worker? && !Sidekiq.options[:queues].include?("dynflow_orchestrator")
      config.delayed_executor = nil
    end
  end
end

Protected Instance Methods

default_sequel_adapter_options(world) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 168
def default_sequel_adapter_options(world)
  base_config = ::ActiveRecord::Base.configurations.configs_for(env_name: ::Rails.env)[0]
  db_config = if base_config.respond_to?(:configuration_hash)
                ::Dynflow::Utils::IndifferentHash.new(base_config.configuration_hash.dup)
              else
                base_config.config.dup
              end
  db_config['adapter'] = db_config['adapter'].gsub(/_?makara_?/, '')
  db_config['adapter'] = 'postgres' if db_config['adapter'] == 'postgresql'
  db_config['max_connections'] = calculate_db_pool_size(world) if increase_db_pool_size?

  if db_config['adapter'] == 'sqlite3'
    db_config['adapter'] = 'sqlite'
    database = db_config['database']
    unless database == ':memory:'
      # We need to create separate database for sqlite
      # to avoid lock conflicts on the database
      db_config['database'] = "#{File.dirname(database)}/dynflow-#{File.basename(database)}"
    end
  end
  db_config
end
initialize_connector(world) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 203
def initialize_connector(world)
  ::Dynflow::Connectors::Database.new(world)
end
initialize_executor(world) click to toggle source
# File lib/dynflow/rails/configuration.rb, line 191
def initialize_executor(world)
  if remote?
    false
  else
    if defined?(::Sidekiq) && Sidekiq.options[:dynflow_executor]
      ::Dynflow::Executors::Sidekiq::Core
    else
      ::Dynflow::Executors::Parallel::Core
    end
  end
end
initialize_persistence(world, options = {}) click to toggle source

Sequel adapter based on Rails app database.yml configuration

# File lib/dynflow/rails/configuration.rb, line 212
def initialize_persistence(world, options = {})
  persistence_class.new(default_sequel_adapter_options(world).merge(options))
end
persistence_class() click to toggle source
# File lib/dynflow/rails/configuration.rb, line 207
def persistence_class
  ::Dynflow::PersistenceAdapters::Sequel
end