rosarium 0.1.6 → 0.1.7
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/lib/rosarium/promise.rb +86 -105
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3789051cf47569f1729bb161433ecb033274b49833e774eec788e5884c490897
|
4
|
+
data.tar.gz: f48ef4f93bc8cadb68d9069d3dd3f8434b45ce43e6f3057918912d97d72f5432
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e108887ddb2cdee8bc0e5abe53915e249028d5f367a7c617874460a4b7b5ec19ca04c364631e3b6235c0da80c2ae2951501e08c6b280dd2609455bdbe9f7858
|
7
|
+
data.tar.gz: 7622eab1b92fcee040b91394422f8b7f1f2c78be004c62988d5e588bf528ab6718da0bc97d3adb8b24022b22498d80843e31c051b5b83ed2f4fed308ff288370
|
data/lib/rosarium/promise.rb
CHANGED
@@ -3,20 +3,20 @@
|
|
3
3
|
module Rosarium
|
4
4
|
class Promise
|
5
5
|
|
6
|
-
DEFAULT_ON_FULFILL = proc { |value| value }
|
7
|
-
DEFAULT_ON_REJECT = proc { |reason| raise reason }
|
8
|
-
|
9
6
|
private_class_method :new
|
10
7
|
|
11
8
|
def self.defer
|
12
9
|
promise = new
|
13
10
|
|
14
|
-
resolver =
|
11
|
+
resolver = lambda do |value|
|
12
|
+
promise.send(:try_settle, value, nil)
|
13
|
+
nil # do not leak
|
14
|
+
end
|
15
15
|
|
16
16
|
rejecter = lambda do |reason|
|
17
17
|
raise "reason must be an Exception" unless reason.is_a?(Exception)
|
18
|
-
|
19
18
|
promise.send(:try_settle, nil, reason)
|
19
|
+
nil # do not leak
|
20
20
|
end
|
21
21
|
|
22
22
|
Deferred.new(promise, resolver, rejecter)
|
@@ -57,7 +57,7 @@ module Rosarium
|
|
57
57
|
end
|
58
58
|
|
59
59
|
promises.each do |promise|
|
60
|
-
promise.
|
60
|
+
promise.send(:when_settled, &check)
|
61
61
|
end
|
62
62
|
|
63
63
|
deferred.promise
|
@@ -72,60 +72,27 @@ module Rosarium
|
|
72
72
|
waiting_for = promises.count
|
73
73
|
mutex = Mutex.new
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
check = lambda do |promise|
|
76
|
+
if promise.fulfilled?
|
77
|
+
# Hits zero iff all promises were fulfilled
|
78
|
+
if mutex.synchronize { (waiting_for -= 1) == 0 }
|
79
|
+
deferred.resolve(promises.map(&:value))
|
80
|
+
end
|
81
|
+
else
|
82
|
+
deferred.reject(promise.reason)
|
80
83
|
end
|
81
84
|
end
|
82
85
|
|
83
86
|
promises.each do |promise|
|
84
|
-
promise.
|
85
|
-
end
|
86
|
-
|
87
|
-
deferred.promise
|
88
|
-
end
|
89
|
-
|
90
|
-
def then(on_rejected = nil, &on_fulfilled)
|
91
|
-
deferred = self.class.defer
|
92
|
-
|
93
|
-
on_fulfilled ||= DEFAULT_ON_FULFILL
|
94
|
-
on_rejected ||= DEFAULT_ON_REJECT
|
95
|
-
|
96
|
-
when_settled do
|
97
|
-
EXECUTOR.submit do
|
98
|
-
begin
|
99
|
-
deferred.resolve(
|
100
|
-
if fulfilled?
|
101
|
-
# User-supplied code
|
102
|
-
on_fulfilled.call value
|
103
|
-
else
|
104
|
-
# User-supplied code
|
105
|
-
on_rejected.call reason
|
106
|
-
end
|
107
|
-
)
|
108
|
-
rescue Exception => e
|
109
|
-
deferred.reject e
|
110
|
-
end
|
111
|
-
end
|
87
|
+
promise.send(:when_settled) { check.call(promise) }
|
112
88
|
end
|
113
89
|
|
114
90
|
deferred.promise
|
115
91
|
end
|
116
92
|
|
117
|
-
def rescue(&block)
|
118
|
-
self.then(block)
|
119
|
-
end
|
120
|
-
|
121
|
-
alias catch rescue
|
122
|
-
alias on_error rescue
|
123
|
-
|
124
|
-
public
|
125
|
-
|
126
93
|
def initialize
|
127
94
|
@state = :pending
|
128
|
-
@
|
95
|
+
@settling = false
|
129
96
|
@mutex = Mutex.new
|
130
97
|
@condition = ConditionVariable.new
|
131
98
|
@when_settled = []
|
@@ -136,15 +103,23 @@ module Rosarium
|
|
136
103
|
end
|
137
104
|
|
138
105
|
def value
|
139
|
-
|
106
|
+
wait_until_settled
|
140
107
|
synchronize { @value }
|
141
108
|
end
|
142
109
|
|
143
110
|
def reason
|
144
|
-
|
111
|
+
wait_until_settled
|
145
112
|
synchronize { @reason }
|
146
113
|
end
|
147
114
|
|
115
|
+
def value!
|
116
|
+
wait_until_settled
|
117
|
+
synchronize do
|
118
|
+
raise @reason if @state == :rejected
|
119
|
+
@value
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
148
123
|
def inspect
|
149
124
|
synchronize do
|
150
125
|
r = { state: @state }
|
@@ -162,24 +137,43 @@ module Rosarium
|
|
162
137
|
state == :rejected
|
163
138
|
end
|
164
139
|
|
165
|
-
def
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
140
|
+
def then(on_rejected = nil, &on_fulfilled)
|
141
|
+
deferred = self.class.defer
|
142
|
+
|
143
|
+
when_settled do
|
144
|
+
EXECUTOR.submit do
|
145
|
+
begin
|
146
|
+
deferred.resolve(
|
147
|
+
if fulfilled?
|
148
|
+
# User-supplied code
|
149
|
+
on_fulfilled ? on_fulfilled.call(value) : value
|
150
|
+
else
|
151
|
+
# User-supplied code
|
152
|
+
on_rejected ? on_rejected.call(reason) : raise(reason)
|
153
|
+
end
|
154
|
+
)
|
155
|
+
rescue Exception => e
|
156
|
+
deferred.reject e
|
157
|
+
end
|
158
|
+
end
|
170
159
|
end
|
160
|
+
|
161
|
+
deferred.promise
|
171
162
|
end
|
172
163
|
|
173
|
-
|
164
|
+
def rescue(&block)
|
165
|
+
self.then(block)
|
166
|
+
end
|
174
167
|
|
175
|
-
|
176
|
-
|
177
|
-
synchronize { @condition.broadcast }
|
178
|
-
end
|
168
|
+
alias catch rescue
|
169
|
+
alias on_error rescue
|
179
170
|
|
171
|
+
private
|
172
|
+
|
173
|
+
def wait_until_settled
|
180
174
|
synchronize do
|
181
175
|
loop do
|
182
|
-
return if @state
|
176
|
+
return if @state != :pending
|
183
177
|
@condition.wait @mutex
|
184
178
|
end
|
185
179
|
end
|
@@ -189,68 +183,55 @@ module Rosarium
|
|
189
183
|
@mutex.synchronize(&block)
|
190
184
|
end
|
191
185
|
|
186
|
+
# Can be called more than once
|
192
187
|
def try_settle(value, reason)
|
193
|
-
|
194
|
-
add_when_settled = false
|
188
|
+
settle_with = nil
|
195
189
|
|
196
190
|
synchronize do
|
197
|
-
if @state
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
@when_settled.clear
|
206
|
-
else
|
207
|
-
@reason = reason
|
208
|
-
@state = :rejected
|
209
|
-
callbacks.concat @when_settled
|
210
|
-
@when_settled.clear
|
211
|
-
end
|
191
|
+
return if @state != :pending || @settling
|
192
|
+
|
193
|
+
if value.is_a? Promise
|
194
|
+
@settling = true
|
195
|
+
elsif reason.nil?
|
196
|
+
settle_with = [value, nil]
|
197
|
+
else
|
198
|
+
settle_with = [nil, reason]
|
212
199
|
end
|
213
200
|
end
|
214
201
|
|
215
|
-
|
216
|
-
|
217
|
-
|
202
|
+
if settle_with
|
203
|
+
settle(*settle_with)
|
204
|
+
else
|
205
|
+
value.when_settled do
|
206
|
+
if value.fulfilled?
|
207
|
+
settle(value.value, nil)
|
208
|
+
else
|
209
|
+
settle(nil, value.reason)
|
210
|
+
end
|
211
|
+
end
|
218
212
|
end
|
219
|
-
# rubocop:enable Style/IfUnlessModifier
|
220
|
-
|
221
|
-
callbacks.each { |c| EXECUTOR.submit(&c) }
|
222
213
|
end
|
223
214
|
|
224
|
-
|
225
|
-
|
226
|
-
|
215
|
+
# Only called once
|
216
|
+
def settle(value, reason)
|
227
217
|
synchronize do
|
228
|
-
@
|
229
|
-
@
|
230
|
-
@
|
231
|
-
@
|
232
|
-
|
233
|
-
|
234
|
-
end
|
235
|
-
|
236
|
-
callbacks.each { |c| EXECUTOR.submit(&c) }
|
218
|
+
@state = (reason ? :rejected : :fulfilled)
|
219
|
+
@value = value
|
220
|
+
@reason = reason
|
221
|
+
@condition.broadcast
|
222
|
+
@when_settled.slice!(0, @when_settled.length)
|
223
|
+
end.each(&:call)
|
237
224
|
end
|
238
225
|
|
239
226
|
protected
|
240
227
|
|
241
228
|
def when_settled(&block)
|
242
229
|
immediate = synchronize do
|
243
|
-
|
244
|
-
|
245
|
-
else
|
246
|
-
@when_settled << block
|
247
|
-
false
|
248
|
-
end
|
230
|
+
@when_settled << block if @state == :pending
|
231
|
+
@state != :pending
|
249
232
|
end
|
250
233
|
|
251
234
|
block.call if immediate
|
252
|
-
|
253
|
-
nil
|
254
235
|
end
|
255
236
|
|
256
237
|
@resolved = resolve(nil)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rosarium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rachel Evans
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -64,7 +64,7 @@ homepage: http://rve.org.uk/gems/rosarium
|
|
64
64
|
licenses:
|
65
65
|
- Apache-2.0
|
66
66
|
metadata: {}
|
67
|
-
post_install_message:
|
67
|
+
post_install_message:
|
68
68
|
rdoc_options: []
|
69
69
|
require_paths:
|
70
70
|
- lib
|
@@ -79,8 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
|
-
rubygems_version: 3.0.
|
83
|
-
signing_key:
|
82
|
+
rubygems_version: 3.0.3
|
83
|
+
signing_key:
|
84
84
|
specification_version: 4
|
85
85
|
summary: Promises, or something like them
|
86
86
|
test_files: []
|