我在两个单独的模块中有两个类(我知道现在这不是一个好的用途:/(我有这样的东西:
module MQ
class Client
def self.start(opts = {})
new(opts).start
end
def initialize(queue, message)
@template_message = message
@queue = queue
end
def start
EventMachine.run do
#some code to send message via AMQP
Signal.trap("INT") { connection.close { EventMachine.stop { exit } }}
Signal.trap("TERM") { connection.close {EventMachine.stop { exit(0) } }}
Signal.trap("INFO") { puts "Current active statements: #{statements.keys.inspect}" }
end
end
def stop
EventMachine.stop
end
end
end
接下来我定义了服务器类:
module Esper
class Server
def self.start(opts = {})
new(opts).start
end
def initialize(options)
end
def start
EventMachine.run do
#some code here to receive messages
Signal.trap("INT") { connection.close { EventMachine.stop { exit } }}
Signal.trap("TERM") { connection.close {EventMachine.stop { exit(0) } }}
Signal.trap("INFO") { puts "Current active statements: #{statements.keys.inspect}" }
end
end
def stop
EventMachine.stop
end
end
end
现在我在 rspec 中(这是错误报告(:
context "matched messages" do
before :each do
@template_message = { }
@server = Esper::Server.new
@client = MQ::Client.new("queue_name", @template_message)
end
describe "transfer" do
it "should receive statements" do
Thread.new do
@server.start
end
Thread.new do
@client.start
end
puts "Sleep for 6 seconds"
sleep(6.0)
#some check here
@server.stop
@client.stop # and here it reports when I am trying to access nil class in class client in method stop.
end
end
尝试调用EventMahine.stop
时,它会在方法 stop
中Client
类中报告它说:
undefined method `stop' for nil:NilClass
有人可以指出我错在哪里,如果您有任何建议如何解决它?
所以,这有点难以解释......
您正在尝试将代码包装在模型中,这在代码组织方面是一件好事。
问题是,它在这里不起作用!
EventMachine 使用一种称为 ReactorPattern 的方法,如果您想同时处理大量并发连接,这种方法非常有用。如果我不是完全错了,它使用运行循环将工作分配给它的客户端/反应堆以异步处理它。你可以在这里找到一篇很好的文章:http://www.igvita.com/2008/05/27/ruby-eventmachine-the-speed-demon/
据我所知(不是很多(,只有一个运行循环。 我认为这也反映在您使用事件机器 API 的方式上。这一切都只是类方法,所以全局状态。如果你说EventMachine.stop
一次,下一次调用EventMachine.stop
可能不起作用,它已经停止了。我不知道为什么错误如此奇怪...
当你编写客户端和服务器应用程序时,你通常在不同的进程中执行此操作,每个进程都有自己的 runloop,所以这应该不是问题。 它只是在您的测试中。
我遇到了这个问题,因为我试图合并 esper 和 ampq。表明我通过使用一些不同的方法克服的问题。我仍然不知道为什么它会给出 nil 指针异常。我的解决方案是使用deamon-kit
宝石作为轨道。我用这个工具包创建了一个恶魔。
deamon 是我原始应用程序中的一个单独应用程序。这样,我可以在其单独的文件夹中测试 ampq,当我想测试整个应用程序时,我可以从原始应用程序中运行 deamon,将数据发送到 deamon,然后检查原始应用程序中返回的值。