Skip to content

Commit

Permalink
fix iterators + add async http example with iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
igrigorik committed Mar 21, 2010
1 parent 3945a39 commit 3867c2e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
33 changes: 20 additions & 13 deletions lib/em-synchrony/iterator.rb
Expand Up @@ -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
Expand Down
30 changes: 24 additions & 6 deletions spec/iterator_spec.rb
Expand Up @@ -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)
Expand All @@ -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
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

0 comments on commit 3867c2e

Please sign in to comment.