Goliath或EventMachine如何切换上下文?

Ser*_*vyi 4 asynchronous eventmachine goliath

假设我有一个I/O限制的操作.我有回调(或同步)

  1. EM如何切换到proccess下一个请求,让前一个请求等待回调?
  2. 它如何保持Thread.current变量被隔离?
  3. 我怎样才能模拟长时间工作?

igr*_*rik 6

1. EM如何切换到proccess下一个请求保持前一个等待回调?

在任何反应器模式中,都有一个执行线程.意思是,一次只能执行一件事.如果反应器正在处理该主线程上的请求,则没有其他请求可以干预(协作调度).现在,请求可以自动"放弃"控制(在EM中,我们有EM.next_tick { # block }),或者通过调度未来的操作:timer(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.类似地,光纤具有相同的语义,虽然有时会让人们措手不及的是使用相同的机制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)..你以后会感谢自己.

  • 你永远不想在反应堆中使用睡眠.一切都在主线程上运行(基本上),进行睡眠将暂停一切.测试的最佳方法是查看您的服务器是否可以处理多个连接.你也可以做一些事情,如果你要连接mysql,你会选择SLEEP(1)',这将导致MySQL被阻止,但这发生在MySQL内部,而不是反应堆.然后,如果您发出10个查询,它们应该在1秒内返回,而不是10秒. (3认同)