【问题标题】:Sharing DB connections across objects using class methods in ruby?使用ruby中的类方法跨对象共享数据库连接?
【发布时间】:2009-08-10 08:01:12
【问题描述】:

我正在编写一个 ruby​​ 脚本,用作 Postfix SMTP 访问策略委托。该脚本需要访问 Tokyo Tyrant 数据库。我正在使用 EventMachine 来处理网络连接。 EventMachine 需要一个 EventMachine::Connection 类,该类在创建新连接时由 EventMachine 的处理循环实例化。因此,对于每个连接,都会实例化和销毁一个类。

我正在从 EventMachine::Connection 的 post_init 创建到 Tokyo Tyrant 的连接(即在连接建立后立即),并在连接终止后将其拆除。

我的问题是这是否是连接数据库的正确方法?即每次我需要它时都建立连接并在我完成后将其拆除?在程序关闭期间连接到数据库一次(程序启动时)会不会更好?如果是这样,我应该如何编码?

我的代码是:

require 'rubygems'
require 'eventmachine'
require 'rufus/tokyo/tyrant'

class LineCounter < EM::Connection
  ActionAllow = "action=dunno\n\n"

  def post_init
    puts "Received a new connection"
    @tokyo = Rufus::Tokyo::Tyrant.new('server', 1978)
    @data_received = ""
  end

  def receive_data data
    @data_received << data
    @data_received.lines do |line|
      key = line.split('=')[0]
      value = line.split('=')[1]
      @reverse_client_name = value.strip() if key == 'reverse_client_name'
      @client_address = value.strip() if key == 'client_address'
      @tokyo[@client_address] = @reverse_client_name
    end
    puts @client_address, @reverse_client_name
    send_data ActionAllow
  end

  def unbind
    @tokyo.close
  end
end

EventMachine::run {
  host,port = "127.0.0.1", 9997
  EventMachine::start_server host, port, LineCounter
  puts "Now accepting connections on address #{host}, port #{port}..."
  EventMachine::add_periodic_timer( 10 ) { $stderr.write "*" }
}

关于,

拉吉

【问题讨论】:

    标签: ruby oop tokyo-cabinet eventmachine


    【解决方案1】:

    令人惊讶的是,这个问题没有答案。

    您可能需要一个连接池,您可以在其中获取、使用和返回所需的连接。

    class ConnectionPool
      def initialize(&block)
        @pool = [ ]
        @generator = block
      end
    
      def fetch
        @pool.shift or @generator and @generator.call
      end
    
      def release(handle)
        @pool.push(handle)
      end
    
      def use
        if (block_given?)
          handle = fetch
    
          yield(handle) 
    
          release(handle)
        end
      end
    end
    
    # Declare a pool with an appropriate connection generator
    tokyo_pool = ConnectionPool.new do
      Rufus::Tokyo::Tyrant.new('server', 1978)
    end
    
    # Fetch/Release cycle
    tokyo = tokyo_pool.fetch
    tokyo[@client_address] = @reverse_client_name
    tokyo_pool.release(tokyo)
    
    # Simple block-method for use
    tokyo_pool.use do |tokyo|
      tokyo[@client_address] = @reverse_client_name
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      • 2023-03-03
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多