简体   繁体   English

EM内的光纤:连接(同步)

[英]Fiber within EM:Connection (em-synchrony)

can anybody explain me why the Redis (redis-rb) synchrony driver works directly under EM.synchrony block but doesn't within EM:Connection? 任何人都可以解释为什么Redis(redis-rb)同步驱动程序直接在EM.synchrony块下工作,但不在EM:Connection中?

Considering following example 考虑以下示例

    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

I'm getting 我越来越

can't yield from root fiber (FiberError)

when using within receive_data . receive_data使用时。 From reading source code for both EventMachine and em-synchrony I can't figure out what's the difference. 从阅读EventMachine和em-synchrony的源代码,我无法弄清楚有什么区别。

Thanks! 谢谢!

PS: Obvious workaround is to wrap the redis code within EventMachine::Synchrony.next_tick as hinted at issue #59 , but given the EM.synchrony I would expect to already have the call wrapped within Fiber... PS:明显的解决方法是将redis代码包装在EventMachine :: Synchrony.next_tick中,如问题#59所示 ,但鉴于EM.synchrony,我希望已经将调用包含在Fiber中...

PPS: same applies for using EM::Synchrony::Iterator PPS:同样适用于使用EM::Synchrony::Iterator

You're doing some rather tricky here.. You're providing a block to start_server, which effectively creates an "anonymous" connection class and executes your block within the post_init method of that class. 你在这里做了一些相当棘手的事情。你正在为start_server提供一个块,它有效地创建了一个“匿名”连接类,并在该类的post_init方法中执行你的块。 Then within that class you're defining an instance method. 然后在该类中定义一个实例方法。

The thing to keep in mind is: when the reactor executes a callback, or a method like receive_data, that happens on the main thread (and within root fiber), which is why you're seeing this exception. 要记住的是:当reactor执行回调或者像receive_data这样的方法时,主线程(以及根光纤内)会发生这种情况,这就是你看到这个异常的原因。 To work around this, you need to wrap each callback to be executed within a Fiber (ex, see Synchrony.add_(periodic)_timer methods). 要解决此问题,您需要将每个回调包装在Fiber中执行(例如,请参阅Synchrony.add_(periodic)_timer方法)。

To address your actual exception: wrap the execution of receive_data within a Fiber. 要解决您的实际异常:在光纤中包装receive_data的执行。 The outer EM.synchrony {} won't do anything for callbacks which are scheduled later by the reactor. 外部EM.synchrony {}对于稍后由反应器安排的回调不会做任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM