rails_bridge 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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"
|