restify 0.3.2.1.b74 → 0.4.0.b1

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YzIwYWY3ZGYxMGQ0OGNkMGQ0ODNkYzY2NzRhMjdiZTMyMDhmN2Y1Yg==
5
- data.tar.gz: !binary |-
6
- YjU2NmZiYWM3MWFkY2RhY2YzMDhlYjFiZDQ2OTBkYzhmYmZjNGMzOQ==
2
+ SHA1:
3
+ metadata.gz: eaa7426d42906e309c899eb7b59b1d3f4b98284a
4
+ data.tar.gz: 494b9841c5a3424157c7d75771cd6fa177277e25
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NTVmNDdiNWUyNmI4ZmUzMTMwNzU4MDQ2YzZkNDVlZmUwNWRiYWIxZDhhNzBm
10
- ZjlhODIzN2ZhOGYyNWNiNWJlMmNlYWY2MjAxYzFiOTE4NDY0NjYzZjMyOTVl
11
- NjY0OGM5Y2ZhYTAyYWYyNGM0YTc3NDI5ZjQzYWExMDMyZmY2NDE=
12
- data.tar.gz: !binary |-
13
- ZjZiOWQ3M2JmZTU3ZWFhOTU1NDdjYmJkNWNhNWNmOWE4YjFiZTNiZWJkZTEw
14
- Mjk1YTc3MzY4NzFiMTBmMTEzMThhOTQ4YWZmMGM1ODQ3Yzg2MjNhNWE5NjYz
15
- MDA4NWQxMjEzOWFmYmRkNDVhMzk4MDM2OGY3Yjk0MzMzZjJiODc=
6
+ metadata.gz: 627086929d8b537b952e4f498c98e62c1609f635e7b7049b70ba0d4a0a9f05da6dacf699c4e290a527688fb12fd79128cac084abf77fd4a3aba2274d904923e7
7
+ data.tar.gz: 36f9848d1585898e5a6ab343c053fb62958c6b701d4ac3e5e43de9be6d097bd6cf32b7e2c1d801495ab2df7eea0a2b01a3f85f7960f2a59187d9220d8d940497
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## master
2
+
3
+ * Drop obligation in favor of simple Concurrent::IVar based promise class.
4
+ Notable changes:
5
+ - Returned object us of type `Restify::Promise` now.
6
+ - `value` will not raise exception but return `nil` in case of failure. Use `value!` for old behavior.
data/README.md CHANGED
@@ -8,16 +8,14 @@ Restify can be used to consume hypermedia REST APIs (like GitHubs), to build a s
8
8
 
9
9
  Restify is build upon the following libraries:
10
10
 
11
- * [obligation](https://github.com/jgraichen/obligation)
12
11
  * [addressable](https://github.com/sporkmonger/addressable)
12
+ * [typhoeus](https://github.com/typhoeus/typhoeus)
13
13
 
14
- It provides HTTP adapters to use with:
14
+ It has optional HTTP adapters using:
15
15
 
16
16
  * [em-http-request](https://github.com/igrigorik/em-http-request)
17
- * [celluloid-io](https://github.com/celluloid/celluloid-io) / [http](https://github.com/httprb/http) (experimental)
18
- * [typhoeus](https://github.com/typhoeus/typhoeus) (not widely tested)
19
17
 
20
- They are mostly run in a background thread and may not survive mid-application forks.
18
+ The HTTP adapters are mostly run in a background thread and may not survive mid-application forks.
21
19
 
22
20
  Included processors can handle:
23
21
 
@@ -44,21 +42,55 @@ Add it to your Gemfile or install it manually: `$ gem install restify`
44
42
 
45
43
  ## Usage
46
44
 
47
- Create new Restify object (actually returns '/' resource):
45
+ Create new Restify object. It essentially means to request some start-resource usually the "root" resource:
48
46
 
49
47
  ```ruby
50
- client = Restify.new('http://api.github.com').value
48
+ client = Restify.new('https://api.github.com').get.value
49
+ # => {"current_user_url"=>"https://api.github.com/user",
50
+ # "current_user_authorizations_html_url"=>"https://github.com/settings/connections/applications{/client_id}",
51
+ # ...
52
+ # "repository_url"=>"https://api.github.com/repos/{owner}/{repo}",
53
+ # ...
51
54
  ```
52
55
 
53
- The `value` call resolves the returned `Obligation` (like a Future object) by blocking the thread until the resource is there.
56
+ We are essentially requesting `'http://api.github.com'` via HTTP `get`. `get` is returning an `Promise`, similar to Java's `Future`. The `value` call resolves the returned `Promise` by blocking the thread until the resource is actually there. `value!` will additionally raise errors instead of returning `nil`. You can chain handlers using the `then` method. This allows you to be build a dependency chain that will be executed when the last promise is needed.
54
57
 
55
- Get a relation described by the root resource. Restify supports Link headers as well as JSON encoded relations (`*_url` fields).
58
+ As we can see GitHub returns us a field `repository_url` with a URI template. Restify automatically scans for `*_url` fields in the JSON response and exposes these as relations. It additionally scans the HTTP Header field `Link` for relations like pagination.
59
+
60
+ We can now use the relations to navigate from resource to resource like a browser from one web page to another page.
56
61
 
57
62
  ```ruby
58
63
  repositories = client.rel(:repository)
64
+ # => #<Restify::Relation:0x00000005548968 @context=#<Restify::Context:0x007f6024066ae0 @uri=#<Addressable::URI:0x29d8684 URI:https://api.github.com>>, @template=#<Addressable::Template:0x2aa44a0 PATTERN:https://api.github.com/repos/{owner}/{repo}>>
65
+ ```
66
+
67
+ This gets us the relation named `repository` that we can request now. The usual HTTP methods are available on a relation:
68
+
69
+ ```ruby
70
+ def get(params = {})
71
+ request :get, nil, params
72
+ end
73
+
74
+ def delete(params = {})
75
+ request :delete, nil, params
76
+ end
77
+
78
+ def post(data = {}, params = {})
79
+ request :post, data, params
80
+ end
81
+
82
+ def put(data = {}, params = {})
83
+ request :put, data, params
84
+ end
85
+
86
+ def patch(data = {}, params = {})
87
+ request :patch, data, params
88
+ end
59
89
  ```
60
90
 
61
- Send a GET request for a specific repository using given parameters. They will be used to expand the URI template behind the `repositories` relation.
91
+ URL templates can define some parameters such as `{owner}` or `{repo}`. They will be expanded from the `params` given to the HTTP method method.
92
+
93
+ Now send a GET request with some parameters to request a specific repository:
62
94
 
63
95
  ```ruby
64
96
  repo = repositories.get(owner: 'jgraichen', repo: 'restify').value
data/lib/restify.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  require 'restify/version'
2
2
 
3
3
  require 'hashie'
4
- require 'obligation'
4
+ require 'concurrent'
5
5
  require 'addressable/uri'
6
6
  require 'addressable/template'
7
7
 
8
8
  #
9
9
  module Restify
10
10
  require 'restify/error'
11
+ require 'restify/promise'
11
12
 
12
13
  require 'restify/context'
13
14
  require 'restify/resource'
@@ -26,7 +27,7 @@ module Restify
26
27
 
27
28
  class << self
28
29
  def new(uri, opts = {})
29
- Relation.new Context.new(uri), uri
30
+ Relation.new Context.new(uri, opts), uri
30
31
  end
31
32
 
32
33
  def adapter
@@ -106,7 +106,7 @@ module Restify
106
106
  end
107
107
 
108
108
  def call(request)
109
- Obligation.create do |writer|
109
+ Promise.create do |writer|
110
110
  next_tick do
111
111
  Connection.open(request.uri).call(request, writer)
112
112
  end
@@ -32,7 +32,7 @@ module Restify
32
32
  end
33
33
 
34
34
  def call(request)
35
- Obligation.create do |writer|
35
+ Promise.create do |writer|
36
36
  queue request, writer
37
37
  end
38
38
  end
@@ -12,8 +12,9 @@ module Restify
12
12
  #
13
13
  attr_reader :uri
14
14
 
15
- def initialize(uri)
15
+ def initialize(uri, opts = {})
16
16
  @uri = uri.is_a?(Addressable::URI) ? uri : Addressable::URI.parse(uri.to_s)
17
+ @opts = opts
17
18
  end
18
19
 
19
20
  def join(uri)
@@ -21,7 +22,7 @@ module Restify
21
22
  end
22
23
 
23
24
  def process(response)
24
- context = Context.new response.uri
25
+ context = Context.new response.uri, @opts
25
26
  processor = Restify::PROCESSORS.find { |p| p.accept? response }
26
27
  processor ||= Restify::Processors::Base
27
28
 
@@ -29,7 +30,11 @@ module Restify
29
30
  end
30
31
 
31
32
  def request(method, uri, data = nil, opts = {})
32
- request = Request.new method: method, uri: join(uri), data: data
33
+ request = Request.new \
34
+ method: method,
35
+ uri: join(uri),
36
+ data: data,
37
+ headers: @opts.fetch(:headers, {})
33
38
 
34
39
  Restify.adapter.call(request).then do |response|
35
40
  if response.success?
@@ -0,0 +1,93 @@
1
+ module Restify
2
+ #
3
+ class Promise < Concurrent::IVar
4
+ def initialize(*dependencies, &task)
5
+ @task = task || proc { |*args| args }
6
+ @dependencies = dependencies.flatten
7
+
8
+ super(&nil)
9
+ end
10
+
11
+ def wait(timeout = nil)
12
+ if @dependencies.any? && pending?
13
+ execute
14
+ end
15
+
16
+ super
17
+ end
18
+
19
+ def then(&block)
20
+ Promise.new([self], &block)
21
+ end
22
+
23
+ def execute
24
+ synchronize { ns_execute }
25
+ end
26
+
27
+ protected
28
+
29
+ # @!visibility private
30
+ def ns_execute
31
+ return unless pending?
32
+
33
+ executor = Concurrent::SafeTaskExecutor.new \
34
+ method(:eval_dependencies), rescue_exception: true
35
+ success, value, reason = executor.execute(@dependencies)
36
+
37
+ if success
38
+ ns_execute_task(*value)
39
+ else
40
+ complete false, nil, reason
41
+ end
42
+ end
43
+
44
+ # @!visibility private
45
+ def ns_execute_task(*args)
46
+ if compare_and_set_state(:processing, :pending)
47
+ success, value, reason = Concurrent::SafeTaskExecutor.new(@task, rescue_exception: true).execute(*args)
48
+
49
+ while success && value.is_a?(Concurrent::IVar)
50
+ success, value, reason = value.wait, value.value, value.reason
51
+ end
52
+
53
+ complete success, value, reason
54
+ end
55
+ end
56
+
57
+ # @!visibility private
58
+ def eval_dependencies(dependencies)
59
+ dependencies.map(&method(:eval_dependency))
60
+ end
61
+
62
+ # @!visibility private
63
+ def eval_dependency(dependency)
64
+ if dependency.is_a? Concurrent::IVar
65
+ eval_dependency dependency.value!
66
+ else
67
+ dependency
68
+ end
69
+ end
70
+
71
+ class << self
72
+ def create
73
+ promise = Promise.new
74
+ yield Writer.new(promise)
75
+ promise
76
+ end
77
+ end
78
+
79
+ class Writer
80
+ def initialize(promise)
81
+ @promise = promise
82
+ end
83
+
84
+ def fulfill(value)
85
+ @promise.send :complete, true, value, nil
86
+ end
87
+
88
+ def reject(reason)
89
+ @promise.send :complete, false, nil, reason
90
+ end
91
+ end
92
+ end
93
+ end
@@ -18,10 +18,16 @@ module Restify
18
18
  #
19
19
  attr_reader :data
20
20
 
21
+ # Request headers
22
+ #
23
+ attr_reader :headers
24
+
21
25
  def initialize(opts = {})
22
- @method = opts.fetch(:method, :get).downcase
23
- @uri = opts.fetch(:uri) { raise ArgumentError.new ':uri required.' }
24
- @data = opts.fetch(:data, nil)
26
+ @method = opts.fetch(:method, :get).downcase
27
+ @uri = opts.fetch(:uri) { raise ArgumentError.new ':uri required.' }
28
+ @data = opts.fetch(:data, nil)
29
+ @headers = opts.fetch(:headers, {}).merge \
30
+ 'Content-Type' => 'application/json'
25
31
  end
26
32
 
27
33
  def body
@@ -29,11 +35,5 @@ module Restify
29
35
  JSON.dump(data) unless data.nil?
30
36
  end
31
37
  end
32
-
33
- def headers
34
- {
35
- 'Content-Type' => 'application/json'
36
- }
37
- end
38
38
  end
39
39
  end
@@ -1,9 +1,9 @@
1
1
  module Restify
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 3
5
- PATCH = 2
6
- STAGE = nil
4
+ MINOR = 4
5
+ PATCH = 0
6
+ STAGE = 'b1'.freeze
7
7
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.').freeze
8
8
 
9
9
  def self.to_s
data/restify.gemspec CHANGED
@@ -18,9 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_runtime_dependency 'obligation', '~> 0.1'
21
+ spec.add_runtime_dependency 'concurrent-ruby', '~> 0.9.0'
22
22
  spec.add_runtime_dependency 'addressable', '~> 2.3'
23
23
  spec.add_runtime_dependency 'typhoeus'
24
+ spec.add_runtime_dependency 'net-http-persistent'
24
25
  spec.add_runtime_dependency 'hashie', '~> 3.3'
25
26
  spec.add_runtime_dependency 'rack'
26
27
 
data/spec/restify_spec.rb CHANGED
@@ -117,22 +117,22 @@ describe Restify do
117
117
  expect(users_relation).to be_a Restify::Relation
118
118
 
119
119
  # Let's create a user first.
120
- # This method returns instantly and returns an `Obligation`.
121
- # This `Obligation` represents the future value.
120
+ # This method returns instantly and returns a `Promise`.
121
+ # This `Promise` represents the future value.
122
122
  # We can pass parameters to a request. They will be used
123
123
  # to expand the URI template behind the relation. Additional
124
124
  # fields will be encoding in e.g. JSON and send if not a GET
125
125
  # request.
126
126
  create_user_promise = users_relation.post
127
- expect(create_user_promise).to be_a Obligation
127
+ expect(create_user_promise).to be_a Restify::Promise
128
128
 
129
129
  # We can do other things while the request is processed in
130
130
  # the background. When we need the response with can call
131
131
  # {#value} on the promise that will block the thread until
132
132
  # the result is here.
133
- begin
134
- create_user_promise.value
135
- rescue Restify::ClientError => e
133
+ expect { create_user_promise.value! }.to \
134
+ raise_error(Restify::ClientError) do |e|
135
+
136
136
  # Because we forgot to send a "name" the server complains
137
137
  # with an error code that will lead to a raised error.
138
138
 
@@ -187,37 +187,5 @@ describe Restify do
187
187
  expect(blurb[:image]).to eq 'http://example.org/avatar.png'
188
188
  end
189
189
  end
190
-
191
- context 'within eventmachine' do
192
- it 'should consume the API' do
193
- skip
194
-
195
- EventMachine.run do
196
- users_promise = c.rel(:users).get
197
- users_promise.then do |users|
198
- expect(users).to have(2).items
199
-
200
- user = users.first
201
- expect(user).to have_key :name
202
- expect(user[:name]).to eq 'John Smith'
203
- expect(user).to have_relation :self
204
- expect(user).to have_relation :blurb
205
-
206
- user.rel(:blurb).get
207
- end.then do |blurb|
208
- expect(blurb).to have_key :title
209
- expect(blurb).to have_key :image
210
-
211
- expect(blurb[:title]).to eq 'Prof. Dr. John Smith'
212
- expect(blurb[:image]).to eq 'http://example.org/avatar.png'
213
-
214
- EventMachine.stop
215
- @done = true
216
- end
217
- end
218
-
219
- expect(@done).to be true
220
- end
221
- end
222
190
  end
223
191
  end
data/spec/spec_helper.rb CHANGED
@@ -17,9 +17,6 @@ case ENV['ADAPTER'].to_s.downcase
17
17
  when 'typhoeus'
18
18
  require 'restify/adapter/typhoeus'
19
19
  Restify.adapter = Restify::Adapter::Typhoeus.new
20
- when 'celluloid'
21
- require 'restify/adapter/celluloid'
22
- Restify.adapter = Restify::Adapter::Celluloid.new
23
20
  else
24
21
  raise "Invalid adapter: #{ENV['ADAPTER']}"
25
22
  end if ENV['ADAPTER']
metadata CHANGED
@@ -1,97 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2.1.b74
4
+ version: 0.4.0.b1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-08 00:00:00.000000000 Z
11
+ date: 2015-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: obligation
14
+ name: concurrent-ruby
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.1'
19
+ version: 0.9.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.1'
26
+ version: 0.9.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: addressable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '2.3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: typhoeus
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-http-persistent
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: hashie
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - ~>
73
+ - - "~>"
60
74
  - !ruby/object:Gem::Version
61
75
  version: '3.3'
62
76
  type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - ~>
80
+ - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: '3.3'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rack
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ! '>='
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ! '>='
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: bundler
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ~>
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
103
  version: '1.5'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ~>
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: '1.5'
97
111
  description: An experimental hypermedia REST client that uses parallel, keep-alive
@@ -102,10 +116,10 @@ executables: []
102
116
  extensions: []
103
117
  extra_rdoc_files: []
104
118
  files:
119
+ - CHANGELOG.md
105
120
  - LICENSE.txt
106
121
  - README.md
107
122
  - lib/restify.rb
108
- - lib/restify/adapter/celluloid.rb
109
123
  - lib/restify/adapter/em.rb
110
124
  - lib/restify/adapter/typhoeus.rb
111
125
  - lib/restify/context.rb
@@ -113,6 +127,7 @@ files:
113
127
  - lib/restify/link.rb
114
128
  - lib/restify/processors/base.rb
115
129
  - lib/restify/processors/json.rb
130
+ - lib/restify/promise.rb
116
131
  - lib/restify/relation.rb
117
132
  - lib/restify/request.rb
118
133
  - lib/restify/resource.rb
@@ -125,7 +140,6 @@ files:
125
140
  - spec/restify/resource_spec.rb
126
141
  - spec/restify_spec.rb
127
142
  - spec/spec_helper.rb
128
- - spec/support/hack_causes.rb
129
143
  homepage: https://github.com/jgraichen/restify
130
144
  licenses:
131
145
  - LGPLv3
@@ -136,17 +150,17 @@ require_paths:
136
150
  - lib
137
151
  required_ruby_version: !ruby/object:Gem::Requirement
138
152
  requirements:
139
- - - ! '>='
153
+ - - ">="
140
154
  - !ruby/object:Gem::Version
141
155
  version: '0'
142
156
  required_rubygems_version: !ruby/object:Gem::Requirement
143
157
  requirements:
144
- - - ! '>'
158
+ - - ">"
145
159
  - !ruby/object:Gem::Version
146
160
  version: 1.3.1
147
161
  requirements: []
148
162
  rubyforge_project:
149
- rubygems_version: 2.4.5
163
+ rubygems_version: 2.4.8
150
164
  signing_key:
151
165
  specification_version: 4
152
166
  summary: An experimental hypermedia REST client.
@@ -157,4 +171,4 @@ test_files:
157
171
  - spec/restify/resource_spec.rb
158
172
  - spec/restify_spec.rb
159
173
  - spec/spec_helper.rb
160
- - spec/support/hack_causes.rb
174
+ has_rdoc:
@@ -1,36 +0,0 @@
1
- require 'celluloid/io'
2
- require 'http'
3
-
4
- module Restify
5
- #
6
- module Adapter
7
- #
8
- class Celluloid
9
- include ::Celluloid::IO
10
-
11
- def process(request, writer)
12
- response = ::HTTP
13
- .headers(request.headers)
14
- .send request.method.downcase,
15
- request.uri.to_s,
16
- body: request.body,
17
- socket_class: ::Celluloid::IO::TCPSocket
18
-
19
- uri = response.uri
20
- status = response.status.code
21
- body = response.body.to_s
22
- headers = response.headers.to_h.each_with_object({}) do |header, hash|
23
- hash[header[0].upcase.tr('-', '_')] = header[1]
24
- end
25
-
26
- writer.fulfill Response.new request, uri, status, headers, body
27
- end
28
-
29
- def call(request)
30
- Obligation.create do |writer|
31
- async.process request, writer
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,14 +0,0 @@
1
-
2
- class Obligation::RejectedError
3
- def backtrace
4
- if cause
5
- if (sup = super).nil?
6
- sup
7
- else
8
- super + ["==== caused by #{cause.class}: #{cause}"] + cause.backtrace
9
- end
10
- else
11
- super
12
- end
13
- end
14
- end