ione 1.2.2 → 1.2.3

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 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