gpt4 book ai didi

ruby - EM :Connection (em-synchrony) 内的光纤

转载 作者:IT王子 更新时间:2023-10-29 06:01:26 28 4
gpt4 key购买 nike

谁能解释一下为什么 Redis (redis-rb) 同步驱动程序直接在 EM.synchrony block 下工作,但不在 EM:Connection 内工作?

考虑下面的例子

    EM.synchrony do
redis = Redis.new(:path => "/usr/local/var/redis.sock")

id = redis.incr "local:id_counter"
puts id

EM.start_server('0.0.0.0', 9999) do |c|
def c.receive_data(data)
redis = Redis.new(:path => "/usr/local/var/redis.sock")
puts redis.incr "local:id_counter"
end
end

end

我得到了

can't yield from root fiber (FiberError)

receive_data 中使用时。通过阅读 EventMachine 和 em-synchrony 的源代码,我无法弄清楚有什么区别。

谢谢!

PS:显而易见的解决方法是将 Redis 代码包装在 EventMachine::Synchrony.next_tick 中,如 issue #59 中所提示的那样,但考虑到 EM.synchrony,我希望已经将调用封装在 Fiber 中......

PPS:同样适用于使用 EM::Synchrony::Iterator

最佳答案

你在这里做了一些相当棘手的事情。你正在为 start_server 提供一个 block ,它有效地创建一个“匿名”连接类并在该类的 post_init 方法中执行你的 block 。然后在该类中定义一个实例方法。

要记住的是:当 react 器执行回调或类似 receive_data 的方法时,它发生在主线程(和根纤程内),这就是您看到此异常的原因。要解决此问题,您需要将要在 Fiber 中执行的每个回调包装起来(例如,请参阅 Synchrony.add_(periodic)_timer 方法)。

要解决您的实际异常:将 receive_data 的执行包装在 Fiber 中。外部 EM.synchrony {} 不会对 react 器稍后安排的回调执行任何操作。

关于ruby - EM :Connection (em-synchrony) 内的光纤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8794198/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com