delayer-deferred 1.0.4 → 1.1.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.
- checksums.yaml +4 -4
- data/Rakefile +8 -0
- data/delayer-deferred.gemspec +1 -0
- data/lib/delayer/deferred/deferred.rb +16 -0
- data/lib/delayer/deferred/deferredable.rb +89 -26
- data/lib/delayer/deferred/error.rb +13 -0
- data/lib/delayer/deferred/result_container.rb +11 -0
- data/lib/delayer/deferred/thread.rb +27 -21
- data/lib/delayer/deferred/tools.rb +9 -4
- data/lib/delayer/deferred/version.rb +1 -1
- data/test/deferred_benchmark.rb +63 -0
- data/test/deferred_profiler.rb +28 -0
- data/test/deferred_test.rb +52 -5
- data/test/thread_test.rb +67 -2
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17fb3ffd22cfc243b60926a084efa91b6f9dee15
|
4
|
+
data.tar.gz: f73bcf244106e7699719884d36d374d52be94080
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac64243c4a9440c32086bb99a94de79339b57f2aca5c57f2f068249d7adc9ac09736c09d7e8ccca220acbc52157c843eba3be63fe8577b1cd1e21b6f0cdbbc86
|
7
|
+
data.tar.gz: 7ec556c87dad8a807a1d9e2318678f3f5fd95dd5accab5c18228194902ac4cc22b85eae1d39cb913f28cffda006bc22751b72306938ee82453be65b9cb918293
|
data/Rakefile
CHANGED
data/delayer-deferred.gemspec
CHANGED
@@ -49,5 +49,21 @@ module Delayer::Deferred
|
|
49
49
|
sprintf("#<%s: %p stat:%s value:%s>".freeze, self.class, object_id, @next_call_stat.inspect, @next_call_value.inspect)
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
def self.fiber(&block)
|
54
|
+
@_fiber ||= Fiber.new do |b|
|
55
|
+
loop do
|
56
|
+
b = Fiber.yield(b.())
|
57
|
+
end
|
58
|
+
end
|
59
|
+
result = @_fiber.resume(block)
|
60
|
+
if result.is_a?(Delayer::Deferred::ResultContainer)
|
61
|
+
result
|
62
|
+
else
|
63
|
+
_fiber = @_fiber
|
64
|
+
@_fiber = nil
|
65
|
+
return result, _fiber
|
66
|
+
end
|
67
|
+
end
|
52
68
|
end
|
53
69
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require "delayer/deferred/version"
|
3
|
+
require "delayer/deferred/result_container"
|
3
4
|
|
4
5
|
# なんでもDeferred
|
5
6
|
module Delayer::Deferred::Deferredable
|
6
7
|
Callback = Struct.new(*%i<ok ng backtrace>)
|
7
|
-
BackTrace = Struct.new(*%i<ok ng>)
|
8
8
|
CallbackDefaultOK = lambda{ |x| x }
|
9
9
|
CallbackDefaultNG = lambda{ |err| Delayer::Deferred.fail(err) }
|
10
10
|
|
@@ -28,16 +28,27 @@ module Delayer::Deferred::Deferredable
|
|
28
28
|
def fail(exception = nil)
|
29
29
|
_call(:ng, exception) end
|
30
30
|
|
31
|
+
# _self_ が終了して結果が出るまで呼び出し側のDeferredを停止し、 _self_ の結果を返す。
|
32
|
+
# 呼び出し側はDeferredブロック内でなければならないが、 _Deferred#next_ を使わずに
|
33
|
+
# 直接戻り値を得ることが出来る。
|
34
|
+
# _self_ が失敗した場合は、呼び出し側のDeferredの直近の _trap_ ブロックが呼ばれる。
|
35
|
+
def +@
|
36
|
+
interrupt = Fiber.yield(self)
|
37
|
+
if interrupt.ok?
|
38
|
+
interrupt.value
|
39
|
+
else
|
40
|
+
Delayer::Deferred.fail(interrupt.value)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
31
44
|
# この一連のDeferredをこれ以上実行しない
|
32
45
|
def cancel
|
33
46
|
@callback = Callback.new(CallbackDefaultOK,
|
34
|
-
CallbackDefaultNG
|
35
|
-
BackTrace.new(nil, nil).freeze).freeze end
|
47
|
+
CallbackDefaultNG).freeze end
|
36
48
|
|
37
49
|
def callback
|
38
50
|
@callback ||= Callback.new(CallbackDefaultOK,
|
39
|
-
CallbackDefaultNG
|
40
|
-
BackTrace.new(nil, nil)) end
|
51
|
+
CallbackDefaultNG) end
|
41
52
|
|
42
53
|
# second 秒待って次を実行する
|
43
54
|
# ==== Args
|
@@ -54,32 +65,74 @@ module Delayer::Deferred::Deferredable
|
|
54
65
|
end
|
55
66
|
|
56
67
|
def _call(stat = :ok, value = nil)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@next.fail(exception) }
|
68
|
+
delayer.new do
|
69
|
+
result, fiber = delayer.Deferred.fiber do
|
70
|
+
begin
|
71
|
+
result = catch(:__deferredable_fail) do
|
72
|
+
Delayer::Deferred::ResultContainer.new(true, _execute(stat, value))
|
73
|
+
end
|
74
|
+
if result.is_a?(Delayer::Deferred::ResultContainer)
|
75
|
+
result
|
66
76
|
else
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
77
|
+
Delayer::Deferred::ResultContainer.new(false, result)
|
78
|
+
end
|
79
|
+
rescue Exception => exception
|
80
|
+
Delayer::Deferred::ResultContainer.new(false, exception)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
#_wait_fiber(fiber, nil)
|
84
|
+
if fiber
|
85
|
+
_fiber_stopped(result){|i| _wait_fiber(fiber, i) }
|
86
|
+
else
|
87
|
+
_fiber_completed(result)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
75
92
|
|
76
93
|
def _execute(stat, value)
|
77
|
-
callback[stat].call(value)
|
94
|
+
callback[stat].call(value)
|
95
|
+
end
|
96
|
+
|
97
|
+
def _wait_fiber(fiber, resume_value)
|
98
|
+
result = fiber.resume(resume_value)
|
99
|
+
if result.is_a?(Delayer::Deferred::ResultContainer)
|
100
|
+
_fiber_completed(result)
|
101
|
+
else
|
102
|
+
_fiber_stopped(result){|i| _wait_fiber(fiber, i) }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Deferredブロックが最後まで終わり、これ以上やることがない時に呼ばれる
|
107
|
+
def _fiber_completed(result)
|
108
|
+
result_value = result.value
|
109
|
+
if result.ok?
|
110
|
+
if result_value.is_a?(Delayer::Deferred::Deferredable)
|
111
|
+
result_value.next{|v|
|
112
|
+
_success_action(v)
|
113
|
+
}.trap{|v|
|
114
|
+
_fail_action(v)
|
115
|
+
}
|
116
|
+
else
|
117
|
+
_success_action(result_value)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
_fail_action(result_value)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Deferredable#@+によって停止され、 _defer_ の完了次第処理を再開する必要がある時に呼ばれる
|
125
|
+
def _fiber_stopped(defer, &cont)
|
126
|
+
defer.next{|v|
|
127
|
+
cont.(Delayer::Deferred::ResultContainer.new(true, v))
|
128
|
+
}.trap{|v|
|
129
|
+
cont.(Delayer::Deferred::ResultContainer.new(false, v))
|
130
|
+
}
|
131
|
+
end
|
78
132
|
|
79
133
|
def _post(kind, &proc)
|
80
134
|
@next = delayer.Deferred.new(self)
|
81
135
|
@next.callback[kind] = proc
|
82
|
-
@next.callback.backtrace[kind] = caller(1)
|
83
136
|
if defined?(@next_call_stat) and defined?(@next_call_value)
|
84
137
|
@next.__send__({ok: :call, ng: :fail}[@next_call_stat], @next_call_value)
|
85
138
|
elsif defined?(@follow) and @follow.nil?
|
@@ -90,10 +143,20 @@ module Delayer::Deferred::Deferredable
|
|
90
143
|
@next_call_stat, @next_call_value = stat, value
|
91
144
|
self end
|
92
145
|
|
146
|
+
def _success_action(obj)
|
147
|
+
if defined?(@next)
|
148
|
+
@next.call(obj)
|
149
|
+
else
|
150
|
+
register_next_call(:ok, obj)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
93
154
|
def _fail_action(err_obj)
|
94
155
|
if defined?(@next)
|
95
|
-
|
156
|
+
@next.fail(err_obj)
|
96
157
|
else
|
97
|
-
register_next_call(:ng, err_obj)
|
158
|
+
register_next_call(:ng, err_obj)
|
159
|
+
end
|
160
|
+
end
|
98
161
|
|
99
162
|
end
|
@@ -9,28 +9,34 @@ class Thread
|
|
9
9
|
Delayer
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def next(*rest, &block)
|
13
|
+
__gen_promise.next(*rest, &block)
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
kill end
|
16
|
+
def trap(*rest, &block)
|
17
|
+
__gen_promise.trap(*rest, &block)
|
18
|
+
end
|
20
19
|
|
21
20
|
private
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
|
22
|
+
def __gen_promise
|
23
|
+
promise = delayer.Deferred.new(true)
|
24
|
+
Thread.new(self) do |tt|
|
25
|
+
__promise_callback(tt, promise)
|
26
|
+
end
|
27
|
+
promise
|
28
|
+
end
|
29
|
+
|
30
|
+
def __promise_callback(tt, promise)
|
31
|
+
failed = catch(:__deferredable_fail) do
|
32
|
+
begin
|
33
|
+
promise.call(tt.value)
|
34
|
+
rescue Exception => err
|
35
|
+
promise.fail(err)
|
36
|
+
end
|
37
|
+
return
|
38
|
+
end
|
39
|
+
promise.fail(failed)
|
40
|
+
end
|
41
|
+
|
36
42
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
require 'delayer/deferred/error'
|
2
3
|
|
3
4
|
module Delayer::Deferred
|
4
5
|
module Tools
|
@@ -43,10 +44,14 @@ module Delayer::Deferred
|
|
43
44
|
# ==== Return
|
44
45
|
# Deferred
|
45
46
|
def system(*args)
|
46
|
-
delayer.Deferred.Thread.new
|
47
|
-
|
48
|
-
|
47
|
+
delayer.Deferred.Thread.new {
|
48
|
+
Process.waitpid2(Kernel.spawn(*args))
|
49
|
+
}.next{|_pid, status|
|
50
|
+
if status && status.success?
|
51
|
+
status
|
49
52
|
else
|
50
|
-
|
53
|
+
raise ForeignCommandAborted.new("command aborted: #{args.join(' ')}", process: $?) end
|
54
|
+
}
|
55
|
+
end
|
51
56
|
end
|
52
57
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'benchmark'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'delayer/deferred'
|
5
|
+
require_relative 'testutils.rb'
|
6
|
+
|
7
|
+
Benchmark.bmbm do |r|
|
8
|
+
extend TestUtils
|
9
|
+
n = 10000
|
10
|
+
|
11
|
+
r.report "construct" do
|
12
|
+
delayer = Delayer.generate_class
|
13
|
+
n.times do
|
14
|
+
delayer.Deferred.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
r.report "register next block" do
|
19
|
+
delayer = Delayer.generate_class
|
20
|
+
n.times do
|
21
|
+
delayer.Deferred.new.next{|x|
|
22
|
+
x
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
r.report "execute next block" do
|
28
|
+
delayer = Delayer.generate_class
|
29
|
+
eval_all_events(delayer) do
|
30
|
+
n.times do
|
31
|
+
delayer.Deferred.new.next{|x|
|
32
|
+
x
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
r.report "double next block" do
|
39
|
+
delayer = Delayer.generate_class
|
40
|
+
eval_all_events(delayer) do
|
41
|
+
n.times do
|
42
|
+
delayer.Deferred.new.next{|x|
|
43
|
+
x
|
44
|
+
}.next{|x|
|
45
|
+
x
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
r.report "trap block" do
|
52
|
+
delayer = Delayer.generate_class
|
53
|
+
eval_all_events(delayer) do
|
54
|
+
n.times do
|
55
|
+
delayer.Deferred.new.next{|x|
|
56
|
+
x
|
57
|
+
}.trap{|x|
|
58
|
+
x
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'delayer/deferred'
|
4
|
+
require 'ruby-prof'
|
5
|
+
require_relative 'testutils.rb'
|
6
|
+
|
7
|
+
extend TestUtils
|
8
|
+
n = 1000
|
9
|
+
|
10
|
+
RubyProf.start
|
11
|
+
delayer = Delayer.generate_class
|
12
|
+
eval_all_events(delayer) do
|
13
|
+
n.times do
|
14
|
+
delayer.Deferred.new.next{|x|
|
15
|
+
x
|
16
|
+
}.trap{|x|
|
17
|
+
x
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
result = RubyProf.stop
|
23
|
+
printer = RubyProf::CallTreePrinter.new(result)
|
24
|
+
path = File.expand_path(File.join(__dir__, '..', 'profile', Time.new.strftime('%Y-%m-%d-%H%M%S')))
|
25
|
+
FileUtils.mkdir_p(path)
|
26
|
+
puts "profile: writing to #{path}"
|
27
|
+
printer.print(path: path)
|
28
|
+
puts "profile: done."
|
data/test/deferred_test.rb
CHANGED
@@ -78,8 +78,8 @@ describe(Delayer::Deferred) do
|
|
78
78
|
}.trap{ |exception|
|
79
79
|
failure = exception }
|
80
80
|
end
|
81
|
-
assert_equal uuid, result
|
82
81
|
assert_equal false, failure
|
82
|
+
assert_equal uuid, result
|
83
83
|
end
|
84
84
|
|
85
85
|
it "join Deferredable#next after end of previous Deferredable" do
|
@@ -218,7 +218,7 @@ describe(Delayer::Deferred) do
|
|
218
218
|
succeed = failure = false
|
219
219
|
delayer = Delayer.generate_class
|
220
220
|
eval_all_events(delayer) do
|
221
|
-
delayer.Deferred.system("
|
221
|
+
delayer.Deferred.system("/bin/sh", "-c", "exit 0").next{ |value|
|
222
222
|
succeed = value
|
223
223
|
}.trap{ |exception|
|
224
224
|
failure = exception } end
|
@@ -230,13 +230,60 @@ describe(Delayer::Deferred) do
|
|
230
230
|
succeed = failure = false
|
231
231
|
delayer = Delayer.generate_class
|
232
232
|
eval_all_events(delayer) do
|
233
|
-
delayer.Deferred.system("
|
233
|
+
delayer.Deferred.system("/bin/sh", "-c", "exit 1").next{ |value|
|
234
234
|
succeed = value
|
235
235
|
}.trap{ |exception|
|
236
236
|
failure = exception } end
|
237
237
|
refute succeed, "next block did not called"
|
238
|
-
|
239
|
-
|
238
|
+
assert_instance_of Delayer::Deferred::ForeignCommandAborted, failure
|
239
|
+
assert failure.process.exited?, "command exited"
|
240
|
+
assert_equal 1, failure.process.exitstatus, "command exit status is 1"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe 'Deferredable#+@' do
|
245
|
+
it 'stops +@ deferred chain, then it returns result after receiver completed' do
|
246
|
+
delayer = Delayer.generate_class
|
247
|
+
log = Array.new
|
248
|
+
eval_all_events(delayer) do
|
249
|
+
delayer.Deferred.new.next{
|
250
|
+
log << :a1
|
251
|
+
b = delayer.Deferred.new.next{
|
252
|
+
log << :b1 << +delayer.Deferred.new.next{
|
253
|
+
log << :c1 << +delayer.Deferred.new.next{
|
254
|
+
log << :d1
|
255
|
+
:d2
|
256
|
+
}
|
257
|
+
:c2
|
258
|
+
}
|
259
|
+
:b2
|
260
|
+
}
|
261
|
+
log << :a2 << +b << :a3
|
262
|
+
}
|
263
|
+
end
|
264
|
+
|
265
|
+
assert_equal [:a1, :a2, :b1, :c1, :d1, :d2, :c2, :b2, :a3], log, 'incorrect call order'
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'fails receiver of +@, then fails callee Deferred' do
|
269
|
+
delayer = Delayer.generate_class
|
270
|
+
log = Array.new
|
271
|
+
eval_all_events(delayer) do
|
272
|
+
delayer.Deferred.new.next{
|
273
|
+
log << :a1
|
274
|
+
b = delayer.Deferred.new.next{
|
275
|
+
log << :b1
|
276
|
+
delayer.Deferred.fail(:be)
|
277
|
+
:b2
|
278
|
+
}
|
279
|
+
log << :a2 << +b << :a3
|
280
|
+
}.trap do |err|
|
281
|
+
log << :ae << err
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
assert_equal [:a1, :a2, :b1, :ae, :be], log, 'incorrect call order'
|
286
|
+
|
240
287
|
end
|
241
288
|
end
|
242
289
|
end
|
data/test/thread_test.rb
CHANGED
@@ -67,7 +67,7 @@ describe(Thread) do
|
|
67
67
|
uuid = SecureRandom.uuid
|
68
68
|
eval_all_events(delayer) do
|
69
69
|
delayer.Deferred.Thread.new {
|
70
|
-
|
70
|
+
raise uuid
|
71
71
|
}.next {
|
72
72
|
succeed = true
|
73
73
|
}.trap { |value|
|
@@ -75,7 +75,8 @@ describe(Thread) do
|
|
75
75
|
}.next {
|
76
76
|
recover = true } end
|
77
77
|
refute succeed, "Raised exception but it was executed successed route."
|
78
|
-
|
78
|
+
assert_instance_of RuntimeError, failure, "trap block takes incorrect value"
|
79
|
+
assert_equal uuid, failure.message, "trap block takes incorrect value"
|
79
80
|
assert recover, "next block did not executed when after trap"
|
80
81
|
end
|
81
82
|
|
@@ -113,4 +114,68 @@ describe(Thread) do
|
|
113
114
|
assert_equal false, failure
|
114
115
|
end
|
115
116
|
|
117
|
+
describe 'Race conditions' do
|
118
|
+
it "calls Thread#next for running thread" do
|
119
|
+
thread = succeed = result = false
|
120
|
+
uuid = SecureRandom.uuid
|
121
|
+
eval_all_events do
|
122
|
+
lock = true
|
123
|
+
th = Thread.new {
|
124
|
+
while lock; Thread.pass end
|
125
|
+
thread = true
|
126
|
+
uuid
|
127
|
+
}
|
128
|
+
th.next do |param|
|
129
|
+
succeed = true
|
130
|
+
result = param
|
131
|
+
end
|
132
|
+
lock = false
|
133
|
+
end
|
134
|
+
assert thread, "Thread did not executed."
|
135
|
+
assert succeed, "next block did not executed."
|
136
|
+
assert_equal uuid, result
|
137
|
+
end
|
138
|
+
|
139
|
+
it "calls Thread#next for stopped thread" do
|
140
|
+
thread = succeed = result = false
|
141
|
+
uuid = SecureRandom.uuid
|
142
|
+
eval_all_events do
|
143
|
+
th = Thread.new {
|
144
|
+
thread = true
|
145
|
+
uuid
|
146
|
+
}
|
147
|
+
while th.alive?; Thread.pass end
|
148
|
+
th.next do |param|
|
149
|
+
succeed = true
|
150
|
+
result = param
|
151
|
+
end
|
152
|
+
end
|
153
|
+
assert thread, "Thread did not executed."
|
154
|
+
assert succeed, "next block did not executed."
|
155
|
+
assert_equal uuid, result
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
it "wait ended Thread for +thread" do
|
160
|
+
result = failure = false
|
161
|
+
delayer = Delayer.generate_class
|
162
|
+
uuid1, uuid2, uuid3 = SecureRandom.uuid, SecureRandom.uuid, SecureRandom.uuid
|
163
|
+
eval_all_events(delayer) do
|
164
|
+
delayer.Deferred.new.next{
|
165
|
+
[
|
166
|
+
+delayer.Deferred.Thread.new{ uuid1 },
|
167
|
+
+delayer.Deferred.Thread.new{ uuid2 },
|
168
|
+
+delayer.Deferred.Thread.new{ uuid3 }
|
169
|
+
]
|
170
|
+
}.next{ |value|
|
171
|
+
result = value
|
172
|
+
}.trap{ |exception|
|
173
|
+
failure = exception }
|
174
|
+
end
|
175
|
+
assert_equal false, failure
|
176
|
+
assert_instance_of Array, result
|
177
|
+
assert_equal uuid1, result[0]
|
178
|
+
assert_equal uuid2, result[1]
|
179
|
+
assert_equal uuid3, result[2]
|
180
|
+
end
|
116
181
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delayer-deferred
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toshiaki Asai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: delayer
|
@@ -72,6 +72,20 @@ dependencies:
|
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '5.7'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: ruby-prof
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
75
89
|
description: Deferred for Delayer.
|
76
90
|
email:
|
77
91
|
- toshi.alternative@gmail.com
|
@@ -90,9 +104,13 @@ files:
|
|
90
104
|
- lib/delayer/deferred/deferredable.rb
|
91
105
|
- lib/delayer/deferred/enumerable.rb
|
92
106
|
- lib/delayer/deferred/enumerator.rb
|
107
|
+
- lib/delayer/deferred/error.rb
|
108
|
+
- lib/delayer/deferred/result_container.rb
|
93
109
|
- lib/delayer/deferred/thread.rb
|
94
110
|
- lib/delayer/deferred/tools.rb
|
95
111
|
- lib/delayer/deferred/version.rb
|
112
|
+
- test/deferred_benchmark.rb
|
113
|
+
- test/deferred_profiler.rb
|
96
114
|
- test/deferred_test.rb
|
97
115
|
- test/enumerable_test.rb
|
98
116
|
- test/helper.rb
|
@@ -118,11 +136,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
136
|
version: '0'
|
119
137
|
requirements: []
|
120
138
|
rubyforge_project:
|
121
|
-
rubygems_version: 2.
|
139
|
+
rubygems_version: 2.6.8
|
122
140
|
signing_key:
|
123
141
|
specification_version: 4
|
124
142
|
summary: Deferred for Delayer
|
125
143
|
test_files:
|
144
|
+
- test/deferred_benchmark.rb
|
145
|
+
- test/deferred_profiler.rb
|
126
146
|
- test/deferred_test.rb
|
127
147
|
- test/enumerable_test.rb
|
128
148
|
- test/helper.rb
|