Sha256: c8cf85d8b8f97efe39f9d9fa933d5c4af4cdc487be18be14a4d2b940b8e2edbf

Contents?: true

Size: 1.89 KB

Versions: 1

Compression:

Stored size: 1.89 KB

Contents

module EbisuConnection
  class Slaves
    class Slave
      attr_reader :hostname, :weight

      def initialize(conf, spec)
        case conf
        when String
          @hostname, weight = conf.split(/\s*,\s*/)
          edit_spec = {:host => @hostname}
        when Hash
          conf = symbolize_keys(conf)
          weight = conf.delete(:weight)
          edit_spec = conf
          @hostname = conf[:host]
        else
          raise ArgumentError, "slaves config is invalid"
        end

        @spec = spec.merge(edit_spec)
        @weight = (weight || 1).to_i
      end

      def connection
        @connection ||= ActiveRecord::Base.send("#{@spec["adapter"]}_connection", @spec)
      end

      def disconnect!
        if @connection
          @connection.disconnect!
          @connection = nil
        end
      rescue
      end

      private

      def symbolize_keys(hash)
        symbolize_hash = {}
        hash.each do |k,v|
          symbolize_hash[k.to_sym] = v
        end
        symbolize_hash
      end
    end

    def initialize(slaves_conf, spec)
      weight_list = []
      @slaves = slaves_conf.map do |conf|
        s = Slave.new(conf, spec)
        weight_list << s.weight
        s
      end

      @roulette = []
      gcd = get_gcd(weight_list)
      weight_list.each_with_index do |w, index|
        weight = w / gcd
        @roulette.concat([index] * weight)
      end
    end

    def sample
      @slaves[@roulette.sample]
    end

    def all_disconnect!
      @slaves.each {|s| s.disconnect!}
    end

    private

    def get_gcd(list)
      list = list.sort.uniq
      n = list.shift
      return n if n == 1 || list.empty?

      while !list.empty?
        m = list.shift
        n = gcd_euclid(m, n)
      end
      n
    end

    def gcd_euclid(m, n)
      m, n = n, m if m < n
      while n != 0
        work = m % n
        m = n
        n = work
      end
      m
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
ebisu_connection-0.0.1 lib/ebisu_connection/slaves.rb