rest-core 3.6.0 → 4.0.0

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/.travis.yml +0 -1
  4. data/CHANGES.md +28 -0
  5. data/Gemfile +0 -2
  6. data/README.md +14 -95
  7. data/Rakefile +16 -3
  8. data/example/simple.rb +1 -0
  9. data/example/use-cases.rb +15 -3
  10. data/lib/rest-core.rb +38 -75
  11. data/lib/rest-core/client/universal.rb +3 -1
  12. data/lib/rest-core/client_oauth1.rb +64 -59
  13. data/lib/rest-core/event.rb +9 -11
  14. data/lib/rest-core/middleware/auth_basic.rb +21 -21
  15. data/lib/rest-core/middleware/bypass.rb +8 -8
  16. data/lib/rest-core/middleware/cache.rb +94 -90
  17. data/lib/rest-core/middleware/clash_response.rb +15 -14
  18. data/lib/rest-core/middleware/common_logger.rb +27 -26
  19. data/lib/rest-core/middleware/default_headers.rb +8 -8
  20. data/lib/rest-core/middleware/default_payload.rb +8 -8
  21. data/lib/rest-core/middleware/default_query.rb +8 -8
  22. data/lib/rest-core/middleware/default_site.rb +12 -12
  23. data/lib/rest-core/middleware/defaults.rb +38 -38
  24. data/lib/rest-core/middleware/error_detector.rb +10 -10
  25. data/lib/rest-core/middleware/error_detector_http.rb +6 -4
  26. data/lib/rest-core/middleware/error_handler.rb +14 -14
  27. data/lib/rest-core/middleware/follow_redirect.rb +28 -27
  28. data/lib/rest-core/middleware/json_request.rb +13 -11
  29. data/lib/rest-core/middleware/json_response.rb +29 -28
  30. data/lib/rest-core/middleware/oauth1_header.rb +84 -83
  31. data/lib/rest-core/middleware/oauth2_header.rb +27 -25
  32. data/lib/rest-core/middleware/oauth2_query.rb +15 -15
  33. data/lib/rest-core/middleware/query_response.rb +14 -14
  34. data/lib/rest-core/middleware/retry.rb +25 -23
  35. data/lib/rest-core/middleware/smash_response.rb +15 -14
  36. data/lib/rest-core/middleware/timeout.rb +18 -19
  37. data/lib/rest-core/test.rb +1 -18
  38. data/lib/rest-core/util/clash.rb +38 -37
  39. data/lib/rest-core/util/config.rb +40 -39
  40. data/lib/rest-core/util/dalli_extension.rb +11 -10
  41. data/lib/rest-core/util/hmac.rb +9 -8
  42. data/lib/rest-core/util/json.rb +55 -54
  43. data/lib/rest-core/util/parse_link.rb +13 -12
  44. data/lib/rest-core/util/parse_query.rb +24 -22
  45. data/lib/rest-core/version.rb +1 -1
  46. data/rest-core.gemspec +121 -158
  47. data/test/test_cache.rb +2 -0
  48. data/test/test_default_payload.rb +1 -1
  49. data/test/test_error_handler.rb +5 -4
  50. data/test/test_timeout.rb +9 -8
  51. data/test/test_universal.rb +8 -0
  52. metadata +9 -73
  53. data/lib/rest-core/builder.rb +0 -162
  54. data/lib/rest-core/client.rb +0 -277
  55. data/lib/rest-core/client/simple.rb +0 -2
  56. data/lib/rest-core/engine.rb +0 -36
  57. data/lib/rest-core/engine/dry.rb +0 -9
  58. data/lib/rest-core/engine/http-client.rb +0 -41
  59. data/lib/rest-core/error.rb +0 -5
  60. data/lib/rest-core/event_source.rb +0 -137
  61. data/lib/rest-core/middleware.rb +0 -151
  62. data/lib/rest-core/promise.rb +0 -249
  63. data/lib/rest-core/thread_pool.rb +0 -131
  64. data/lib/rest-core/timer.rb +0 -58
  65. data/lib/rest-core/util/payload.rb +0 -173
  66. data/test/test_builder.rb +0 -40
  67. data/test/test_client.rb +0 -177
  68. data/test/test_event_source.rb +0 -159
  69. data/test/test_future.rb +0 -16
  70. data/test/test_httpclient.rb +0 -118
  71. data/test/test_payload.rb +0 -204
  72. data/test/test_promise.rb +0 -146
  73. data/test/test_simple.rb +0 -38
  74. data/test/test_thread_pool.rb +0 -10
@@ -8,6 +8,7 @@ describe RC::Universal do
8
8
  WebMock.reset!
9
9
  end
10
10
 
11
+ # TODO: RuntimeError: The request GET http://localhost:1/ with body nil was expected to execute 1 time but it executed 2 times
11
12
  would 'only send payload for post, put, patch' do
12
13
  c = RC::Universal.new(:log_method => false, :payload => '$payload')
13
14
  [:get, :delete, :head, :options].each do |method|
@@ -69,4 +70,11 @@ describe RC::Universal do
69
70
  errors.map(&:class).should.eq [Errno::ECONNREFUSED]*2
70
71
  called.map(&:class).should.eq [Errno::ECONNREFUSED]
71
72
  end
73
+
74
+ would 'not deadlock with ErrorHandler' do
75
+ c = RC::Universal.new(:log_method => false).
76
+ event_source('http://localhost:1')
77
+ c.onerror{ |e| e.should.kind_of?(Errno::ECONNREFUSED) }
78
+ c.start.wait
79
+ end
72
80
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.0
4
+ version: 4.0.0
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: 2016-01-27 00:00:00.000000000 Z
11
+ date: 2016-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: httpclient
14
+ name: rest-builder
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -24,45 +24,12 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: mime-types
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: timers
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 4.0.1
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: 4.0.1
55
27
  description: |-
56
- Modular Ruby clients interface for REST APIs.
57
-
58
- There has been an explosion in the number of REST APIs available today.
59
- To address the need for a way to access these APIs easily and elegantly,
60
- we have developed rest-core, which consists of composable middleware
61
- that allows you to build a REST client for any REST API. Or in the case of
62
- common APIs such as Facebook, Github, and Twitter, you can simply use the
63
- dedicated clients provided by [rest-more][].
28
+ Various [rest-builder](https://github.com/godfat/rest-builder) middleware
29
+ for building REST clients.
64
30
 
65
- [rest-more]: https://github.com/godfat/rest-more
31
+ Checkout [rest-more](https://github.com/godfat/rest-more) for pre-built
32
+ clients.
66
33
  email:
67
34
  - godfat (XD) godfat.org
68
35
  executables: []
@@ -82,18 +49,9 @@ files:
82
49
  - example/simple.rb
83
50
  - example/use-cases.rb
84
51
  - lib/rest-core.rb
85
- - lib/rest-core/builder.rb
86
- - lib/rest-core/client.rb
87
- - lib/rest-core/client/simple.rb
88
52
  - lib/rest-core/client/universal.rb
89
53
  - lib/rest-core/client_oauth1.rb
90
- - lib/rest-core/engine.rb
91
- - lib/rest-core/engine/dry.rb
92
- - lib/rest-core/engine/http-client.rb
93
- - lib/rest-core/error.rb
94
54
  - lib/rest-core/event.rb
95
- - lib/rest-core/event_source.rb
96
- - lib/rest-core/middleware.rb
97
55
  - lib/rest-core/middleware/auth_basic.rb
98
56
  - lib/rest-core/middleware/bypass.rb
99
57
  - lib/rest-core/middleware/cache.rb
@@ -117,10 +75,7 @@ files:
117
75
  - lib/rest-core/middleware/retry.rb
118
76
  - lib/rest-core/middleware/smash_response.rb
119
77
  - lib/rest-core/middleware/timeout.rb
120
- - lib/rest-core/promise.rb
121
78
  - lib/rest-core/test.rb
122
- - lib/rest-core/thread_pool.rb
123
- - lib/rest-core/timer.rb
124
79
  - lib/rest-core/util/clash.rb
125
80
  - lib/rest-core/util/config.rb
126
81
  - lib/rest-core/util/dalli_extension.rb
@@ -128,7 +83,6 @@ files:
128
83
  - lib/rest-core/util/json.rb
129
84
  - lib/rest-core/util/parse_link.rb
130
85
  - lib/rest-core/util/parse_query.rb
131
- - lib/rest-core/util/payload.rb
132
86
  - lib/rest-core/util/smash.rb
133
87
  - lib/rest-core/version.rb
134
88
  - rest-core.gemspec
@@ -136,11 +90,9 @@ files:
136
90
  - task/gemgem.rb
137
91
  - test/config/rest-core.yaml
138
92
  - test/test_auth_basic.rb
139
- - test/test_builder.rb
140
93
  - test/test_cache.rb
141
94
  - test/test_clash.rb
142
95
  - test/test_clash_response.rb
143
- - test/test_client.rb
144
96
  - test/test_client_oauth1.rb
145
97
  - test/test_config.rb
146
98
  - test/test_dalli_extension.rb
@@ -151,23 +103,16 @@ files:
151
103
  - test/test_error_detector.rb
152
104
  - test/test_error_detector_http.rb
153
105
  - test/test_error_handler.rb
154
- - test/test_event_source.rb
155
106
  - test/test_follow_redirect.rb
156
- - test/test_future.rb
157
- - test/test_httpclient.rb
158
107
  - test/test_json_request.rb
159
108
  - test/test_json_response.rb
160
109
  - test/test_oauth1_header.rb
161
110
  - test/test_oauth2_header.rb
162
111
  - test/test_parse_link.rb
163
- - test/test_payload.rb
164
- - test/test_promise.rb
165
112
  - test/test_query_response.rb
166
113
  - test/test_retry.rb
167
- - test/test_simple.rb
168
114
  - test/test_smash.rb
169
115
  - test/test_smash_response.rb
170
- - test/test_thread_pool.rb
171
116
  - test/test_timeout.rb
172
117
  - test/test_universal.rb
173
118
  homepage: https://github.com/godfat/rest-core
@@ -190,17 +135,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
135
  version: '0'
191
136
  requirements: []
192
137
  rubyforge_project:
193
- rubygems_version: 2.5.1
138
+ rubygems_version: 2.5.2
194
139
  signing_key:
195
140
  specification_version: 4
196
- summary: Modular Ruby clients interface for REST APIs.
141
+ summary: Various [rest-builder](https://github.com/godfat/rest-builder) middleware
197
142
  test_files:
198
143
  - test/test_auth_basic.rb
199
- - test/test_builder.rb
200
144
  - test/test_cache.rb
201
145
  - test/test_clash.rb
202
146
  - test/test_clash_response.rb
203
- - test/test_client.rb
204
147
  - test/test_client_oauth1.rb
205
148
  - test/test_config.rb
206
149
  - test/test_dalli_extension.rb
@@ -211,22 +154,15 @@ test_files:
211
154
  - test/test_error_detector.rb
212
155
  - test/test_error_detector_http.rb
213
156
  - test/test_error_handler.rb
214
- - test/test_event_source.rb
215
157
  - test/test_follow_redirect.rb
216
- - test/test_future.rb
217
- - test/test_httpclient.rb
218
158
  - test/test_json_request.rb
219
159
  - test/test_json_response.rb
220
160
  - test/test_oauth1_header.rb
221
161
  - test/test_oauth2_header.rb
222
162
  - test/test_parse_link.rb
223
- - test/test_payload.rb
224
- - test/test_promise.rb
225
163
  - test/test_query_response.rb
226
164
  - test/test_retry.rb
227
- - test/test_simple.rb
228
165
  - test/test_smash.rb
229
166
  - test/test_smash_response.rb
230
- - test/test_thread_pool.rb
231
167
  - test/test_timeout.rb
232
168
  - test/test_universal.rb
@@ -1,162 +0,0 @@
1
-
2
- require 'thread'
3
- require 'weakref'
4
- require 'rest-core/client'
5
-
6
- class RestCore::Builder
7
- include RestCore
8
-
9
- singleton_class.module_eval do
10
- attr_writer :default_engine
11
- def default_engine
12
- @default_engine ||= RestCore::HttpClient
13
- end
14
-
15
- def client *attrs, &block
16
- new(&block).to_client(*attrs)
17
- end
18
- end
19
-
20
- def initialize &block
21
- @engine = nil
22
- @middles ||= []
23
- instance_eval(&block) if block_given?
24
- end
25
-
26
- attr_reader :middles
27
- attr_writer :default_engine
28
- def default_engine
29
- @default_engine ||= self.class.default_engine
30
- end
31
-
32
- def use middle, *args, &block
33
- middles << [middle, args, block]
34
- end
35
-
36
- def run engine
37
- @engine = engine
38
- end
39
-
40
- def members
41
- middles.map{ |(middle, _, _)|
42
- middle.members if middle.respond_to?(:members)
43
- }.flatten.compact
44
- end
45
-
46
- def to_app engine=@engine || default_engine
47
- # === foldr m.new app middles
48
- middles.reverse.inject(engine.new){ |app, (middle, args, block)|
49
- begin
50
- middle.new(app, *partial_deep_copy(args), &block)
51
- rescue ArgumentError => e
52
- raise ArgumentError.new("#{middle}: #{e}")
53
- end
54
- }
55
- end
56
-
57
- def to_client *attrs
58
- fields = (members + attrs + [:config_engine]).uniq
59
- struct = build_struct(fields)
60
- client = Class.new(struct)
61
- client.const_set('Struct', struct)
62
- class_methods = build_class_methods
63
- client.const_set('ClassMethods', class_methods)
64
- client.singleton_class.send(:include, class_methods)
65
- client.send(:include, Client)
66
- client.builder = self
67
- client.pool_size = 0 # default to no pool
68
- client.pool_idle_time = 60 # default to 60 seconds
69
- client.event_source_class = EventSource
70
- client.promises = []
71
- client.mutex = Mutex.new
72
- client
73
- end
74
-
75
- private
76
- def partial_deep_copy obj
77
- case obj
78
- when Array; obj.map{ |o| partial_deep_copy(o) }
79
- when Hash ; obj.inject({}){ |r, (k, v)| r[k] = partial_deep_copy(v); r }
80
- else ; obj
81
- end
82
- end
83
-
84
- def build_struct fields
85
- if fields.empty?
86
- Struct.new(nil)
87
- else
88
- Struct.new(*fields.uniq)
89
- end
90
- end
91
-
92
- def build_class_methods
93
- Module.new do
94
- attr_accessor :builder, :pool_size, :pool_idle_time,
95
- :event_source_class, :promises, :mutex
96
-
97
- def inherited sub
98
- sub.builder = builder
99
- sub.pool_size = pool_size
100
- sub.pool_idle_time = pool_idle_time
101
- sub.event_source_class = event_source_class
102
- sub.promises = []
103
- sub.mutex = Mutex.new
104
- end
105
-
106
- def thread_pool; RestCore::ThreadPool[self]; end
107
-
108
- def defer returns=:future_body
109
- raise ArgumentError.new('no block given') unless block_given?
110
- promise = RestCore::Promise.new({RestCore::CLIENT => self},
111
- lambda{ |res|
112
- if err = res[FAIL].find{ |f| f.kind_of?(Exception) }
113
- Promise.set_backtrace(err) unless err.backtrace
114
- raise err
115
- else
116
- res
117
- end
118
- })
119
- give_promise(WeakRef.new(promise))
120
- promise.defer do
121
- begin
122
- promise.done(yield)
123
- rescue => e
124
- promise.reject(e)
125
- end
126
- end
127
- promise.send(returns)
128
- end
129
-
130
- def give_promise weak_promise, ps=promises, m=mutex
131
- m.synchronize do
132
- ps << weak_promise
133
- ps.keep_if(&:weakref_alive?)
134
- end
135
- end
136
-
137
- # Shutdown the thread pool for this client and wait for all requests
138
- def shutdown
139
- thread_pool.shutdown
140
- wait
141
- end
142
-
143
- # Wait for all the requests to be done for this client
144
- def wait ps=promises, m=mutex
145
- return self if ps.empty?
146
- current_promises = nil
147
- m.synchronize do
148
- current_promises = ps.dup
149
- ps.clear
150
- end
151
- current_promises.each do |p|
152
- next unless p.weakref_alive?
153
- begin
154
- p.wait
155
- rescue WeakRef::RefError # it's gc'ed after we think it's alive
156
- end
157
- end
158
- wait(ps, m)
159
- end
160
- end
161
- end
162
- end
@@ -1,277 +0,0 @@
1
-
2
- require 'thread'
3
- require 'weakref'
4
- require 'rest-core'
5
-
6
- module RestCore::Client
7
- include RestCore
8
-
9
- Unserializable = [Proc, Method, IO]
10
-
11
- def self.included mod
12
- # honor default attributes
13
- src = mod.members.map{ |name|
14
- <<-RUBY
15
- def #{name}
16
- if (r = super).nil?
17
- self.#{name} = default_#{name}
18
- else
19
- r
20
- end
21
- end
22
-
23
- def default_#{name} a=app
24
- if self.class.respond_to?("default_#{name}")
25
- self.class.default_#{name} # old class default style
26
- elsif a.respond_to?(:#{name})
27
- a.#{name}({}) # middleware instance value
28
- elsif a.respond_to?(:app)
29
- default_#{name}(a.app) # walk into next app
30
- else
31
- nil
32
- end
33
- end
34
- private :default_#{name}
35
- RUBY
36
- }
37
- accessor = Module.new
38
- accessor.module_eval(src.join("\n"), __FILE__, __LINE__)
39
- mod.const_set('Accessor', accessor)
40
- mod.send(:include, accessor)
41
- end
42
-
43
- attr_reader :app, :dry, :promises
44
- attr_accessor :error_callback
45
- def initialize o={}
46
- @app ||= self.class.builder.to_app # lighten! would reinitialize anyway
47
- @dry ||= self.class.builder.to_app(Dry)
48
- @promises = [] # don't record any promises in lighten!
49
- @mutex = nil # for locking promises, lazily initialized
50
- # for serialization
51
- @error_callback = nil
52
- o.each{ |key, value| send("#{key}=", value) if respond_to?("#{key}=") }
53
- end
54
-
55
- def attributes
56
- Hash[each_pair.map{ |k, v| [k, send(k)] }]
57
- end
58
-
59
- def inspect
60
- fields = if size > 0
61
- ' ' + attributes.map{ |k, v|
62
- "#{k}=#{v.inspect.sub(/(?<=.{12}).{4,}/, '...')}"
63
- }.join(', ')
64
- else
65
- ''
66
- end
67
- "#<struct #{self.class.name}#{fields}>"
68
- end
69
-
70
- def lighten! o={}
71
- attributes.each{ |k, v| vv = case v;
72
- when Hash; lighten_hash(v)
73
- when Array; lighten_array(v)
74
- when *Unserializable; nil
75
- else v
76
- end
77
- send("#{k}=", vv)}
78
- initialize(o)
79
- @app, @dry = lighten_app(app), lighten_app(dry)
80
- self
81
- end
82
-
83
- def lighten o={}
84
- dup.lighten!(o)
85
- end
86
-
87
- def wait
88
- self.class.wait(promises, mutex)
89
- self
90
- end
91
-
92
- def url path, query={}, opts={}
93
- dry.call(build_env({
94
- REQUEST_PATH => path,
95
- REQUEST_QUERY => query,
96
- DRY => true}.merge(opts)), &Middleware.method(:request_uri))
97
- end
98
-
99
- def get path, query={}, opts={}, &cb
100
- request(
101
- {REQUEST_METHOD => :get ,
102
- REQUEST_PATH => path ,
103
- REQUEST_QUERY => query }.merge(opts), &cb)
104
- end
105
-
106
- def delete path, query={}, opts={}, &cb
107
- request(
108
- {REQUEST_METHOD => :delete,
109
- REQUEST_PATH => path ,
110
- REQUEST_QUERY => query }.merge(opts), &cb)
111
- end
112
-
113
- def head path, query={}, opts={}, &cb
114
- request(
115
- {REQUEST_METHOD => :head ,
116
- REQUEST_PATH => path ,
117
- REQUEST_QUERY => query ,
118
- RESPONSE_KEY => RESPONSE_HEADERS}.merge(opts), &cb)
119
- end
120
-
121
- def options path, query={}, opts={}, &cb
122
- request(
123
- {REQUEST_METHOD => :options,
124
- REQUEST_PATH => path ,
125
- REQUEST_QUERY => query ,
126
- RESPONSE_KEY => RESPONSE_HEADERS}.merge(opts), &cb)
127
- end
128
-
129
- def post path, payload={}, query={}, opts={}, &cb
130
- request(
131
- {REQUEST_METHOD => :post ,
132
- REQUEST_PATH => path ,
133
- REQUEST_QUERY => query ,
134
- REQUEST_PAYLOAD => payload}.merge(opts), &cb)
135
- end
136
-
137
- def put path, payload={}, query={}, opts={}, &cb
138
- request(
139
- {REQUEST_METHOD => :put ,
140
- REQUEST_PATH => path ,
141
- REQUEST_QUERY => query ,
142
- REQUEST_PAYLOAD => payload}.merge(opts), &cb)
143
- end
144
-
145
- def patch path, payload={}, query={}, opts={}, &cb
146
- request(
147
- {REQUEST_METHOD => :patch ,
148
- REQUEST_PATH => path ,
149
- REQUEST_QUERY => query ,
150
- REQUEST_PAYLOAD => payload}.merge(opts), &cb)
151
- end
152
-
153
- def event_source path, query={}, opts={}
154
- self.class.event_source_class.new(self, path, query, opts)
155
- end
156
-
157
- def request env, a=app
158
- if block_given?
159
- request_full(env, a){ |response| yield(response[response_key(env)]) }
160
- else
161
- request_full(env, a)[response_key(env)]
162
- end
163
- end
164
-
165
- def request_full env, a=app, &k
166
- response = a.call(build_env({ASYNC => !!k}.merge(env))) do |res|
167
- (k || RC.id).call(request_complete(res))
168
- end
169
-
170
- give_promise(response)
171
-
172
- if block_given?
173
- self
174
- else
175
- response
176
- end
177
- end
178
-
179
- def give_promise response
180
- # under ASYNC callback, response might not be a response hash
181
- # in that case (maybe in a user created engine), Client#wait
182
- # won't work because we have no way to track the promise.
183
- if response.kind_of?(Hash) && response[PROMISE].kind_of?(Promise)
184
- weak_promise = WeakRef.new(response[PROMISE])
185
- self.class.give_promise(weak_promise)
186
- self.class.give_promise(weak_promise, promises, mutex)
187
- end
188
-
189
- response
190
- end
191
-
192
- def build_env env={}
193
- default_env.merge(
194
- Middleware.string_keys(attributes).merge(Middleware.string_keys(env)))
195
- end
196
-
197
- def default_env
198
- {REQUEST_METHOD => :get,
199
- REQUEST_PATH => '/' ,
200
- REQUEST_QUERY => {} ,
201
- REQUEST_PAYLOAD => {} ,
202
- REQUEST_HEADERS => {} ,
203
- FAIL => [] ,
204
- LOG => [] ,
205
- CLIENT => self}
206
- end
207
- # ------------------------ instance ---------------------
208
-
209
-
210
-
211
- private
212
- def request_complete res
213
- if err = res[FAIL].find{ |f| f.kind_of?(Exception) }
214
- Promise.set_backtrace(err) unless err.backtrace
215
- error_callback.call(err) if error_callback
216
- if res[ASYNC]
217
- res.merge(response_key(res) => err)
218
- else
219
- raise err
220
- end
221
- else
222
- res
223
- end
224
- end
225
-
226
- def mutex
227
- @mutex ||= Mutex.new
228
- end
229
-
230
- def response_key opts
231
- opts[RESPONSE_KEY] ||
232
- if opts[HIJACK] then RESPONSE_SOCKET else RESPONSE_BODY end
233
- end
234
-
235
- def lighten_hash hash
236
- Hash[hash.map{ |(key, value)|
237
- case value
238
- when Hash; lighten_hash(value)
239
- when Array; lighten_array(value)
240
- when *Unserializable; [key, nil]
241
- else [key, value]
242
- end
243
- }]
244
- end
245
-
246
- def lighten_array array
247
- array.map{ |value|
248
- case value
249
- when Hash; lighten_hash(value)
250
- when Array; lighten_array(value)
251
- when *Unserializable; nil
252
- else value
253
- end
254
- }.compact
255
- end
256
-
257
- def lighten_app app
258
- members = if app.class.respond_to?(:members)
259
- app.class.members.map{ |key|
260
- case value = app.send(key, {})
261
- when Hash; lighten_hash(value)
262
- when Array; lighten_array(value)
263
- when *Unserializable; nil
264
- else value
265
- end
266
- }
267
- else
268
- []
269
- end
270
-
271
- if app.respond_to?(:app) && app.app
272
- app.class.new(lighten_app(app.app), *members)
273
- else
274
- app.class.new(*members)
275
- end
276
- end
277
- end