2009-08-10 47 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