<commit_before># encoding: utf-8

require 'countdownlatch'

module Adhearsion
  class CallController
    extend ActiveSupport::Autoload

    autoload :Dial
    autoload :Input
    autoload :MenuDSL
    autoload :Output
    autoload :Record
    autoload :Utility

    include Dial
    include Input
    include Output
    include Record
    include Utility

    class_attribute :callbacks

    self.callbacks = {:before_call => [], :after_call => []}

    self.callbacks.keys.each do |name|
      class_eval <<-STOP
        def self.#{name}(method_name = nil, &block)
          callback = if method_name
            lambda { send method_name }
          elsif block
            block
          end
          self.callbacks = self.callbacks.dup.tap { |cb| cb[:#{name}] += Array(callback) }
        end
      STOP
    end

    class << self
      #
      # Execute a call controller, allowing passing control to another controller
      #
      # @param [CallController] controller
      #
      def exec(controller)
        controller.exec
      end

      #
      # Include another module into all CallController classes
      #
      def mixin(mod)
        include mod
      end
    end

    attr_reader :call, :metadata

    # @private
    attr_reader :block

    delegate :[], :[]=, :to => :@metadata
    delegate :variables, :to => :call

    #
    # Create a new instance
    #
    # @param [Call] call the call to operate the controller on
    # @param [Hash] metadata generic key-value storage applicable to the controller
    # @param block to execute on the call
    #
    def initialize(call, metadata = nil, &block)
      @call, @metadata, @block = call, metadata || {}, block
    end

    #
    # Execute the controller, allowing passing control to another controller
    #
    def exec(controller = self)
      new_controller = catch :pass_controller do
        controller.execute!
        nil
      end

      exec new_controller if new_controller
    end

    def bg_exec(completion_callback = nil)
      Thread.new do
        catching_standard_errors do
          exec_with_callback completion_callback
        end
      end
    end

    def exec_with_callback(completion_callback = nil)<commit_msg>[CS] Use Celluloid's thread pool for CallControllers<commit_after># encoding: utf-8

require 'countdownlatch'

module Adhearsion
  class CallController
    extend ActiveSupport::Autoload

    autoload :Dial
    autoload :Input
    autoload :MenuDSL
    autoload :Output
    autoload :Record
    autoload :Utility

    include Dial
    include Input
    include Output
    include Record
    include Utility

    class_attribute :callbacks

    self.callbacks = {:before_call => [], :after_call => []}

    self.callbacks.keys.each do |name|
      class_eval <<-STOP
        def self.#{name}(method_name = nil, &block)
          callback = if method_name
            lambda { send method_name }
          elsif block
            block
          end
          self.callbacks = self.callbacks.dup.tap { |cb| cb[:#{name}] += Array(callback) }
        end
      STOP
    end

    class << self
      #
      # Execute a call controller, allowing passing control to another controller
      #
      # @param [CallController] controller
      #
      def exec(controller)
        controller.exec
      end

      #
      # Include another module into all CallController classes
      #
      def mixin(mod)
        include mod
      end
    end

    attr_reader :call, :metadata

    # @private
    attr_reader :block

    delegate :[], :[]=, :to => :@metadata
    delegate :variables, :to => :call

    #
    # Create a new instance
    #
    # @param [Call] call the call to operate the controller on
    # @param [Hash] metadata generic key-value storage applicable to the controller
    # @param block to execute on the call
    #
    def initialize(call, metadata = nil, &block)
      @call, @metadata, @block = call, metadata || {}, block
    end

    #
    # Execute the controller, allowing passing control to another controller
    #
    def exec(controller = self)
      new_controller = catch :pass_controller do
        controller.execute!
        nil
      end

      exec new_controller if new_controller
    end

    def bg_exec(completion_callback = nil)
      Celluloid.internal_pool.get do
        catching_standard_errors do
          exec_with_callback completion_callback
        end
      end
    end

    def exec_with_callback(completion_callback = nil)
{'fraction_non_alphanumeric': 0.07537912578055307, 'fraction_numerical': 0.00044603033006244426, 'mean_word_length': 2.240606936416185, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7299490', 'n_tokens_mistral': 1271, 'n_tokens_neox': 1234, 'n_words': 389}