rails_bridge 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.rdoc +33 -0
- data/VERSION +1 -1
- data/lib/rails_bridge/content_bridge.rb +27 -10
- data/rails_bridge.gemspec +1 -1
- data/spec/integration/content_bridge_spec.rb +25 -6
- metadata +3 -3
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -180,6 +180,39 @@ will create a class named +MyContentBridge+ containing a prototype request defin
|
|
180
180
|
|
181
181
|
All classes under app/rails_bridge/content_bridges will be loaded automatically during application initialization and reloaded when in running in development.
|
182
182
|
|
183
|
+
|
184
|
+
=== Batching requests for parallel execution
|
185
|
+
|
186
|
+
You can also queue up a batch of multiple requests and execute them in parallel to minimize the time it takes to execute them all. In order to assign the results, you must use the request_<request_name> method and pass a block accepting the result as a parameter which assigns the result to a variable in your context. When you have scheduled all of your requests, call +execute_requests+ to execute them in parallel. When +execute_requests+ returns, all of the blocks passed to your request methods will have been executed.
|
187
|
+
|
188
|
+
class TwitterStatusCacher < RailsBridge::ContentBridge
|
189
|
+
self.request_timeout = 2000 # miliseconds
|
190
|
+
self.cache_timeout = 60 # seconds
|
191
|
+
self.host = 'api.twitter.com'
|
192
|
+
self.path = '/statuses/user_timeline.json'
|
193
|
+
self.on_success {|content| JSON.parse(content).first['text']}
|
194
|
+
|
195
|
+
content_request( :hoonpark ) {|r| r.params = {:screen_name => 'hoonpark'}}
|
196
|
+
content_request( :soopa ) {|r| r.params = {:screen_name => 'soopa'}}
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
soopa_latest_tweet = hoonpark_latest_tweet = nil
|
201
|
+
|
202
|
+
TwitterStatusCacher.request_soopa do |result|
|
203
|
+
soopa_latest_tweet = result
|
204
|
+
end
|
205
|
+
|
206
|
+
TwitterStatusCacher.request_hoonpark do |result|
|
207
|
+
hoonpark_latest_tweet = result
|
208
|
+
end
|
209
|
+
|
210
|
+
# soopa_latest_tweet and hoonpark_latest_tweet not assigned yet
|
211
|
+
|
212
|
+
TwitterStatusCacher.execute_requests # executes requests in parallel
|
213
|
+
|
214
|
+
# soopa_latest_tweet and hoonpark_latest_tweet will now be assigned
|
215
|
+
|
183
216
|
---
|
184
217
|
|
185
218
|
== LAYOUT BRIDGE
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
@@ -79,34 +79,48 @@ module RailsBridge
|
|
79
79
|
[remote_url, options]
|
80
80
|
end
|
81
81
|
|
82
|
-
def
|
82
|
+
def request_remote_content( remote, options={}, &block )
|
83
83
|
hydra = Typhoeus::Hydra.hydra # the singleton Hydra
|
84
84
|
hydra.disable_memoization
|
85
85
|
remote_url, options = process_remote_and_options( remote, options )
|
86
86
|
default_content = options.delete(:default_content) || self.default_content
|
87
87
|
# options[:verbose] = true # for debugging only
|
88
88
|
request = Typhoeus::Request.new(remote_url, options)
|
89
|
-
|
89
|
+
if self.cache && request.cache_timeout && request.cache_timeout > 0 && result = cache_get( request.cache_key )
|
90
|
+
# result = on_success.call(result) if on_success
|
91
|
+
block.call(result)
|
92
|
+
else
|
90
93
|
result = default_content
|
91
94
|
request.on_complete do |response|
|
92
95
|
case response.code
|
93
96
|
when 200
|
94
|
-
|
95
|
-
|
96
|
-
else
|
97
|
-
result = response.body
|
98
|
-
end
|
97
|
+
result = response.body
|
98
|
+
result = on_success.call(result) if on_success
|
99
99
|
cache_set( request.cache_key, result, request.cache_timeout ) if self.cache && request.cache_timeout && request.cache_timeout > 0
|
100
100
|
logger.debug "ContentBridge : Request Succeeded - Content: #{result}"
|
101
101
|
when 0
|
102
102
|
logger.warn "ContentBridge : Request Timeout for #{remote_url}"
|
103
103
|
else
|
104
104
|
logger.warn "ContentBridge : Request for #{remote_url}\mRequest Failed with HTTP result code: #{response.code}\n#{response.body}"
|
105
|
-
end
|
105
|
+
end
|
106
|
+
block.call(result)
|
106
107
|
end
|
107
108
|
hydra.queue request
|
108
|
-
hydra.run # this is a blocking call that returns once all requests are complete
|
109
109
|
end
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def execute_requests
|
114
|
+
hydra = Typhoeus::Hydra.hydra # the singleton Hydra
|
115
|
+
hydra.run
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_remote_content( remote, options={} )
|
119
|
+
result = nil
|
120
|
+
request_remote_content( remote, options ) do |r_result|
|
121
|
+
result = r_result
|
122
|
+
end
|
123
|
+
execute_requests
|
110
124
|
result
|
111
125
|
end
|
112
126
|
|
@@ -125,10 +139,13 @@ module RailsBridge
|
|
125
139
|
new_request
|
126
140
|
end
|
127
141
|
|
128
|
-
def method_missing method, *args
|
142
|
+
def method_missing method, *args, &block
|
129
143
|
if matches = method.to_s.match( /^get_(.*)$/ )
|
130
144
|
request_name = matches[1]
|
131
145
|
self.get_remote_content( request_name.to_sym, *args )
|
146
|
+
elsif matches = method.to_s.match( /^request_(.*)$/ )
|
147
|
+
request_name = matches[1]
|
148
|
+
self.request_remote_content( request_name.to_sym, *args, &block )
|
132
149
|
else
|
133
150
|
super
|
134
151
|
end
|
data/rails_bridge.gemspec
CHANGED
@@ -22,10 +22,29 @@ describe RailsBridge::ContentBridge do
|
|
22
22
|
ContentBridgeTest.get_remote_content("http://localhost:#{TEST_SERVER_PORT}/")
|
23
23
|
end
|
24
24
|
|
25
|
-
it "fetches the server's content" do
|
25
|
+
it "fetches the server's content using get" do
|
26
26
|
ContentBridgeTest.get_chang.should == DEFAULT_RETURN_DATA
|
27
27
|
end
|
28
28
|
|
29
|
+
it "fetches the server's content in parallel using request" do
|
30
|
+
cbt = ContentBridgeTest
|
31
|
+
wang = ContentBridgeTest.content_requests[:chang].dup
|
32
|
+
wang.params = wang.params.merge({:return_data=>"other"})
|
33
|
+
cbt.content_requests[:wang] = wang
|
34
|
+
chang_result = wang_result = nil
|
35
|
+
cbt.request_wang do |result|
|
36
|
+
wang_result = result
|
37
|
+
end
|
38
|
+
cbt.request_chang do |result|
|
39
|
+
chang_result = result
|
40
|
+
end
|
41
|
+
wang_result.should == nil
|
42
|
+
chang_result.should == nil
|
43
|
+
cbt.execute_requests
|
44
|
+
chang_result.should == DEFAULT_RETURN_DATA
|
45
|
+
wang_result.should == "other"
|
46
|
+
end
|
47
|
+
|
29
48
|
it "honors the bridge's request_timeout on a hung connection" do
|
30
49
|
cbt = ContentBridgeTest
|
31
50
|
wang = ContentBridgeTest.content_requests[:chang].dup
|
@@ -56,20 +75,20 @@ describe RailsBridge::ContentBridge do
|
|
56
75
|
unique = __LINE__
|
57
76
|
cbt = ContentBridgeTest
|
58
77
|
chang = cbt.content_requests[:chang]
|
59
|
-
cbt.get_chang(:cache_timeout=>60,:params=>
|
78
|
+
cbt.get_chang(:cache_timeout=>60,:params=>{:unique=>unique}).should == DEFAULT_RETURN_DATA
|
60
79
|
TestServer.shutdown
|
61
|
-
cbt.get_chang(:cache_timeout=>60,:params=>
|
80
|
+
cbt.get_chang(:cache_timeout=>60,:params=>{:unique=>unique}).should == DEFAULT_RETURN_DATA
|
62
81
|
end
|
63
82
|
|
64
83
|
it "the cache expires correctly" do
|
65
84
|
unique = __LINE__
|
66
85
|
cbt = ContentBridgeTest
|
67
86
|
chang = cbt.content_requests[:chang]
|
68
|
-
cbt.get_chang(:cache_timeout=>2,:params=>
|
87
|
+
cbt.get_chang(:cache_timeout=>2,:params=>{:unique=>unique}).should == DEFAULT_RETURN_DATA
|
69
88
|
TestServer.shutdown
|
70
|
-
cbt.get_chang(:cache_timeout=>2,:params=>
|
89
|
+
cbt.get_chang(:cache_timeout=>2,:params=>{:unique=>unique}).should == DEFAULT_RETURN_DATA
|
71
90
|
sleep 2
|
72
|
-
cbt.get_chang(:cache_timeout=>2,:params=>
|
91
|
+
cbt.get_chang(:cache_timeout=>2,:params=>{:unique=>unique}).should == cbt.content_requests[:chang].default_content
|
73
92
|
end
|
74
93
|
|
75
94
|
it "allows get_remote_content to be called directly with request options" do
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 8
|
9
|
+
version: 0.0.8
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- shock
|
@@ -331,7 +331,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
331
331
|
requirements:
|
332
332
|
- - ">="
|
333
333
|
- !ruby/object:Gem::Version
|
334
|
-
hash:
|
334
|
+
hash: -987999199138465577
|
335
335
|
segments:
|
336
336
|
- 0
|
337
337
|
version: "0"
|