exceptional_synchrony 1.0.1 → 1.3.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.
@@ -4,13 +4,13 @@ describe ExceptionalSynchrony::LimitedWorkQueue do
4
4
  end
5
5
 
6
6
  it "should raise an exception if created with a limit < 1" do
7
- assert_raises(ArgumentError) do
7
+ expect(assert_raises(ArgumentError) do
8
8
  ExceptionalSynchrony::LimitedWorkQueue.new(@em, 0)
9
- end.message.must_match /must be positive/
9
+ end.message).must_match(/must be positive/)
10
10
 
11
- assert_raises(ArgumentError) do
11
+ expect(assert_raises(ArgumentError) do
12
12
  ExceptionalSynchrony::LimitedWorkQueue.new(@em, -2)
13
- end.message.must_match /must be positive/
13
+ end.message).must_match(/must be positive/)
14
14
  end
15
15
 
16
16
  describe "when created" do
@@ -21,9 +21,9 @@ describe ExceptionalSynchrony::LimitedWorkQueue do
21
21
  it "should run non-blocking jobs immediately" do
22
22
  c = 0
23
23
  ExceptionalSynchrony::EMP.run_and_stop do
24
- @queue.add { c+=1 }
25
- @queue.add { c+=1 }
26
- @queue.add { c+=1 }
24
+ @queue.add! { c+=1 }
25
+ @queue.add! { c+=1 }
26
+ @queue.add! { c+=1 }
27
27
  end
28
28
  assert_equal 3, c
29
29
  end
@@ -46,9 +46,9 @@ describe ExceptionalSynchrony::LimitedWorkQueue do
46
46
  it "should allow objects to be queued instead of Procs" do
47
47
  c = 0
48
48
  ExceptionalSynchrony::EMP.run_and_stop do
49
- @queue.add(LWQTestProc.new { c+=1 })
50
- @queue.add(LWQTestProc.new { c+=1 })
51
- @queue.add(LWQTestProc.new { c+=1 })
49
+ @queue.add!(LWQTestProc.new { c+=1 })
50
+ @queue.add!(LWQTestProc.new { c+=1 })
51
+ @queue.add!(LWQTestProc.new { c+=1 })
52
52
  end
53
53
  assert_equal 3, c
54
54
  end
@@ -71,17 +71,17 @@ describe ExceptionalSynchrony::LimitedWorkQueue do
71
71
  end
72
72
 
73
73
  ExceptionalSynchrony::EMP.run_and_stop do
74
- @queue.add(job_proc)
74
+ @queue.add!(job_proc)
75
75
  end
76
76
  end
77
77
 
78
78
  it "should allow objects to merge themselves into the queue (canceling itself)" do
79
79
  c = 0
80
80
  ExceptionalSynchrony::EMP.run_and_stop do
81
- @queue.add(LWQTestProc.new { @em.sleep(0.001); c+=1 })
82
- @queue.add(LWQTestProc.new { @em.sleep(0.001); c+=2 })
83
- @queue.add(LWQTestProcWithMergeDrop.new(-> { c+=4 }) { @em.sleep(0.001); c+=8 })
84
- @queue.add(LWQTestProcWithMergeDrop.new(-> { c+=16 }) { @em.sleep(0.001); c+=32 }) # will get merged (by canceling self)
81
+ @queue.add!(LWQTestProc.new { @em.sleep(0.001); c+=1 })
82
+ @queue.add!(LWQTestProc.new { @em.sleep(0.001); c+=2 })
83
+ @queue.add!(LWQTestProcWithMergeDrop.new(-> { c+=4 }) { @em.sleep(0.001); c+=8 })
84
+ @queue.add!(LWQTestProcWithMergeDrop.new(-> { c+=16 }) { @em.sleep(0.001); c+=32 }) # will get merged (by canceling self)
85
85
  @em.sleep(0.050)
86
86
  end
87
87
  assert_equal 1+2+8+16, c
@@ -99,15 +99,35 @@ describe ExceptionalSynchrony::LimitedWorkQueue do
99
99
  it "should allow objects to merge themselves into the queue (canceling/replacing earlier)" do
100
100
  c = 0
101
101
  ExceptionalSynchrony::EMP.run_and_stop do
102
- @queue.add(LWQTestProc.new { @em.sleep(0.001); c+=1 })
103
- @queue.add(LWQTestProc.new { @em.sleep(0.001); c+=2 })
104
- @queue.add(LWQTestProcWithMergeReplace.new(-> { c+=4 }) { @em.sleep(0.001); c+=8 })
105
- @queue.add(LWQTestProcWithMergeReplace.new(-> { c+=16 }) { @em.sleep(0.001); c+=32 }) # will get merged with above (replacing above)
102
+ @queue.add!(LWQTestProc.new { @em.sleep(0.001); c+=1 })
103
+ @queue.add!(LWQTestProc.new { @em.sleep(0.001); c+=2 })
104
+ @queue.add!(LWQTestProcWithMergeReplace.new(-> { c+=4 }) { @em.sleep(0.001); c+=8 })
105
+ @queue.add!(LWQTestProcWithMergeReplace.new(-> { c+=16 }) { @em.sleep(0.001); c+=32 }) # will get merged with above (replacing above)
106
106
  @em.sleep(0.050)
107
107
  end
108
108
  assert_equal 1+2+4+32, c
109
109
  end
110
110
 
111
+ it "should ensure that the queue continues to function even when an exception is raised" do
112
+ mock(ExceptionHandling).log_error(anything, /LimitedWorkQueue encountered an exception/).twice
113
+ ExceptionalSynchrony::EMP.run_and_stop do
114
+ c = 0
115
+ last_start = nil; end_0 = nil; end_1 = nil
116
+ @queue.add! { c += 1; @em.sleep(0.001); end_0 = c+=1; raise "Boom" }
117
+ @queue.add! { c += 1; @em.sleep(0.001); end_1 = c+=1; raise "Boom" }
118
+ @queue.add! { last_start = c+= 1; @em.sleep(0.001); c+=1 }
119
+
120
+ 3.times do
121
+ @em.sleep(0.030)
122
+ break if c == 6
123
+ end
124
+
125
+ assert last_start && last_start > 3, "Unexpected value for last_start: #{last_start.inspect}"
126
+ assert [end_0, end_1].any? {|e| last_start > e }
127
+ assert_equal 6, c
128
+ end
129
+ end
130
+
111
131
  it "should run 2 blocking tasks in parallel and only start 3rd when one of the first 2 finishes" do
112
132
  stub_request(:get, "http://www.google.com/").
113
133
  to_return(:status => 200, :body => "1", :headers => {})
@@ -121,12 +141,12 @@ describe ExceptionalSynchrony::LimitedWorkQueue do
121
141
  ExceptionalSynchrony::EMP.run_and_stop do
122
142
  c = -1
123
143
  started2 = nil; ended0 = nil; ended1 = nil
124
- @queue.add { c+=1; @em.sleep(0.001); ExceptionalSynchrony::EMP.connection.new("http://www.google.com").get; ended0 = c+=1 }
125
- @queue.add { c+=1; @em.sleep(0.001); ExceptionalSynchrony::EMP.connection.new("http://www.cnn.com").get; ended1 = c+=1 }
126
- @queue.add { started2 = c+=1; ExceptionalSynchrony::EMP.connection.new("http://news.ycombinator.com").get; c+=1 }
144
+ @queue.add! { c+=1; @em.sleep(0.001); ExceptionalSynchrony::EMP.connection.new("http://www.google.com").get; ended0 = c+=1 }
145
+ @queue.add! { c+=1; @em.sleep(0.001); ExceptionalSynchrony::EMP.connection.new("http://www.cnn.com").get; ended1 = c+=1 }
146
+ @queue.add! { started2 = c+=1; ExceptionalSynchrony::EMP.connection.new("http://news.ycombinator.com").get; c+=1 }
127
147
 
128
148
  3.times do
129
- @em.sleep(0.005)
149
+ @em.sleep(0.030)
130
150
  break if c == 5
131
151
  end
132
152
 
@@ -135,5 +155,183 @@ describe ExceptionalSynchrony::LimitedWorkQueue do
135
155
  assert started2 > ended0 || started2 > ended1, [ended0, ended1, started2].inspect
136
156
  end
137
157
  end
158
+
159
+ describe '#paused?' do
160
+ it 'should return false when @paused is false' do
161
+ @queue.instance_variable_set(:@paused, false)
162
+ assert_equal false, @queue.paused?
163
+ end
164
+
165
+ it 'should return true when @paused is true' do
166
+ @queue.instance_variable_set(:@paused, false)
167
+ assert_equal false, @queue.paused?
168
+ end
169
+ end
170
+
171
+ describe '#pause!' do
172
+ it 'should set @paused to true if @paused is currently false' do
173
+ assert_equal false, @queue.instance_variable_get('@paused')
174
+ @queue.pause!
175
+ assert_equal true, @queue.instance_variable_get('@paused')
176
+ end
177
+
178
+ it 'should set @paused to true if @paused is currently true' do
179
+ @queue.instance_variable_set(:@paused, true)
180
+ assert_equal true, @queue.instance_variable_get('@paused')
181
+ @queue.pause!
182
+ assert_equal true, @queue.instance_variable_get('@paused')
183
+ end
184
+ end
185
+
186
+ describe '#unpause!' do
187
+ it 'should set @paused to false if @paused is currently false' do
188
+ assert_equal false, @queue.instance_variable_get('@paused')
189
+ @queue.unpause!
190
+ assert_equal false, @queue.instance_variable_get('@paused')
191
+ end
192
+
193
+ it 'should set @paused to false if @paused is currently true' do
194
+ @queue.instance_variable_set(:@paused, true)
195
+ assert_equal true, @queue.instance_variable_get('@paused')
196
+ @queue.unpause!
197
+ assert_equal false, @queue.instance_variable_get('@paused')
198
+ end
199
+ end
200
+
201
+ describe '#add!' do
202
+ it 'should run jobs added to the queue when paused? is false' do
203
+ assert_equal false, @queue.paused? # queue#paused is false be default
204
+ counter = 0
205
+ ExceptionalSynchrony::EMP.run_and_stop do
206
+ 3.times { @queue.add! { counter+=1 } }
207
+ end
208
+
209
+ assert_equal 0, @queue.instance_variable_get("@job_procs").size
210
+ assert_equal 3, counter
211
+ end
212
+
213
+ it 'should not run jobs added to the queue when paused? is true' do
214
+ @queue.pause!
215
+ assert_equal true, @queue.paused?
216
+ counter = 0
217
+ ExceptionalSynchrony::EMP.run_and_stop do
218
+ 3.times { @queue.add! { counter+=1 } }
219
+ end
220
+
221
+ mock(@queue).work!.never
222
+ assert_equal 3, @queue.instance_variable_get("@job_procs").size
223
+ assert_equal 0, counter
224
+ end
225
+
226
+ it 'should have a method alias to #add for callers using the previous #add method' do
227
+ assert_equal @queue.method(:add!), @queue.method(:add)
228
+ end
229
+ end
230
+
231
+ describe '#items' do
232
+ it 'should return job_procs array' do
233
+ assert_equal 0, @queue.items.size
234
+ job_procs = Array.new(3) { Proc.new { puts 'Hello World' } }
235
+ @queue.instance_variable_set(:@job_procs, job_procs)
236
+ assert_equal 3, @queue.items.size
237
+ end
238
+ end
239
+
240
+ describe '#work!' do
241
+ before do
242
+ @queue = ExceptionalSynchrony::LimitedWorkQueue.new(@em, 2)
243
+ end
244
+
245
+ it 'should run items in queue' do
246
+ counter = 0
247
+ job_procs = Array.new(3) { Proc.new { counter += 1} }
248
+ @queue.instance_variable_set(:@job_procs, job_procs)
249
+ mock.proxy(Fiber).new.with_any_args.times(3)
250
+ @queue.work!
251
+
252
+ assert_equal 0, @queue.instance_variable_get("@job_procs").size
253
+ assert_equal 3, counter
254
+ end
255
+
256
+ it 'should run items already in queue, even if queue is paused' do
257
+ @queue.pause!
258
+ counter = 4
259
+ job_procs = Array.new(3) { Proc.new { counter += 1} }
260
+ @queue.instance_variable_set(:@job_procs, job_procs)
261
+ assert_equal 3, @queue.instance_variable_get("@job_procs").size
262
+ mock.proxy(Fiber).new.with_any_args.times(3)
263
+
264
+ @queue.work!
265
+
266
+ assert_equal 7, counter
267
+ assert_equal 0, @queue.instance_variable_get("@job_procs").size
268
+ end
269
+
270
+ it 'should not run if queue_empty' do
271
+ stub(@queue).queue_empty? { true }
272
+ counter = 0
273
+ job_procs = Array.new(3) { Proc.new { counter += 1} }
274
+ @queue.instance_variable_set(:@job_procs, job_procs)
275
+ assert_equal 3, @queue.instance_variable_get("@job_procs").size
276
+ mock(Fiber).new.never
277
+
278
+ @queue.work!
279
+ assert_equal 0, counter
280
+ end
281
+
282
+ it 'should not run if workers are full' do
283
+ stub(@queue).workers_full? { true }
284
+ counter = 0
285
+ job_procs = Array.new(3) { Proc.new { counter += 1} }
286
+ @queue.instance_variable_set(:@job_procs, job_procs)
287
+
288
+ assert_equal 3, @queue.instance_variable_get("@job_procs").size
289
+ mock(Fiber).new.never
290
+
291
+ @queue.work!
292
+ assert_equal 0, counter
293
+ end
294
+ end
295
+
296
+ describe '#workers_full?' do
297
+ before do
298
+ @queue = ExceptionalSynchrony::LimitedWorkQueue.new(@em, 2) # limit the number of active workers to 2 max
299
+ end
300
+
301
+ it 'should return true if the number of current workers is greater than the queue\'s defined worker limit' do
302
+ @queue.instance_variable_set(:@worker_count, 20)
303
+ @queue.instance_variable_set(:@limit, 10)
304
+ assert_equal true, @queue.workers_full?
305
+ end
306
+
307
+ it 'should return true if the current number of workers is equal to the queue\'s defined worker limit' do
308
+ @queue.instance_variable_set(:@worker_count, 10)
309
+ @queue.instance_variable_set(:@limit, 10)
310
+ assert_equal true, @queue.workers_full?
311
+ end
312
+
313
+ it 'should return false if the current number of workers is less than the queue\'s defined worker limit' do
314
+ @queue.instance_variable_set(:@worker_count, 5)
315
+ @queue.instance_variable_set(:@limit, 10)
316
+ assert_equal false, @queue.workers_full?
317
+ end
318
+ end
319
+
320
+ describe '#queue_empty?' do
321
+ before do
322
+ @queue = ExceptionalSynchrony::LimitedWorkQueue.new(@em, 2)
323
+ end
324
+
325
+ it 'should return true if queue is empty' do
326
+ @queue.instance_variable_set(:@job_procs, [])
327
+ assert_equal true, @queue.queue_empty?
328
+ end
329
+
330
+ it 'should return false if queue is not empty' do
331
+ @queue.instance_variable_set(:@job_procs, [Proc.new { 'hello'}])
332
+ assert_equal false, @queue.queue_empty?
333
+ end
334
+ end
335
+
138
336
  end
139
337
  end
@@ -56,15 +56,15 @@ describe ExceptionalSynchrony::ParallelSync do
56
56
  stub_request(:get, "http://news.ycombinator.com/").
57
57
  to_return(:status => 200, :body => "3", :headers => {})
58
58
 
59
- assert_raises(NotImplementedError) do
59
+ expect(assert_raises(NotImplementedError) do
60
60
  ExceptionalSynchrony::EMP.run_and_stop do
61
- responses = ExceptionalSynchrony::ParallelSync.parallel(@em) do |parallel|
61
+ ExceptionalSynchrony::ParallelSync.parallel(@em) do |parallel|
62
62
  parallel.add { ExceptionalSynchrony::EMP.connection.new("http://www.google.com").get; raise NotImplementedError, "Not implemented!" }
63
63
  parallel.add { ExceptionalSynchrony::EMP.connection.new("http://www.cnn.com").get }
64
64
  parallel.add { ExceptionalSynchrony::EMP.connection.new("http://news.ycombinator.com").get }
65
65
  end
66
66
  end
67
- end.to_s.must_match(/Not implemented!/)
67
+ end.to_s).must_match(/Not implemented!/)
68
68
  end
69
69
 
70
70
  it "should pass several exceptions through and raise them on the other side" do
@@ -77,15 +77,15 @@ describe ExceptionalSynchrony::ParallelSync do
77
77
  stub_request(:get, "http://news.ycombinator.com/").
78
78
  to_return(:status => 200, :body => "3", :headers => {})
79
79
 
80
- assert_raises(NotImplementedError) do
80
+ expect(assert_raises(NotImplementedError) do
81
81
  ExceptionalSynchrony::EMP.run_and_stop do
82
- responses = ExceptionalSynchrony::ParallelSync.parallel(@em) do |parallel|
82
+ ExceptionalSynchrony::ParallelSync.parallel(@em) do |parallel|
83
83
  parallel.add { ExceptionalSynchrony::EMP.connection.new("http://www.google.com").get; raise NotImplementedError, "Not implemented!" }
84
84
  parallel.add { ExceptionalSynchrony::EMP.connection.new("http://www.cnn.com").get; raise LoadError, "A load error occurred" }
85
85
  parallel.add { ExceptionalSynchrony::EMP.connection.new("http://news.ycombinator.com").get; raise IndexError, "An index error occurred" }
86
86
  end
87
87
  end
88
- end.message.must_match(/Not implemented!.*LoadError: A load error occurred.*IndexError: An index error occurred/m)
88
+ end.message).must_match(/Not implemented!.*LoadError: A load error occurred.*IndexError: An index error occurred/m)
89
89
  end
90
90
 
91
91
  class TestProc
metadata CHANGED
@@ -1,154 +1,102 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exceptional_synchrony
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - Colin Kelley
8
- autorequire:
7
+ - Invoca
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2014-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: exception_handling
14
+ name: em-synchrony
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '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
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: eventmachine
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
33
- version: 1.0.3
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ~>
39
- - !ruby/object:Gem::Version
40
- version: 1.0.3
41
- - !ruby/object:Gem::Dependency
42
- name: em-synchrony
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ~>
46
- - !ruby/object:Gem::Version
47
- version: 1.0.3
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ~>
53
- - !ruby/object:Gem::Version
54
- version: 1.0.3
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: em-http-request
57
29
  requirement: !ruby/object:Gem::Requirement
58
30
  requirements:
59
- - - '>='
31
+ - - ">="
60
32
  - !ruby/object:Gem::Version
61
33
  version: '0'
62
34
  type: :runtime
63
35
  prerelease: false
64
36
  version_requirements: !ruby/object:Gem::Requirement
65
37
  requirements:
66
- - - '>='
38
+ - - ">="
67
39
  - !ruby/object:Gem::Version
68
40
  version: '0'
69
41
  - !ruby/object:Gem::Dependency
70
- name: hobo_support
42
+ name: eventmachine
71
43
  requirement: !ruby/object:Gem::Requirement
72
44
  requirements:
73
- - - '>='
45
+ - - ">="
74
46
  - !ruby/object:Gem::Version
75
47
  version: '0'
76
48
  type: :runtime
77
49
  prerelease: false
78
50
  version_requirements: !ruby/object:Gem::Requirement
79
51
  requirements:
80
- - - '>='
52
+ - - ">="
81
53
  - !ruby/object:Gem::Version
82
54
  version: '0'
83
55
  - !ruby/object:Gem::Dependency
84
- name: thor
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - '>='
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - '>='
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: minitest
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - '>='
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - '>='
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: webmock
56
+ name: exception_handling
113
57
  requirement: !ruby/object:Gem::Requirement
114
58
  requirements:
115
- - - ~>
59
+ - - "~>"
116
60
  - !ruby/object:Gem::Version
117
- version: 1.17.1
118
- type: :development
61
+ version: '2.2'
62
+ type: :runtime
119
63
  prerelease: false
120
64
  version_requirements: !ruby/object:Gem::Requirement
121
65
  requirements:
122
- - - ~>
66
+ - - "~>"
123
67
  - !ruby/object:Gem::Version
124
- version: 1.17.1
68
+ version: '2.2'
125
69
  - !ruby/object:Gem::Dependency
126
- name: rr
70
+ name: invoca-utils
127
71
  requirement: !ruby/object:Gem::Requirement
128
72
  requirements:
129
- - - ~>
73
+ - - "~>"
130
74
  - !ruby/object:Gem::Version
131
- version: 1.1.2
132
- type: :development
75
+ version: '0.3'
76
+ type: :runtime
133
77
  prerelease: false
134
78
  version_requirements: !ruby/object:Gem::Requirement
135
79
  requirements:
136
- - - ~>
80
+ - - "~>"
137
81
  - !ruby/object:Gem::Version
138
- version: 1.1.2
82
+ version: '0.3'
139
83
  description: ''
140
- email: colin@invoca.com
84
+ email: development@invoca.com
141
85
  executables: []
142
86
  extensions: []
143
87
  extra_rdoc_files: []
144
88
  files:
145
- - .gitignore
146
- - .ruby-gemset
89
+ - ".dependabot/config.yml"
90
+ - ".gitignore"
91
+ - ".jenkins/Jenkinsfile"
92
+ - ".jenkins/ruby_build_pod.yml"
93
+ - ".ruby-gemset"
94
+ - ".ruby-version"
95
+ - CHANGELOG.md
147
96
  - Gemfile
148
97
  - Gemfile.lock
149
98
  - README.md
150
99
  - Rakefile
151
- - Thorfile
152
100
  - exceptional_synchrony.gemspec
153
101
  - lib/exceptional_synchrony.rb
154
102
  - lib/exceptional_synchrony/callback_exceptions.rb
@@ -164,25 +112,26 @@ files:
164
112
  homepage: https://github.com/Invoca/exceptional_synchrony
165
113
  licenses:
166
114
  - MIT
167
- metadata: {}
168
- post_install_message:
115
+ metadata:
116
+ source_code_uri: https://github.com/Invoca/exceptional_synchrony
117
+ allowed_push_host: https://rubygems.org
118
+ post_install_message:
169
119
  rdoc_options: []
170
120
  require_paths:
171
121
  - lib
172
122
  required_ruby_version: !ruby/object:Gem::Requirement
173
123
  requirements:
174
- - - '>='
124
+ - - ">="
175
125
  - !ruby/object:Gem::Version
176
126
  version: '0'
177
127
  required_rubygems_version: !ruby/object:Gem::Requirement
178
128
  requirements:
179
- - - '>='
129
+ - - ">="
180
130
  - !ruby/object:Gem::Version
181
131
  version: '0'
182
132
  requirements: []
183
- rubyforge_project:
184
- rubygems_version: 2.0.3
185
- signing_key:
133
+ rubygems_version: 3.0.3
134
+ signing_key:
186
135
  specification_version: 4
187
136
  summary: Extensions to EventMachine/Synchrony to work well with exceptions
188
137
  test_files: []