| Class | EventMachine::Iterator |
| In: |
lib/em/iterator.rb
|
| Parent: | Object |
A simple iterator for concurrent asynchronous work.
Unlike ruby‘s built-in iterators, the end of the current iteration cycle is signaled manually, instead of happening automatically after the yielded block finishes executing. For example:
(0..10).each{ |num| }
becomes:
EM::Iterator.new(0..10).each{ |num,iter| iter.next }
This is especially useful when doing asynchronous work via reactor libraries and functions. For example, given a sync and async http api:
response = sync_http_get(url); ...
async_http_get(url){ |response| ... }
a synchronous iterator such as:
responses = urls.map{ |url| sync_http_get(url) }
...
puts 'all done!'
could be written as:
EM::Iterator.new(urls).map(proc{ |url,iter|
async_http_get(url){ |res|
iter.return(res)
}
}, proc{ |responses|
...
puts 'all done!'
})
Now, you can take advantage of the asynchronous api to issue requests in parallel. For example, to fetch 10 urls at a time, simply pass in a concurrency of 10:
EM::Iterator.new(urls, 10).each do |url,iter|
async_http_get(url){ iter.next }
end
| concurrency | [R] |
Change the concurrency of this iterator. Workers will automatically be spawned or destroyed to accomodate the new concurrency level.
Iterate over a set of items using the specified block or proc.
EM::Iterator.new(1..100).each do |num, iter|
puts num
iter.next
end
An optional second proc is invoked after the iteration is complete.
EM::Iterator.new(1..100).each(
proc{ |num,iter| iter.next },
proc{ puts 'all done' }
)
Inject the results of an asynchronous iteration onto a given object.
EM::Iterator.new(%w[ pwd uptime uname date ], 2).inject({}, proc{ |hash,cmd,iter|
EM.system(cmd){ |output,status|
hash[cmd] = status.exitstatus == 0 ? output.strip : nil
iter.return(hash)
}
}, proc{ |results|
p results
})