rest-core 3.5.1 → 3.5.2
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -3
- data/CHANGES.md +11 -0
- data/lib/rest-core/client.rb +1 -5
- data/lib/rest-core/promise.rb +39 -28
- data/lib/rest-core/timer.rb +3 -2
- data/lib/rest-core/version.rb +1 -1
- data/rest-core.gemspec +3 -3
- data/test/test_httpclient.rb +1 -2
- data/test/test_timeout.rb +4 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0399835474967a9425ce60b8073d0b4a49e7c572
|
4
|
+
data.tar.gz: 6cac1d0a2fce2e8f5ea64e64b2b56343d8e61368
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5beda3343160e6e04d7df902f702a6d99aa02ef49c6e7d9085d398c76ec07d518e096af779bdbf336a6e2b80fe20438f630676b4c97cd20706d990d0a263c5db
|
7
|
+
data.tar.gz: 1ee0950dd782a66de5bf11fe8e5cf4f7a42da6717883a7d25c58be37abb7c38d7ad5b1334bef1325b45e42eafd46d250ae0b928d4846757af0bfc7fe90019c1d
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## rest-core 3.5.2 -- 2015-01-09
|
4
|
+
|
5
|
+
### Bugs fixed
|
6
|
+
|
7
|
+
* Now callbacks would respect `RC::RESPONSE_KEY`.
|
8
|
+
* Clear `Thread.current[:backtrace]` after done in thread pool to reduce
|
9
|
+
memory footprint.
|
10
|
+
* Fixed backtrace for exception raised in callbacks.
|
11
|
+
* Fixed some potential corner cases where errors are not properly handled
|
12
|
+
when timeout happened.
|
13
|
+
|
3
14
|
## rest-core 3.5.1 -- 2014-12-27
|
4
15
|
|
5
16
|
* Ruby 2.2 compatibility.
|
data/lib/rest-core/client.rb
CHANGED
@@ -214,11 +214,7 @@ module RestCore::Client
|
|
214
214
|
RC::Promise.set_backtrace(err) unless err.backtrace
|
215
215
|
error_callback.call(err) if error_callback
|
216
216
|
if res[ASYNC]
|
217
|
-
|
218
|
-
res.merge(RESPONSE_SOCKET => err)
|
219
|
-
else
|
220
|
-
res.merge(RESPONSE_BODY => err)
|
221
|
-
end
|
217
|
+
res.merge(response_key(res) => err)
|
222
218
|
else
|
223
219
|
raise err
|
224
220
|
end
|
data/lib/rest-core/promise.rb
CHANGED
@@ -65,16 +65,15 @@ class RestCore::Promise
|
|
65
65
|
# called in client thread
|
66
66
|
def defer
|
67
67
|
if pool_size < 0 # negative number for blocking call
|
68
|
-
self.thread = Thread.current
|
69
|
-
|
70
|
-
env[TIMER].on_timeout{ cancel_task } if env[TIMER]
|
71
|
-
protected_yield{ yield }
|
68
|
+
self.thread = Thread.current # set working thread
|
69
|
+
protected_yield{ yield } # avoid any exception and do the job
|
72
70
|
else
|
73
71
|
backtrace = caller + self.class.backtrace
|
74
72
|
if pool_size > 0
|
75
73
|
self.task = client_class.thread_pool.defer(mutex) do
|
76
74
|
Thread.current[:backtrace] = backtrace
|
77
75
|
protected_yield{ yield }
|
76
|
+
Thread.current[:backtrace] = nil
|
78
77
|
end
|
79
78
|
else
|
80
79
|
self.thread = Thread.new do
|
@@ -82,8 +81,6 @@ class RestCore::Promise
|
|
82
81
|
protected_yield{ yield }
|
83
82
|
end
|
84
83
|
end
|
85
|
-
# set timeout after thread/task set
|
86
|
-
env[TIMER].on_timeout{ cancel_task } if env[TIMER]
|
87
84
|
end
|
88
85
|
end
|
89
86
|
|
@@ -153,32 +150,31 @@ class RestCore::Promise
|
|
153
150
|
# called in a new thread if pool_size == 0, otherwise from the pool
|
154
151
|
# i.e. requesting thread
|
155
152
|
def protected_yield
|
156
|
-
|
153
|
+
if env[TIMER]
|
154
|
+
timeout_protected_yield{ yield }
|
155
|
+
else
|
156
|
+
yield
|
157
|
+
end
|
157
158
|
rescue Exception => e
|
158
159
|
mutex.synchronize do
|
159
|
-
|
160
|
-
|
161
|
-
self.class.set_backtrace(e)
|
162
|
-
end
|
163
|
-
|
164
|
-
if done?
|
160
|
+
self.class.set_backtrace(e)
|
161
|
+
if done? # log user callback error
|
165
162
|
callback_error(e)
|
166
|
-
else
|
163
|
+
else # IOError, SystemCallError, etc
|
167
164
|
begin
|
168
|
-
rejecting(e)
|
169
|
-
rescue Exception =>
|
170
|
-
callback_error(
|
165
|
+
rejecting(e)
|
166
|
+
rescue Exception => f # log user callback error
|
167
|
+
callback_error(f){ self.class.set_backtrace(f) }
|
171
168
|
end
|
172
169
|
end
|
173
170
|
end
|
174
171
|
end
|
175
172
|
|
176
|
-
|
177
|
-
|
178
|
-
def never_raise_yield
|
173
|
+
def timeout_protected_yield
|
174
|
+
env[TIMER].on_timeout{ cancel_task } # set timeout
|
179
175
|
yield
|
180
|
-
|
181
|
-
|
176
|
+
ensure
|
177
|
+
env[TIMER].cancel
|
182
178
|
end
|
183
179
|
|
184
180
|
# called in client thread, when yield is called
|
@@ -195,8 +191,10 @@ class RestCore::Promise
|
|
195
191
|
self.called = true
|
196
192
|
end
|
197
193
|
|
194
|
+
# log user callback error
|
198
195
|
def callback_error e
|
199
196
|
never_raise_yield do
|
197
|
+
yield if block_given?
|
200
198
|
if env[CLIENT].error_callback
|
201
199
|
env[CLIENT].error_callback.call(e)
|
202
200
|
else
|
@@ -205,18 +203,31 @@ class RestCore::Promise
|
|
205
203
|
end
|
206
204
|
end
|
207
205
|
|
208
|
-
|
206
|
+
# timeout!
|
207
|
+
def cancel_task backtrace=nil
|
209
208
|
mutex.synchronize do
|
210
|
-
next if done?
|
209
|
+
next if done? # don't cancel if it's done
|
211
210
|
if t = thread || task.thread
|
212
|
-
t.raise(env[TIMER].error)
|
213
|
-
else
|
214
|
-
|
215
|
-
|
211
|
+
t.raise(env[TIMER].error) # raise Timeout::Error to working thread
|
212
|
+
else # task was queued and never started, just cancel it and
|
213
|
+
begin # fulfil the promise with Timeout::Error
|
214
|
+
task.cancel
|
215
|
+
rejecting(env[TIMER].error)
|
216
|
+
rescue Exception => e # log user callback error
|
217
|
+
callback_error(e){e.set_backtrace(e.backtrace + (backtrace || []))}
|
218
|
+
end
|
216
219
|
end
|
217
220
|
end
|
218
221
|
end
|
219
222
|
|
223
|
+
# only use this for unimportant stuffs and in most critical section
|
224
|
+
# e.g. error logging in critical section
|
225
|
+
def never_raise_yield
|
226
|
+
yield
|
227
|
+
rescue Exception => e
|
228
|
+
Thread.main.raise(e) if !!$DEBUG
|
229
|
+
end
|
230
|
+
|
220
231
|
def client_class; env[CLIENT].class; end
|
221
232
|
def pool_size
|
222
233
|
@pool_size ||= if client_class.respond_to?(:pool_size)
|
data/lib/rest-core/timer.rb
CHANGED
@@ -34,16 +34,17 @@ class RestCore::Timer
|
|
34
34
|
self.timeout = timeout
|
35
35
|
self.error = error
|
36
36
|
self.block = block
|
37
|
-
start
|
37
|
+
start if block_given?
|
38
38
|
end
|
39
39
|
|
40
40
|
def on_timeout &block
|
41
41
|
self.block = block
|
42
|
+
start if block_given?
|
42
43
|
end
|
43
44
|
|
44
45
|
# should never raise!
|
45
46
|
def cancel
|
46
|
-
timer.cancel
|
47
|
+
timer.cancel if timer
|
47
48
|
self.block = nil
|
48
49
|
end
|
49
50
|
|
data/lib/rest-core/version.rb
CHANGED
data/rest-core.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: rest-core 3.5.
|
2
|
+
# stub: rest-core 3.5.2 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "rest-core"
|
6
|
-
s.version = "3.5.
|
6
|
+
s.version = "3.5.2"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib"]
|
10
10
|
s.authors = ["Lin Jen-Shin (godfat)"]
|
11
|
-
s.date = "
|
11
|
+
s.date = "2015-01-09"
|
12
12
|
s.description = "Modular Ruby clients interface for REST APIs.\n\nThere has been an explosion in the number of REST APIs available today.\nTo address the need for a way to access these APIs easily and elegantly,\nwe have developed rest-core, which consists of composable middleware\nthat allows you to build a REST client for any REST API. Or in the case of\ncommon APIs such as Facebook, Github, and Twitter, you can simply use the\ndedicated clients provided by [rest-more][].\n\n[rest-more]: https://github.com/godfat/rest-more"
|
13
13
|
s.email = ["godfat (XD) godfat.org"]
|
14
14
|
s.files = [
|
data/test/test_httpclient.rb
CHANGED
@@ -40,8 +40,7 @@ describe RC::HttpClient do
|
|
40
40
|
|
41
41
|
would 'not kill the thread if error was coming from the task' do
|
42
42
|
mock(HTTPClient).new{ raise 'boom' }.with_any_args
|
43
|
-
c.request(RC::
|
44
|
-
RC::ASYNC => true).first.message.should.eq 'boom'
|
43
|
+
c.request(RC::ASYNC => true).message.should.eq 'boom'
|
45
44
|
Muack.verify
|
46
45
|
end
|
47
46
|
end
|
data/test/test_timeout.rb
CHANGED
@@ -43,9 +43,8 @@ describe RC::Timeout do
|
|
43
43
|
}
|
44
44
|
end
|
45
45
|
app.pool_size = 1
|
46
|
-
app.new.request(RC::
|
47
|
-
|
48
|
-
first.message.should.eq 'boom'
|
46
|
+
app.new.request(RC::TIMER => timer, RC::ASYNC => true).
|
47
|
+
message.should.eq 'boom'
|
49
48
|
end
|
50
49
|
|
51
50
|
would 'interrupt the task if timing out' do
|
@@ -71,9 +70,8 @@ describe RC::Timeout do
|
|
71
70
|
end
|
72
71
|
(-1..1).each do |size|
|
73
72
|
app.pool_size = size
|
74
|
-
app.new.request(RC::
|
75
|
-
|
76
|
-
first.message.should.eq 'boom'
|
73
|
+
app.new.request(RC::TIMER => timer, RC::ASYNC => true, 'pipe' => wr).
|
74
|
+
message.should.eq 'boom'
|
77
75
|
end
|
78
76
|
end
|
79
77
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.5.
|
4
|
+
version: 3.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lin Jen-Shin (godfat)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|