simple-future 1.0.0.pre1 → 1.0.0.pre2
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/LICENSE.txt +21 -0
- data/README.md +175 -0
- data/Rakefile +27 -0
- data/doc/SimpleFuture/ChildError.html +411 -0
- data/doc/SimpleFuture/Error.html +140 -0
- data/doc/SimpleFuture/ResultTypeError.html +147 -0
- data/doc/SimpleFuture.html +998 -0
- data/doc/_index.html +152 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +499 -0
- data/doc/file.README.html +255 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +255 -0
- data/doc/js/app.js +248 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +147 -0
- data/doc/top-level-namespace.html +110 -0
- data/simple-future.gemspec +31 -0
- data/spec/simple-future_spec.rb +180 -0
- data/spec/spec_helper.rb +6 -0
- metadata +25 -1
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def time_it(&blk)
|
4
|
+
before = Time.now
|
5
|
+
blk.call()
|
6
|
+
return Time.now - before
|
7
|
+
end
|
8
|
+
|
9
|
+
class ScratchError < RuntimeError; end
|
10
|
+
class BogoError < RuntimeError
|
11
|
+
def initialize(e)
|
12
|
+
super(e)
|
13
|
+
@unmarshalableValue = proc{42}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "SimpleFuture" do
|
18
|
+
it "lets you specify the number of tasks" do
|
19
|
+
expect(SimpleFuture.max_tasks).to be > 0
|
20
|
+
SimpleFuture.max_tasks = 4
|
21
|
+
expect(SimpleFuture.max_tasks).to be 4
|
22
|
+
end
|
23
|
+
|
24
|
+
it "executes a block without changing the current state" do
|
25
|
+
foo = 42
|
26
|
+
r = SimpleFuture.new do
|
27
|
+
foo += 1
|
28
|
+
foo
|
29
|
+
end
|
30
|
+
|
31
|
+
expect(r.value).to be 43
|
32
|
+
expect(foo).to be 42
|
33
|
+
end
|
34
|
+
|
35
|
+
it "allows non-blocking polling" do
|
36
|
+
# We use time-based measurements to test this, so there's the
|
37
|
+
# potential for unusual timing conditions to break this test. It
|
38
|
+
# shouldn't happen on normal hardware and conditions, though.
|
39
|
+
r = SimpleFuture.new do
|
40
|
+
sleep 1
|
41
|
+
42
|
42
|
+
end
|
43
|
+
|
44
|
+
expect(r.check_if_ready).to be false
|
45
|
+
sleep 2
|
46
|
+
expect(r.check_if_ready).to be true
|
47
|
+
expect(r.value).to be 42
|
48
|
+
end
|
49
|
+
|
50
|
+
it "correctly returns the block's results" do
|
51
|
+
f1 = SimpleFuture.new { sleep 1; 1}
|
52
|
+
f2 = SimpleFuture.new { sleep 1; 2}
|
53
|
+
f3 = SimpleFuture.new { sleep 1; 3}
|
54
|
+
f4 = SimpleFuture.new { sleep 1; 4}
|
55
|
+
|
56
|
+
expect(f1.value).to be 1
|
57
|
+
expect(f2.value).to be 2
|
58
|
+
expect(f3.value).to be 3
|
59
|
+
expect(f4.value).to be 4
|
60
|
+
end
|
61
|
+
|
62
|
+
it "allows multiple calls to wait" do
|
63
|
+
f1 = SimpleFuture.new { 42 }
|
64
|
+
f1.wait
|
65
|
+
expect(f1.value).to be 42
|
66
|
+
|
67
|
+
f1.wait
|
68
|
+
expect(f1.value).to be 42
|
69
|
+
|
70
|
+
f1.wait
|
71
|
+
expect(f1.value).to be 42
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
it "lets you wait until completion and test for that" do
|
77
|
+
r = SimpleFuture.new { 12345 }
|
78
|
+
expect(r.complete?).to be false
|
79
|
+
|
80
|
+
r.wait
|
81
|
+
expect(r.complete?).to be true
|
82
|
+
|
83
|
+
expect(r.value).to be 12345
|
84
|
+
end
|
85
|
+
|
86
|
+
it "gracefully handles exceptions thrown by the child" do
|
87
|
+
r = SimpleFuture.new { raise ScratchError.new("Foo!") }
|
88
|
+
expect {r.wait}.to raise_error(SimpleFuture::ChildError, /Foo!/)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "returns Exception objects if requested" do
|
92
|
+
r = SimpleFuture.new { ScratchError.new("not thrown!") }
|
93
|
+
r.wait
|
94
|
+
expect(r.value.class).to be ScratchError
|
95
|
+
expect(r.value.message).to eq "not thrown!"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "attaches the original exception to the ChildError" do
|
99
|
+
r = SimpleFuture.new { raise ScratchError.new("Foo!") }
|
100
|
+
begin
|
101
|
+
r.wait
|
102
|
+
rescue SimpleFuture::ChildError => e
|
103
|
+
expect(e.cause.class).to be ScratchError
|
104
|
+
expect(e.cause.message).to match("Foo!")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
it "cleans up completed child processes" do
|
110
|
+
first = SimpleFuture.new { sleep 1; 1}
|
111
|
+
second = SimpleFuture.new { sleep 2; 2}
|
112
|
+
sleep 1.1
|
113
|
+
|
114
|
+
expect(SimpleFuture.all_done?).to be false
|
115
|
+
|
116
|
+
# First should now have completed:
|
117
|
+
expect(first.complete?).to be true
|
118
|
+
expect(second.complete?).to be false
|
119
|
+
expect(second.check_if_ready).to be false
|
120
|
+
|
121
|
+
# Wait for second one to complete, then scrub
|
122
|
+
sleep 1
|
123
|
+
expect(second.complete?).to be false
|
124
|
+
expect(SimpleFuture.all_done?).to be true
|
125
|
+
expect(second.complete?).to be true
|
126
|
+
end
|
127
|
+
|
128
|
+
it "does not block when free tasks are available" do
|
129
|
+
SimpleFuture.max_tasks = 4
|
130
|
+
|
131
|
+
tt = time_it {
|
132
|
+
sfs = (0..3).map{|i| SimpleFuture.new {sleep 1; i} }
|
133
|
+
sfs.each{|sf| sf.value}
|
134
|
+
}
|
135
|
+
expect(tt).to be < 1.1
|
136
|
+
end
|
137
|
+
|
138
|
+
it "interprets maximum tasks of 0 as meaning no limit on children" do
|
139
|
+
SimpleFuture.max_tasks = 0
|
140
|
+
|
141
|
+
tt = time_it {
|
142
|
+
sfs = (0..30).map{|i| SimpleFuture.new {sleep 1; i} }
|
143
|
+
sfs.each{|sf| sf.value}
|
144
|
+
}
|
145
|
+
expect(tt).to be < 1.1
|
146
|
+
end
|
147
|
+
|
148
|
+
it "blocks when the maximum number of children is reached" do
|
149
|
+
SimpleFuture.max_tasks = 4
|
150
|
+
|
151
|
+
tt = time_it {
|
152
|
+
sfs = (0..7).map{|i| SimpleFuture.new {sleep 1; i} }
|
153
|
+
sfs.each{|sf| sf.value}
|
154
|
+
}
|
155
|
+
expect(tt).to be > 1
|
156
|
+
expect(tt).to be < 2.1
|
157
|
+
end
|
158
|
+
|
159
|
+
it "can block until all active children have finished" do
|
160
|
+
SimpleFuture.max_tasks = 4
|
161
|
+
sfs = (0..3).map{|i| SimpleFuture.new {sleep 1; i} }
|
162
|
+
|
163
|
+
SimpleFuture.wait_for_all
|
164
|
+
|
165
|
+
sfs.each{|sf|
|
166
|
+
expect(sf.check_if_ready).to be true
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
it "handles the case where the result isn't marshallable" do
|
171
|
+
r = SimpleFuture.new { proc{42} }
|
172
|
+
expect {r.value}.to raise_error(SimpleFuture::ResultTypeError, /Proc/)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "handles the case where the exception contains an unmarshallable item" do
|
176
|
+
r = SimpleFuture.new { raise BogoError.new("error!") }
|
177
|
+
expect {r.value}.to raise_error(SimpleFuture::ResultTypeError, /dumped/)
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-future
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Reuter
|
@@ -63,7 +63,31 @@ executables: []
|
|
63
63
|
extensions: []
|
64
64
|
extra_rdoc_files: []
|
65
65
|
files:
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- doc/SimpleFuture.html
|
70
|
+
- doc/SimpleFuture/ChildError.html
|
71
|
+
- doc/SimpleFuture/Error.html
|
72
|
+
- doc/SimpleFuture/ResultTypeError.html
|
73
|
+
- doc/_index.html
|
74
|
+
- doc/class_list.html
|
75
|
+
- doc/css/common.css
|
76
|
+
- doc/css/full_list.css
|
77
|
+
- doc/css/style.css
|
78
|
+
- doc/file.README.html
|
79
|
+
- doc/file_list.html
|
80
|
+
- doc/frames.html
|
81
|
+
- doc/index.html
|
82
|
+
- doc/js/app.js
|
83
|
+
- doc/js/full_list.js
|
84
|
+
- doc/js/jquery.js
|
85
|
+
- doc/method_list.html
|
86
|
+
- doc/top-level-namespace.html
|
66
87
|
- lib/simple-future.rb
|
88
|
+
- simple-future.gemspec
|
89
|
+
- spec/simple-future_spec.rb
|
90
|
+
- spec/spec_helper.rb
|
67
91
|
homepage: https://github.com/suetanvil/simple-future
|
68
92
|
licenses:
|
69
93
|
- MIT
|