igrigorik / em-synchrony

Fiber aware EventMachine clients and convenience classes
http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers
MIT License
1.04k stars 151 forks source link

problem with recursive nested iterator #13

Closed francescoagati closed 13 years ago

francescoagati commented 13 years ago

with this code

require 'rubygems' require 'eventmachine' require "em-synchrony" require "em-synchrony/em-http" require "em-synchrony/iterator" require 'nokogiri'

EM.synchrony do concurrency = 2 urls = ["http://www.x1.com", "http://www.x2.com"]

iterator will execute async blocks until completion, .each, .inject also work!

results = EM::Synchrony::Iterator.new(urls, concurrency).map do |url, iter|

# fire async requests, on completion advance the iterator
http = EventMachine::HttpRequest.new(url).aget
http.callback { iter.return(http) }

end

result2 = EM::Synchrony::Iterator.new(results, concurrency).map do |client, iter| doc=Nokogiri::XML(client.response)

results_xml=nil
Fiber.new do

  results_xml = EM::Synchrony::Iterator.new(doc.search("*"), concurrency).map do |node, iter2|
    iter2.return(node.name)
  end

end.resume

iter.return(results_xml)

end

p result2

EventMachine.stop end

result2 is an array of nil. if like if second iterator don't return to first iterator the result. where i have write wrong code? is right or synchroni can only use of one level of profondity in stack?

igrigorik commented 13 years ago

Francesco, you don't necessarily have to use synchrony iterators for every operation. Specifically, you only need to use them when you're making an outbound network call, which may block for a long time.

In your example, once you've fetched the page, simply iterate over the results using your regular ruby each/map/collect/inject. You don't win anything by wrapping your code into more fibers there, since all of those operations are CPU bound.

Here's a simplified, working example of the code you provided: https://gist.github.com/735865

francescoagati commented 13 years ago

ok thanks in advance.