exceptional_synchrony 1.0.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []