我正在尝试等待异步代码,这是片段:
condition = Celluloid::Condition.new
Rails.logger.debug "Sending RPC request to #{subject}"
NATS.start uri: ENV['NATS_SERVER'] do
Rails.logger.debug "Connected to #{ENV['NATS_SERVER']}"
sid = NATS.request(subject,msg) do |response|
Rails.logger.debug "Assigning response"
condition.signal response
NATS.stop
end
NATS.timeout(sid, 1) do
NATS.stop
condition.signal ASYNC_ERROR
raise "One second timeout waiting for a NATS RPC reply from #{subject}"
end
end
result = condition.wait
if result = ASYNC_ERROR
raise "Error in RPC call"
else
return result
end
我收到异常Celluloid::Condition signaled spuriously
,但没有额外的信息,我不明白为什么会造成这种情况,https://github.com/celluloid/celluloid/wiki/Conditions不提供更多信息。
为什么会造成这种情况,我该如何解决?
答案 0 :(得分:1)
使用条件来回答你的问题,就像你陈述的问题一样。
class Nats
include Celluloid
def initialize
@condition = Celluloid::Condition.new
end
def start
Rails.logger.debug "Sending RPC request to #{subject}"
NATS.start uri: ENV['NATS_SERVER'] do
Rails.logger.debug "Connected to #{ENV['NATS_SERVER']}"
sid = NATS.request(subject,msg) do |response|
Rails.logger.debug "Assigning response"
@condition.signal response
NATS.stop
end
NATS.timeout(sid, 1) do
NATS.stop
@condition.signal ASYNC_ERROR
raise "One second timeout waiting for a NATS RPC reply from #{subject}"
end
end
end
def value
@condition.wait
end
end
nats = Nats.new
nats.async.start
result = nats.value
if result = ASYNC_ERROR
raise "Error in RPC call"
else
return result
end
这种情况测试得更少,但如果您不像我的其他答案那样使用Future
,则应该向您展示基本方法。
答案 1 :(得分:0)
您的情况不是在演员的背景下运作。请注意,在示例中,使用了actor。可以避免使用actor上下文,但这是非常不同的,并且是你收到的错误的根源。
如果你不想在演员中实现这个,就像在例子中一样,这是一种你可以在没有演员的情况下实现的方法:
Celluloid::Future
(即使嵌套async
次调用)nats = Celluloid::Future.new {
blocker = Queue.new
Rails.logger.debug "Sending RPC request to #{subject}"
NATS.start uri: ENV['NATS_SERVER'] do
Rails.logger.debug "Connected to #{ENV['NATS_SERVER']}"
sid = NATS.request(subject,msg) do |response|
Rails.logger.debug "Assigning response"
NATS.stop
blocker << response
end
NATS.timeout(sid, 1) do
NATS.stop
blocker << nil
#de "One second timeout waiting for a NATS RPC reply from #{subject}"
end
end
blocker.pop || raise ASYNC_ERROR
}
begin
result = nats.value
rescue ASYNC_ERROR
raise "Error in RPC call"
rescue => ex
#de Other exception
else
return result
end
以上是用于实现async
响应收集的一个简单示例,具有异常处理功能。这是许多可能方法中的一个例子。