-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasyncness.rb
86 lines (76 loc) · 2.53 KB
/
asyncness.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Depends on gems eventmachine, em-http-request,
# and em-resolv-replace (for # async DNS)
require 'eventmachine'
require 'em-http'
require 'fiber'
require 'em-resolv-replace'
def make_request_to(url)
connection = EventMachine::HttpRequest.new(url)
request = connection.get
# Stores the fiber on which the request was made
original_fiber = Fiber.current
# This block is going to be executed when the request finishes
request.callback do
# When the request finishes, we wake the fiber with Fiber#resume. The
# argument we pass here (the result of the request) will be the return
# value of Fiber.yield
original_fiber.resume(request.response)
end
request.errback do
puts "Ooops :("
EM.stop
end
# This will make the fiber be 'suspended' until a #resume call is issued
# against it. The argument given to #resume will be the return value here.
return Fiber.yield
end
# Simple counter to know when to exit the program. A web server probably
# wouldnt' have something like this :)
def notify_done(number)
@complete_requests ||= 0
@complete_requests += 1
#NOTE: depending on a number... variable... not so smart.
if @complete_requests == number
EM.stop
end
puts "done? #{@complete_requests}"
puts
end
# rack-fiber-pool does something similar to this:
# It puts each request on a
# different fiber. When you Fiber.yield (either directly or with a library
# such as em-synchrony doing that for you), the server goes on and handles the
# next request on the line. Then, as the fibers get awaken (from the database
# driver, or from an external http call, like on this example), the server
# continues processing the original request.
#NOTE Example:
# EM.run do
# # We put inside the lines that depend on each other on the same fiber. For
# # instance: printing the response depends on the response arriving.
# Fiber.new {
# puts 'Making google request'
#
# # This call is going to suspend the fiber until the request returns.
# google_response = make_request_to("http://google.com")
#
# puts
# puts "google response:"
# puts google_response.lines.take(10)
#
# notify_done
# }.resume
#
# Fiber.new {
# puts 'Making twitter request'
#
# # Since the previous fiber is suspended as soon as the 'google' request is
# # made, the 'twitter' request is made before the previous one returns.
# twitter_response = make_request_to("http://twitter.com")
#
# puts
# puts "twitter response:"
# puts twitter_response.lines.take(10)
#
# notify_done
# }.resume
# end