控制红宝石纤维流程

我知道纤维是合作的线程。 光纤具有对执行上下文的控制权,而抢先式线程不具有控制权。 光纤可以产生控制,这意味着光纤可以在明确的位置开始和停止。

显然,为什么光纤用于均匀的红宝石的原因是为了清理由反应堆图案引起的嵌套块。

但是我很难掌握下面使用光纤的脚本的控制流程。

def http_get(url)
  f = Fiber.current
  http = EventMachine::HttpRequest.new(url).get

  # resume fiber once http call is done
  http.callback { f.resume(http) }
  http.errback  { f.resume(http) }

  return Fiber.yield
end

EventMachine.run do
  Fiber.new{
    page = http_get('http://www.google.com/')
    puts "Fetched page: #{page.response_header.status}"

    if page
      page = http_get('http://www.google.com/search?q=eventmachine')
      puts "Fetched page 2: #{page.response_header.status}"
    end
  }.resume
end

我理解它的方式:

1)EM开始其事件循环

2)创建光纤,然后调用简历。 传递给新获得的代码块是否立即执行,或者是否在调用简历后执行?

3)第一次调用http_get。 它执行一个异步事件(在linux上使用select,poll或epoll)。 我们设置异步事件的事件处理程序(在回调方法中)。 然后光纤自动控制线程EventMachine(主线程)。 但是,只要调用回调函数,它将使用f.resume(http)进行控制。 但在这个简化的例子中,我是否应该在f.resume(http)之后放置自己的回调代码? 因为现在看起来好像f.resume(http)只是将控制权交还给光纤,并且什么都不做。

我认为yield之后会发生什么事情,控制权将进入EventMachine,并进入事件循环。 所以第二个http_get没有被调用。 现在一旦回调被调用,控制就返回到光纤(我们只使用一个Fiber.new,所以我假设在这一切中只有一个光纤实例)。 但是第二个http_get何时被调用?


让我看看我能否为你回答。 我在添加行号来帮助描述:

01: def http_get(url)
02:   f = Fiber.current
03:   http = EventMachine::HttpRequest.new(url).get
04: 
05:   # resume fiber once http call is done
06:   http.callback { f.resume(http) }
07:   http.errback  { f.resume(http) }
08: 
09:   return Fiber.yield
10: end
11: 
12: EventMachine.run do
13:   Fiber.new{
14:     page = http_get('http://www.google.com/')
15:     puts "Fetched page: #{page.response_header.status}"
16: 
17:     if page
18:       page = http_get('http://www.google.com/search?q=eventmachine')
19:       puts "Fetched page 2: #{page.response_header.status}"
20:     end
21:   }.resume
22: end
  • 第21行开始执行代码在14-20行的光纤
  • 纤维代码似乎在做以下工作:第14行检查我们是否可以在google.come上进行GET。 在第17行中,它检查是否有来自http_get有效响应,然后执行第18行中的下一个请求来搜索字符串eventmachine
  • 当光纤执行由于第21行的.resume启动时,第14行被执行,调用http_get方法。
  • 02行到07行设置异步HTTP GET请求和回调。
  • 09行将控制权交还给EventMachine。
  • 经过一段时间,来自线路03的异步HTTP GET调用异步完成执行并导致线路06或07上的回调之一后,在线路13至线路20上创建的原始光纤恢复控制。
  • 现在光纤执行从第15行继续。第06/07行的回调已经通过了http对象的引用,该对象现在在第14行的变量page中引用,随后在第15行中用于转储HTTP请求状态。
  • 随着光纤继续执行,它会检查page是否为真值,然后继续并再次调用http_get ,但使用新的URL。 请注意,代码if page可能永远不会执行,如果nil ,第15行将在没有检查nil情况下轰炸访问page
  • 类似的过程重复 - 02到07行设置HTTP GET调用,09行将控制权交还给EventMachine。
  • 经过一段时间后,其中一个回调被调用,Line 19在Fibre恢复控制时被执行。
  • 在执行第19行之后,光纤将会死亡。
  • 希望澄清此事。

    至于用额外的逻辑处理HTTP GET的响应,我想你可以用一些有意义的处理逻辑来替换这些puts 。 这个样本中的puts似乎是处理回复,回调主要用于恢复光纤。

    链接地址: http://www.djcxy.com/p/79329.html

    上一篇: control flow in ruby fiber program

    下一篇: How does one achieve parallel tasks with Ruby's Fibers?