3 votes

Partage de connexions DB entre objets à l'aide de méthodes de classe en ruby ?

Je suis en train d'écrire un script ruby script pour être utilisé comme délégation de politique d'accès SMTP de Postfix. Le script doit accéder à une base de données Tokyo Tyrant. J'utilise EventMachine pour prendre en charge les connexions réseau. EventMachine a besoin d'une classe EventMachine::Connection qui est instanciée par la boucle de traitement d'EventMachine chaque fois qu'une nouvelle connexion est créée, donc pour chaque connexion une classe est instanciée et détruite.

Je crée une connexion à Tokyo Tyrant à partir du post_init de EventMachine::Connection (c'est à dire juste après l'établissement de la connexion) et je la supprime après la fin de la connexion.

Ma question est de savoir si c'est la bonne façon de se connecter à la base de données, c'est-à-dire d'établir une connexion chaque fois que j'en ai besoin et de la supprimer une fois que j'ai terminé. Ne serait-il pas préférable de se connecter à la base de données une seule fois (au démarrage du programme) et de la supprimer lors de l'arrêt du programme ? Si c'est le cas, comment dois-je coder cela ?

Mon code est le suivant :

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

avec mes salutations,

raj

1voto

tadman Points 70178

Il est surprenant qu'il n'y ait pas de réponse à cette question.

Ce dont vous avez probablement besoin, c'est d'un pool de connexions dans lequel vous pouvez récupérer, utiliser et renvoyer des connexions au fur et à mesure des besoins.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X