Created
May 8, 2019 07:31
-
-
Save romiras/d0109994c3da650d5c10961940763f0a to your computer and use it in GitHub Desktop.
EventMachine async URL fetcher
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://github.com/betamatt/fiber-test/blob/master/lib/fiber_pool.rb | |
require 'fiber' | |
class FiberPool | |
def initialize(max) | |
@max = max | |
@fibers = [] | |
@queue = [] | |
max.times do | |
fiber = Fiber.new do |value, block| | |
loop do | |
block.call(value) | |
if @queue.empty? | |
@fibers << Fiber.current | |
break if @done | |
block = Fiber.yield | |
else | |
value, block = @queue.shift | |
end | |
end | |
teardown | |
end | |
@fibers << fiber | |
end | |
end | |
def finish(parent) | |
@done = true | |
@parent = parent | |
end | |
def enqueue(value, &block) | |
if @fibers.empty? | |
@queue << [value, block] | |
else | |
fiber = @fibers.shift | |
fiber.resume([value, block]) | |
end | |
end | |
private | |
def teardown | |
@parent.resume if @fibers.size == @max | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source "https://rubygems.org" | |
gem 'eventmachine' | |
gem 'em-http-request' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'eventmachine' | |
require 'em-http-request' | |
require './lib/fiber_pool' | |
URLS = [ | |
'http://example.com/', | |
'https://www.cloudflare.com/robots2.txt', # 404 - not found | |
'https://rubygems.org/gems/em-http-request/versions.atom', | |
'http://twitter.com/robots.txt', | |
] | |
def url_handler(url) | |
fiber = Fiber.current | |
http = EventMachine::HttpRequest.new(url).get | |
http.callback { fiber.resume(http) } | |
http.errback { p 'Uh oh'; fiber.resume(http) } | |
Fiber.yield | |
puts "#{http.response_header.status.inspect} #{url}" | |
if http.response_header.status == 200 | |
p http.response[0,100] | |
else | |
p http.response_header | |
end | |
puts '-'*20 | |
end | |
def main | |
pool = FiberPool.new(3) | |
EventMachine.run do | |
URLS.each do |url| | |
pool.enqueue(url) do |url| | |
url_handler(url) | |
end | |
end | |
# Need a notification when all of the items on the queue are done processing | |
Fiber.new do | |
pool.finish(Fiber.current) | |
Fiber.yield # wait for callback | |
EM.stop | |
end.resume | |
end | |
end | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment