Skip to content

Commit b71b40e

Browse files
committed
adding a sample for using fiber
1 parent f3cfded commit b71b40e

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

samples/fiber_crawler.rb

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env ruby
2+
3+
# Use the locally built curb (extension + libs) instead of any installed gem.
4+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
5+
$LOAD_PATH.unshift File.expand_path('../ext', __dir__)
6+
7+
require 'curl'
8+
9+
# Demo parameters
10+
GROUPS = (ENV['GROUPS'] || 3).to_i
11+
PER_GROUP = (ENV['PER_GROUP'] || 5).to_i
12+
CONNECT_TIMEOUT = (ENV['CONNECT_TIMEOUT'] || 5).to_i
13+
TOTAL_TIMEOUT = (ENV['TOTAL_TIMEOUT'] || 15).to_i
14+
DELAY_S = (ENV['DELAY_S'] || 0.25).to_f
15+
16+
require 'webrick'
17+
require 'async'
18+
19+
# Start a small local HTTP server on loopback and wait until it’s listening.
20+
ready = Queue.new
21+
server = WEBrick::HTTPServer.new(
22+
BindAddress: '127.0.0.1',
23+
Port: (ENV['PORT'] || 0).to_i, # 0 chooses a free port
24+
Logger: WEBrick::Log.new($stderr, WEBrick::Log::FATAL),
25+
AccessLog: [],
26+
StartCallback: -> { ready << true }
27+
)
28+
server.mount_proc('/test') do |_req, res|
29+
sleep DELAY_S
30+
res.status = 200
31+
res['Content-Type'] = 'text/plain'
32+
res.body = 'OK'
33+
end
34+
35+
server_thread = Thread.new { server.start }
36+
ready.pop # wait until the server is bound
37+
bound_port = server.listeners.first.addr[1]
38+
URL = "http://127.0.0.1:#{bound_port}/test"
39+
40+
puts "Async demo: groups=#{GROUPS} per_group=#{PER_GROUP} url=#{URL} delay=#{DELAY_S}s"
41+
42+
def crawl(url)
43+
c = Curl::Easy.new
44+
c.url = url
45+
c.connect_timeout = CONNECT_TIMEOUT
46+
c.timeout = TOTAL_TIMEOUT
47+
start = Time.now
48+
code = nil
49+
error = nil
50+
begin
51+
c.perform
52+
code = c.response_code
53+
rescue => e
54+
code = -1
55+
error = "#{e.class}: #{e.message}"
56+
end
57+
{ code: code, error: error, duration: (Time.now - start) }
58+
end
59+
60+
results = []
61+
started = Time.now
62+
if Async.respond_to?(:run)
63+
Async.run do |top|
64+
GROUPS.times do
65+
PER_GROUP.times do
66+
top.async do
67+
results << crawl(URL)
68+
end
69+
end
70+
end
71+
end
72+
else
73+
Async do |top|
74+
GROUPS.times do
75+
PER_GROUP.times do
76+
top.async do
77+
results << crawl(URL)
78+
end
79+
end
80+
end
81+
end
82+
end
83+
duration = Time.now - started
84+
85+
ok = results.count { |r| r[:code] == 200 }
86+
fail = results.count { |r| r[:code] != 200 }
87+
puts "Completed #{results.size} requests in #{duration.round(3)}s (ok=#{ok}, fail=#{fail})"
88+
89+
server.shutdown
90+
server_thread.join

0 commit comments

Comments
 (0)