EventMachine 模块的实例变量

Instance variable with EventMachine module

我正在编写一个应用程序,它使用 EventMachine 来中继来自服务的命令。我想重新使用与服务的连接(而不是为每个新请求重新创建它)。该服务从模块方法启动,并且该模块提供给 EventMachine。如何存储连接以便在事件机器方法中重复使用?

我有什么(简体):

require 'ruby-mpd'
module RB3Jay
  def self.start
    @mpd = MPD.new
    @mpd.connect
    EventMachine.run{ EventMachine.start_server '127.0.0.1', 7331, self }
  end
  def receive_data
    # I need to access @mpd here
  end
end

到目前为止,我唯一的想法是 @@class_variable,但我正在考虑这样的 hack 的唯一原因是我不习惯 EventMachine,也不知道更好的模式。我如何重构我的代码以使 @mpd 实例在请求期间可用?

我相信这对单身人士来说可能是一个机会class。

require 'ruby-mpd'
require 'singleton'

class Mdp
  include Singleton
  attr_reader :mpd

  def start_mpd
    @mpd = MPD.new
    @mpd.connect
  end
end

module RB3Jay
  def self.start
    Mdp.instance.start_mdp
    EventMachine.run{ EventMachine.start_server '127.0.0.1', 7331, self }
  end
end

class Klass
  extend RB3Jay

  def receive_data
    Mdp.instance.mpd
  end
end

此代码段假定 Klass.start 将在创建 Klass 实例之前被调用。

不使用模块方法,您可以继承 EM::Connection 并通过 EventMachine.start_server 传递 mpd,这将把它传递到 class' initialize 方法。

require 'ruby-mpd'
require 'eventmachine'

class RB3Jay < EM::Connection
  def initialize(mpd)
    @mpd = mpd
  end

  def receive_data
    # do stuff with @mpd
  end

  def self.start
    mpd = MPD.new
    mpd.connect

    EventMachine.run do
      EventMachine.start_server("127.0.0.1", 7331, RB3Jay, mpd)
    end
  end
end

RB3Jay.start