假设我有一个 I/O 受限的操作。我确实有回调(或 em 同步)
- EM 如何切换到处理下一个请求保持前一个等待回调?
- 它如何使 Thread.current 变量保持隔离?
- 如何模拟长时间运行的作业?
假设我有一个 I/O 受限的操作。我确实有回调(或 em 同步)
1. EM如何切换到处理下一个请求保持前一个等待回调?
在任何反应器模式中,都有一个执行线程。意思是,一次只能执行一件事。如果反应器正在处理该主线程上的请求,则没有其他请求可以干预(协作调度)。现在,请求可以自愿“放弃”控制权(在 EM 中,我们有EM.next_tick { # block }
),或者通过调度将来的操作:计时器(EM.add_timer { #block }
),或者通过进行另一个 IO 操作!
例如,如果您使用的是 EM-Synchrony,那么当您发出 HTTP 请求(通过 em-http)时,当请求被分派时,光纤将暂停,并在后台为您创建回调。请求完成后,EventMachine 通过内部回调调用回调......并且控制权返回给您的请求。如需更深入的了解: http ://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/
2. 它是如何保持 Thread.current 变量隔离的?
没有魔法。在 Ruby 中,我们有线程局部变量:Thread.current[:foo] = bar
. 同样,Fiber 具有相同的语义,尽管有时让人们措手不及的是使用了相同的机制.. aka Thread.current[:foo] = bar
。
见这里:http ://devblog.avdi.org/2012/02/02/ruby-thread-locals-are-also-fiber-local/
3. 如何模拟长时间运行的作业?
最佳方法:将它们移出反应堆。任何反应器系统都是如此。
a) 创建一个作业队列并将其推送到另一个进程 b) EM 确实提供EM.defer
了,它产生了另一个线程。
尽可能选择(a)而不是(b)..你以后会感谢自己的。