2009-08-10 22 views
3

我正在写一个ruby脚本来用作Postfix SMTP访问策略委托。该脚本需要访问东京暴君数据库。我正在使用EventMachine来处理网络连接。 EventMachine需要一个EventMachine :: Connection类,每当创建一个新的连接时,EventMachine的处理循环就会实例化这个EventMachine :: Connection类。所以对于每个连接,一个类被实例化并销毁。在ruby中使用类方法跨对象共享数据库连接?

我从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 "*" } 
} 

与问候,

拉吉

回答

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