ione 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 941fc3fd59d15b806854ddd8ff0f30f645ff51bf
4
- data.tar.gz: 1b89b672b8b69eda9561138190aed7d35d677538
3
+ metadata.gz: c3ef9ccb78957f99a401f9d3808fa74ea940ff17
4
+ data.tar.gz: 081d0432ba2a6960d84ee527c9ff10474b4ce31e
5
5
  SHA512:
6
- metadata.gz: f26209edcf366c70ac80a913901f4c6db5a7a15e2e4a9c53e0d73f99b9d1e25e98bd4f0533dc4e88d3ec846abd538b6f80cb9d877ae547091a363121d1a05992
7
- data.tar.gz: 6c5565772dd3994caac71ffd2a63cf25f2c595161eeb501928050123c59b5579cf1d5a45ac4a0e585ca15fd9c82b9c7f1253135c2e6f74cf0e9569a89e66d1dc
6
+ metadata.gz: 8c4624c05b932671afdd0c8406e345cd3476bfad89b2118fabf3ce4101ba3849dc98ad0f32168c7c8b255c0f20bec9961d016f469a516dae20db7792294829ca
7
+ data.tar.gz: 6a1ec1a33dbdb4f9bdaf0faffd68e4e23019763ab4a3a90e232144ebea228eff1d865ec6094b323b908fc63e419c993cb02183acb39f7f5d5632dc735ab3b0f7
@@ -179,10 +179,12 @@ module Ione
179
179
  swap_buffers
180
180
  end
181
181
  read_buffer_length = @read_buffer.bytesize
182
- if start_index < read_buffer_length - @offset && (index = @read_buffer.index(substring, @offset + start_index))
182
+ if start_index + substring.bytesize <= read_buffer_length - @offset && (index = @read_buffer.index(substring, @offset + start_index))
183
183
  index - @offset
184
- elsif (index = @write_buffer.index(substring, start_index - read_buffer_length + @offset))
185
- index + read_buffer_length - @offset
184
+ elsif start_index + substring.bytesize <= read_buffer_length - @offset + @write_buffer.bytesize
185
+ merge_read_buffer
186
+ start_index = read_buffer_length - substring.bytesize if read_buffer_length - substring.bytesize > start_index
187
+ @read_buffer.index(substring, start_index)
186
188
  else
187
189
  nil
188
190
  end
@@ -298,5 +300,11 @@ module Ione
298
300
  @read_buffer = @write_buffer
299
301
  @write_buffer = ''
300
302
  end
303
+
304
+ def merge_read_buffer
305
+ @read_buffer = @read_buffer[@offset, @read_buffer.length - @offset] << @write_buffer
306
+ @write_buffer = ''
307
+ @offset = 0
308
+ end
301
309
  end
302
310
  end
@@ -209,6 +209,8 @@ module Ione
209
209
  end
210
210
  if futures.count == 0
211
211
  resolved([])
212
+ elsif (failed = futures.find { |f| f.respond_to?(:failed?) && f.failed? })
213
+ failed
212
214
  else
213
215
  CombinedFuture.new(futures)
214
216
  end
@@ -231,6 +233,7 @@ module Ione
231
233
  if futures.size == 1 && (fs = futures.first).is_a?(Enumerable)
232
234
  *futures = *fs
233
235
  end
236
+ futures.reject! { |f| f.respond_to?(:resolved?) && f.resolved? }
234
237
  if futures.count == 0
235
238
  ResolvedFuture::NIL
236
239
  elsif futures.count == 1
@@ -262,7 +265,9 @@ module Ione
262
265
  futures = fs
263
266
  end
264
267
  if futures.count == 0
265
- resolved
268
+ ResolvedFuture::NIL
269
+ elsif (done = futures.find { |f| f.respond_to?(:resolved?) && f.resolved? })
270
+ done
266
271
  else
267
272
  FirstFuture.new(futures)
268
273
  end
@@ -874,64 +879,56 @@ module Ione
874
879
  def initialize(futures, initial_value, reducer)
875
880
  super()
876
881
  @futures = Array(futures)
877
- @remaining = @futures.size
878
- @initial_value = initial_value
879
- @accumulator = initial_value.nil? ? NO_INITIAL_VALUE : initial_value
882
+ @initial_value = initial_value.nil? ? NO_INITIAL_VALUE : initial_value
880
883
  @reducer = reducer
881
884
  end
882
-
883
- private
884
-
885
- def reduce_one(value)
886
- unless failed?
887
- @lock.lock
888
- begin
889
- if @accumulator.equal?(NO_INITIAL_VALUE)
890
- @accumulator = value
891
- else
892
- @accumulator = @reducer.call(@accumulator, value)
893
- end
894
- @remaining -= 1
895
- rescue => e
896
- @lock.unlock
897
- fail(e)
898
- else
899
- @lock.unlock
900
- end
901
- unless failed?
902
- if @remaining == 0
903
- resolve(@accumulator)
904
- :done
905
- else
906
- :continue
907
- end
908
- end
909
- end
910
- end
911
885
  end
912
886
 
913
887
  # @private
914
888
  class OrderedReducingFuture < ReducingFuture
915
889
  def initialize(futures, initial_value, reducer)
916
890
  super
917
- if @remaining > 0
918
- reduce_next(0)
891
+ if @futures.empty?
892
+ resolve(@initial_value.equal?(NO_INITIAL_VALUE) ? nil : @initial_value)
893
+ elsif @initial_value.equal?(NO_INITIAL_VALUE)
894
+ @futures.shift.on_complete(&method(:reduce_next))
919
895
  else
920
- resolve(@initial_value)
896
+ reduce_next(@initial_value, nil)
921
897
  end
922
898
  end
923
899
 
924
900
  private
925
901
 
926
- def reduce_next(i)
927
- @futures[i].on_complete do |v, e|
928
- unless failed?
929
- if e
930
- fail(e)
931
- elsif reduce_one(v) == :continue
932
- reduce_next(i + 1)
902
+ def reduce_next(accumulator, e)
903
+ if e
904
+ @futures = nil
905
+ fail(e)
906
+ elsif @futures.empty?
907
+ @futures = nil
908
+ resolve(accumulator)
909
+ else
910
+ outer = Thread.current
911
+ looping = more = true
912
+ while more
913
+ more = false
914
+ @futures.shift.on_complete do |v, ee|
915
+ if ee
916
+ reduce_next(nil, ee)
917
+ else
918
+ begin
919
+ accumulator = @reducer.call(accumulator, v)
920
+ if @futures.empty? || !looping || !Thread.current.equal?(outer)
921
+ reduce_next(accumulator, nil)
922
+ else
923
+ more = true
924
+ end
925
+ rescue => eee
926
+ reduce_next(nil, eee)
927
+ end
928
+ end
933
929
  end
934
930
  end
931
+ looping = false
935
932
  end
936
933
  end
937
934
  end
@@ -940,20 +937,37 @@ module Ione
940
937
  class UnorderedReducingFuture < ReducingFuture
941
938
  def initialize(futures, initial_value, reducer)
942
939
  super
943
- if @remaining > 0
944
- futures.each do |f|
940
+ if @futures.empty?
941
+ resolve(@initial_value.equal?(NO_INITIAL_VALUE) ? nil : @initial_value)
942
+ else
943
+ accumulator = @initial_value
944
+ remaining = @futures.size
945
+ @futures.each do |f|
945
946
  f.on_complete do |v, e|
946
947
  unless failed?
947
948
  if e
948
949
  fail(e)
949
950
  else
950
- reduce_one(v)
951
+ done = false
952
+ @lock.lock
953
+ begin
954
+ accumulator = accumulator.equal?(NO_INITIAL_VALUE) ? v : @reducer.call(accumulator, v)
955
+ remaining -= 1
956
+ done = (remaining == 0)
957
+ rescue => ee
958
+ @lock.unlock
959
+ fail(ee)
960
+ else
961
+ @lock.unlock
962
+ end
963
+ if done
964
+ @futures = nil
965
+ resolve(accumulator)
966
+ end
951
967
  end
952
968
  end
953
969
  end
954
970
  end
955
- else
956
- resolve(@initial_value)
957
971
  end
958
972
  end
959
973
  end
@@ -124,7 +124,7 @@ module Ione
124
124
  # after {#stop} has been called, but false when the future returned by
125
125
  # {#stop} completes.
126
126
  def running?
127
- @state == RUNNING_STATE
127
+ (state = @state) == RUNNING_STATE || state == STOPPING_STATE
128
128
  end
129
129
 
130
130
  # Starts the reactor. This will spawn a background thread that will manage
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Ione
4
- VERSION = '1.2.2'.freeze
4
+ VERSION = '1.2.3'.freeze
5
5
  end
@@ -354,6 +354,20 @@ module Ione
354
354
  buffer.append(' baz baz')
355
355
  buffer.index('baz', 8).should == 11
356
356
  end
357
+
358
+ it 'returns the first index when the matching substring spans the read and write buffer' do
359
+ buffer.append('foo bar')
360
+ buffer.read(1)
361
+ buffer.append('bar barbar')
362
+ buffer.index('barbar', 0).should == 3
363
+ end
364
+
365
+ it 'returns nil when the substring does not fit in the search space' do
366
+ buffer.append('foo')
367
+ buffer.read(1)
368
+ buffer.append('bar')
369
+ buffer.index('bar', 3).should be_nil
370
+ end
357
371
  end
358
372
 
359
373
  context 'when reading and appending' do
@@ -916,6 +916,12 @@ module Ione
916
916
  future.value.should == 6
917
917
  end
918
918
 
919
+ it 'handles a really long list of futures' do
920
+ futures = Array.new(10000, Future.resolved(1))
921
+ future = Future.reduce(futures, 0, &:+)
922
+ future.value.should eq(10000)
923
+ end
924
+
919
925
  context 'when the :ordered option is false' do
920
926
  it 'calls the block with the values in the order of completion, when the :ordered option is false' do
921
927
  promises = [Promise.new, Promise.new, Promise.new]
@@ -949,6 +955,12 @@ module Ione
949
955
  future.should be_failed
950
956
  end
951
957
 
958
+ it 'handles a really long list of futures' do
959
+ futures = Array.new(10000, Future.resolved(1))
960
+ future = Future.reduce(futures, 0, ordered: false, &:+)
961
+ future.value.should eq(10000)
962
+ end
963
+
952
964
  context 'when the list of futures is empty' do
953
965
  it 'returns a future that resolves to the initial value' do
954
966
  Future.reduce([], :foo, ordered: false).value.should == :foo
@@ -93,6 +93,7 @@ module Ione
93
93
  end
94
94
 
95
95
  it 'restarts the reactor even when restarted before a failed stop' do
96
+ pending 'This test is broken in JRuby' if RUBY_ENGINE == 'jruby'
96
97
  barrier = Queue.new
97
98
  selector.handler do
98
99
  if barrier.pop == :fail
@@ -171,12 +172,27 @@ module Ione
171
172
  reactor.stop.value.should equal(reactor)
172
173
  end
173
174
 
174
- it 'is not running after being stopped' do
175
+ it 'is not running after stop completed' do
175
176
  reactor.start.value
176
177
  reactor.stop.value
177
178
  reactor.should_not be_running
178
179
  end
179
180
 
181
+ it 'keeps running until stop completed' do
182
+ running_barrier = Queue.new
183
+ stop_barrier = Queue.new
184
+ selector.handler do
185
+ running_barrier.push(nil)
186
+ stop_barrier.pop
187
+ [[], [], []]
188
+ end
189
+ reactor.start.value
190
+ future = reactor.stop
191
+ running_barrier.pop
192
+ reactor.should be_running
193
+ stop_barrier.push(nil) until future.completed?
194
+ end
195
+
180
196
  it 'closes all sockets' do
181
197
  reactor.start.value
182
198
  connection = reactor.connect('example.com', 9999, 5).value
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ione
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theo Hultberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-21 00:00:00.000000000 Z
11
+ date: 2015-10-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Reactive programming framework for Ruby, painless evented IO, futures
14
14
  and an efficient byte buffer