diff --git a/lib/em-synchrony/iterator.rb b/lib/em-synchrony/iterator.rb index 7f6d84a..21d7cc7 100644 --- a/lib/em-synchrony/iterator.rb +++ b/lib/em-synchrony/iterator.rb @@ -23,21 +23,28 @@ def each(foreach=nil, after=nil, &blk) def map(&block) fiber = Fiber.current - after = Proc.new {|result| p [:after_map, result]; fiber.resume(result)} - - Fiber.yield super(block, after) - end + result = nil - def inject(obj, &block) - fiber = Fiber.current - after = Proc.new {|result| p [:after_inject, result]; fiber.resume(result)} - super(obj, block, after) - Fiber.yield + after = Proc.new {|res| result = res; fiber.resume } + super(block, after) + + Fiber.yield + result end - - # original iterator method for map support - def inject(obj, foreach, after) - super(obj, foreach, after) + + def inject(obj, foreach = nil, after = nil, &block) + if foreach and after + super(obj, foreach, after) + else + fiber = Fiber.current + result = nil + + after = Proc.new {|res| result = res; fiber.resume} + super(obj, block, after) + + Fiber.yield + result + end end end diff --git a/spec/iterator_spec.rb b/spec/iterator_spec.rb index 5a51b88..6d0fdb1 100644 --- a/spec/iterator_spec.rb +++ b/spec/iterator_spec.rb @@ -19,8 +19,6 @@ end it "should map values within the iterator" do - pending "erm?" - EM.synchrony do results = EM::Synchrony::Iterator.new(1..50, 10).map do |num, iter| iter.return(num + 1) @@ -33,18 +31,38 @@ end it "should sum values within the iterator" do - pending "erm?" - EM.synchrony do data = (1..50).to_a res = EM::Synchrony::Iterator.new(data, 10).inject(0) do |total, num, iter| total += num iter.return(total) end - + res.should == data.inject(:+) EventMachine.stop end end -end \ No newline at end of file + it "should fire async http requests in blocks of 2" do + EM.synchrony do + num_urls = 4 + concurrency = 2 + delay = 0.25 + + s = StubServer.new("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nFoo", delay) + urls = ['http://localhost:8081/'] * num_urls + + start = now + results = EM::Synchrony::Iterator.new(urls, concurrency).map do |url, iter| + http = EventMachine::HttpRequest.new(url).aget + http.callback { iter.return(http) } + end + + results.size.should == 4 + (now - start.to_f).should be_within(delay * 0.15).of(delay * (num_urls / concurrency)) + + EventMachine.stop + end + end + +end