polyphony 0.59.1 → 0.63

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.
@@ -101,16 +101,20 @@ class ::IO
101
101
  return @read_buffer.slice!(0) if @read_buffer && !@read_buffer.empty?
102
102
 
103
103
  @read_buffer ||= +''
104
- Polyphony.backend_read(self, @read_buffer, 8192, false)
104
+ Polyphony.backend_read(self, @read_buffer, 8192, false, -1)
105
105
  return @read_buffer.slice!(0) if !@read_buffer.empty?
106
106
 
107
107
  nil
108
108
  end
109
109
 
110
110
  alias_method :orig_read, :read
111
- def read(len = nil)
111
+ def read(len = nil, buf = nil, buf_pos = 0)
112
+ if buf
113
+ return Polyphony.backend_read(self, buf, len, true, buf_pos)
114
+ end
115
+
112
116
  @read_buffer ||= +''
113
- result = Polyphony.backend_read(self, @read_buffer, len, true)
117
+ result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
114
118
  return nil unless result
115
119
 
116
120
  already_read = @read_buffer
@@ -119,8 +123,8 @@ class ::IO
119
123
  end
120
124
 
121
125
  alias_method :orig_readpartial, :read
122
- def readpartial(len, str = +'')
123
- result = Polyphony.backend_read(self, str, len, false)
126
+ def readpartial(len, str = +'', buffer_pos = 0)
127
+ result = Polyphony.backend_read(self, str, len, false, buffer_pos)
124
128
  raise EOFError unless result
125
129
 
126
130
  result
@@ -151,9 +155,10 @@ class ::IO
151
155
  idx = @read_buffer.index(sep)
152
156
  return @read_buffer.slice!(0, idx + sep_size) if idx
153
157
 
154
- data = readpartial(8192, +'')
155
- return nil unless data
156
- @read_buffer << data
158
+ result = readpartial(8192, @read_buffer, -1)
159
+
160
+ #Polyphony.backend_read(self, @read_buffer, 8192, false, -1)
161
+ return nil unless result
157
162
  end
158
163
  rescue EOFError
159
164
  return nil
@@ -216,8 +221,8 @@ class ::IO
216
221
  buf ? readpartial(maxlen, buf) : readpartial(maxlen)
217
222
  end
218
223
 
219
- def read_loop(&block)
220
- Polyphony.backend_read_loop(self, &block)
224
+ def read_loop(maxlen = 8192, &block)
225
+ Polyphony.backend_read_loop(self, maxlen, &block)
221
226
  end
222
227
 
223
228
  def feed_loop(receiver, method = :call, &block)
@@ -64,13 +64,37 @@ class ::OpenSSL::SSL::SSLSocket
64
64
  # @sync = osync
65
65
  end
66
66
 
67
- def readpartial(maxlen, buf = +'')
68
- result = sysread(maxlen, buf)
67
+ alias_method :orig_read, :read
68
+ def read(maxlen = nil, buf = nil, buf_pos = 0)
69
+ return readpartial(maxlen, buf, buf_pos) if buf
70
+
71
+ buf = +''
72
+ return readpartial(maxlen, buf) if maxlen
73
+
74
+ while true
75
+ readpartial(4096, buf, -1)
76
+ end
77
+ rescue EOFError
78
+ buf
79
+ end
80
+
81
+ def readpartial(maxlen, buf = +'', buffer_pos = 0)
82
+ if buffer_pos != 0
83
+ if (result = sysread(maxlen, +''))
84
+ if buffer_pos == -1
85
+ result = buf + result
86
+ else
87
+ result = buf[0...buffer_pos] + result
88
+ end
89
+ end
90
+ else
91
+ result = sysread(maxlen, buf)
92
+ end
69
93
  result || (raise EOFError)
70
94
  end
71
95
 
72
- def read_loop
73
- while (data = sysread(8192))
96
+ def read_loop(maxlen = 8192)
97
+ while (data = sysread(maxlen))
74
98
  yield data
75
99
  end
76
100
  end
@@ -22,12 +22,29 @@ class ::Socket
22
22
  Polyphony.backend_connect(self, addr.ip_address, addr.ip_port)
23
23
  end
24
24
 
25
+ alias_method :orig_read, :read
26
+ def read(maxlen = nil, buf = nil, buf_pos = 0)
27
+ return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
28
+ return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
29
+
30
+ buf = +''
31
+ len = buf.bytesize
32
+ while true
33
+ Polyphony.backend_recv(self, buf, maxlen || 4096, -1)
34
+ new_len = buf.bytesize
35
+ break if new_len == len
36
+
37
+ len = new_len
38
+ end
39
+ buf
40
+ end
41
+
25
42
  def recv(maxlen, flags = 0, outbuf = nil)
26
- Polyphony.backend_recv(self, outbuf || +'', maxlen)
43
+ Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
27
44
  end
28
45
 
29
- def recv_loop(&block)
30
- Polyphony.backend_recv_loop(self, &block)
46
+ def recv_loop(maxlen = 8192, &block)
47
+ Polyphony.backend_recv_loop(self, maxlen, &block)
31
48
  end
32
49
  alias_method :read_loop, :recv_loop
33
50
 
@@ -60,8 +77,8 @@ class ::Socket
60
77
  # Polyphony.backend_send(self, mesg, 0)
61
78
  # end
62
79
 
63
- def readpartial(maxlen, str = +'')
64
- Polyphony.backend_recv(self, str, maxlen)
80
+ def readpartial(maxlen, str = +'', buffer_pos = 0)
81
+ Polyphony.backend_recv(self, str, maxlen, buffer_pos)
65
82
  end
66
83
 
67
84
  ZERO_LINGER = [0, 0].pack('ii').freeze
@@ -140,12 +157,29 @@ class ::TCPSocket
140
157
  setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEPORT, 1)
141
158
  end
142
159
 
160
+ alias_method :orig_read, :read
161
+ def read(maxlen = nil, buf = nil, buf_pos = 0)
162
+ return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
163
+ return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
164
+
165
+ buf = +''
166
+ len = buf.bytesize
167
+ while true
168
+ Polyphony.backend_recv(self, buf, maxlen || 4096, -1)
169
+ new_len = buf.bytesize
170
+ break if new_len == len
171
+
172
+ len = new_len
173
+ end
174
+ buf
175
+ end
176
+
143
177
  def recv(maxlen, flags = 0, outbuf = nil)
144
- Polyphony.backend_recv(self, outbuf || +'', maxlen)
178
+ Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
145
179
  end
146
180
 
147
- def recv_loop(&block)
148
- Polyphony.backend_recv_loop(self, &block)
181
+ def recv_loop(maxlen = 8192, &block)
182
+ Polyphony.backend_recv_loop(self, maxlen, &block)
149
183
  end
150
184
  alias_method :read_loop, :recv_loop
151
185
 
@@ -165,8 +199,8 @@ class ::TCPSocket
165
199
  # Polyphony.backend_send(self, mesg, 0)
166
200
  # end
167
201
 
168
- def readpartial(maxlen, str = +'')
169
- result = Polyphony.backend_recv(self, str, maxlen)
202
+ def readpartial(maxlen, str = +'', buffer_pos = 0)
203
+ result = Polyphony.backend_recv(self, str, maxlen, buffer_pos)
170
204
  raise EOFError unless result
171
205
 
172
206
  str
@@ -217,12 +251,29 @@ class ::UNIXServer
217
251
  end
218
252
 
219
253
  class ::UNIXSocket
254
+ alias_method :orig_read, :read
255
+ def read(maxlen = nil, buf = nil, buf_pos = 0)
256
+ return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
257
+ return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
258
+
259
+ buf = +''
260
+ len = buf.bytesize
261
+ while true
262
+ Polyphony.backend_recv(self, buf, maxlen || 4096, -1)
263
+ new_len = buf.bytesize
264
+ break if new_len == len
265
+
266
+ len = new_len
267
+ end
268
+ buf
269
+ end
270
+
220
271
  def recv(maxlen, flags = 0, outbuf = nil)
221
- Polyphony.backend_recv(self, outbuf || +'', maxlen)
272
+ Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
222
273
  end
223
274
 
224
- def recv_loop(&block)
225
- Polyphony.backend_recv_loop(self, &block)
275
+ def recv_loop(maxlen = 8192, &block)
276
+ Polyphony.backend_recv_loop(self, maxlen, &block)
226
277
  end
227
278
  alias_method :read_loop, :recv_loop
228
279
 
@@ -242,8 +293,8 @@ class ::UNIXSocket
242
293
  Polyphony.backend_send(self, mesg, 0)
243
294
  end
244
295
 
245
- def readpartial(maxlen, str = +'')
246
- result = Polyphony.backend_recv(self, str, maxlen)
296
+ def readpartial(maxlen, str = +'', buffer_pos = 0)
297
+ result = Polyphony.backend_recv(self, str, maxlen, buffer_pos)
247
298
  raise EOFError unless result
248
299
 
249
300
  str
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.59.1'
4
+ VERSION = '0.63'
5
5
  end
data/polyphony.gemspec CHANGED
@@ -29,13 +29,6 @@ Gem::Specification.new do |s|
29
29
  s.add_development_dependency 'pry', '0.13.1'
30
30
 
31
31
  s.add_development_dependency 'msgpack', '1.4.2'
32
- s.add_development_dependency 'pg', '1.1.4'
33
- s.add_development_dependency 'redis', '4.1.0'
34
- s.add_development_dependency 'hiredis', '0.6.3'
35
- s.add_development_dependency 'http_parser.rb', '~>0.6.0'
36
- s.add_development_dependency 'rack', '>=2.0.8', '<2.3.0'
37
- s.add_development_dependency 'mysql2', '0.5.3'
38
- s.add_development_dependency 'sequel', '5.34.0'
39
32
  s.add_development_dependency 'httparty', '0.17.1'
40
33
  s.add_development_dependency 'localhost', '~>1.1.4'
41
34
 
data/test/test_backend.rb CHANGED
@@ -26,14 +26,14 @@ class BackendTest < MiniTest::Test
26
26
  @backend.sleep 0.01
27
27
  count += 1
28
28
  }.await
29
- assert_in_delta 0.03, Time.now - t0, 0.01
29
+ assert_in_range 0.02..0.04, Time.now - t0
30
30
  assert_equal 3, count
31
31
  end
32
32
 
33
33
  def test_write_read_partial
34
34
  i, o = IO.pipe
35
35
  buf = +''
36
- f = spin { @backend.read(i, buf, 5, false) }
36
+ f = spin { @backend.read(i, buf, 5, false, 0) }
37
37
  @backend.write(o, 'Hello world')
38
38
  return_value = f.await
39
39
 
@@ -44,7 +44,7 @@ class BackendTest < MiniTest::Test
44
44
  def test_write_read_to_eof_limited_buffer
45
45
  i, o = IO.pipe
46
46
  buf = +''
47
- f = spin { @backend.read(i, buf, 5, true) }
47
+ f = spin { @backend.read(i, buf, 5, true, 0) }
48
48
  @backend.write(o, 'Hello')
49
49
  snooze
50
50
  @backend.write(o, ' world')
@@ -59,7 +59,7 @@ class BackendTest < MiniTest::Test
59
59
  def test_write_read_to_eof
60
60
  i, o = IO.pipe
61
61
  buf = +''
62
- f = spin { @backend.read(i, buf, 10**6, true) }
62
+ f = spin { @backend.read(i, buf, 10**6, true, 0) }
63
63
  @backend.write(o, 'Hello')
64
64
  snooze
65
65
  @backend.write(o, ' world')
@@ -71,6 +71,59 @@ class BackendTest < MiniTest::Test
71
71
  assert_equal return_value, buf
72
72
  end
73
73
 
74
+ def test_write_read_with_buffer_position
75
+ i, o = IO.pipe
76
+ buf = +'abcdefghij'
77
+ f = spin { @backend.read(i, buf, 20, false, 0) }
78
+ @backend.write(o, 'blah')
79
+ return_value = f.await
80
+
81
+ assert_equal 'blah', buf
82
+ assert_equal return_value, buf
83
+
84
+ buf = +'abcdefghij'
85
+ f = spin { @backend.read(i, buf, 20, false, -1) }
86
+ @backend.write(o, 'klmn')
87
+ return_value = f.await
88
+
89
+ assert_equal 'abcdefghijklmn', buf
90
+ assert_equal return_value, buf
91
+
92
+ buf = +'abcdefghij'
93
+ f = spin { @backend.read(i, buf, 20, false, 3) }
94
+ @backend.write(o, 'DEF')
95
+ return_value = f.await
96
+
97
+ assert_equal 'abcDEF', buf
98
+ assert_equal return_value, buf
99
+ end
100
+
101
+ def test_read_concat_big
102
+ i, o = IO.pipe
103
+
104
+ body = " " * 4000
105
+
106
+ data = "post /?q=time&blah=blah HTTP/1\r\nHost: dev.realiteq.net\r\n\r\n" +
107
+ "get /?q=time HTTP/1.1\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}" +
108
+ "get /?q=time HTTP/1.1\r\nCookie: foo\r\nCookie: bar\r\n\r\n"
109
+
110
+ o << data
111
+ o.close
112
+
113
+ buf = +''
114
+
115
+ @backend.read(i, buf, 4096, false, -1)
116
+ assert_equal 4096, buf.bytesize
117
+
118
+ @backend.read(i, buf, 1, false, -1)
119
+ assert_equal 4097, buf.bytesize
120
+
121
+ @backend.read(i, buf, 4096, false, -1)
122
+
123
+ assert_equal data.bytesize, buf.bytesize
124
+ assert_equal data, buf
125
+ end
126
+
74
127
  def test_waitpid
75
128
  pid = fork do
76
129
  @backend.post_fork
@@ -87,7 +140,7 @@ class BackendTest < MiniTest::Test
87
140
  buf = []
88
141
  f = spin do
89
142
  buf << :ready
90
- @backend.read_loop(i) { |d| buf << d }
143
+ @backend.read_loop(i, 8192) { |d| buf << d }
91
144
  buf << :done
92
145
  end
93
146
 
@@ -107,7 +160,7 @@ class BackendTest < MiniTest::Test
107
160
  parent = spin do
108
161
  f = spin do
109
162
  buf << :ready
110
- @backend.read_loop(i) { |d| buf << d }
163
+ @backend.read_loop(i, 8192) { |d| buf << d }
111
164
  buf << :done
112
165
  end
113
166
  suspend
@@ -125,6 +178,16 @@ class BackendTest < MiniTest::Test
125
178
  assert_equal [:ready, 'foo', 'bar'], buf
126
179
  end
127
180
 
181
+ def test_read_loop_with_max_len
182
+ r, w = IO.pipe
183
+
184
+ w << 'foobar'
185
+ w.close
186
+ buf = []
187
+ @backend.read_loop(r, 3) { |data| buf << data }
188
+ assert_equal ['foo', 'bar'], buf
189
+ end
190
+
128
191
  Net = Polyphony::Net
129
192
 
130
193
  def test_accept
data/test/test_ext.rb CHANGED
@@ -42,7 +42,7 @@ class ExceptionTest < MiniTest::Test
42
42
  end
43
43
 
44
44
  class ProcessTest < MiniTest::Test
45
- def test_detach
45
+ def test_process_detach
46
46
  pid = Polyphony.fork { sleep 0.05; exit! 42 }
47
47
  buffer = []
48
48
  spin { 3.times { |i| buffer << i; snooze } }
data/test/test_fiber.rb CHANGED
@@ -43,6 +43,14 @@ class FiberTest < MiniTest::Test
43
43
  f&.stop
44
44
  end
45
45
 
46
+ def test_await_dead_children
47
+ f1 = spin { :foo }
48
+ f2 = spin { :bar }
49
+ 2.times { snooze }
50
+
51
+ assert_equal [:foo, :bar], Fiber.await(f1, f2)
52
+ end
53
+
46
54
  def test_await_from_multiple_fibers
47
55
  buffer = []
48
56
  f1 = spin {
@@ -348,12 +356,12 @@ class FiberTest < MiniTest::Test
348
356
  assert_equal [:foo, :terminate], buffer
349
357
  end
350
358
 
351
- CMD_TERMINATE_MAIN_FIBER = <<~BASH
352
- ruby -rbundler/setup -rpolyphony -e"spin { sleep 0.1; Thread.current.main_fiber.terminate }; begin; sleep; rescue Polyphony::Terminate; STDOUT << 'terminated'; end" 2>&1
359
+ CMD_TERMINATE_CHILD_FIBER = <<~BASH
360
+ ruby -rbundler/setup -rpolyphony -e'f = spin { sleep }; spin { sleep 0.1; f.terminate }; f.await' 2>&1
353
361
  BASH
354
362
 
355
- CMD_TERMINATE_CHILD_FIBER = <<~BASH
356
- ruby -rbundler/setup -rpolyphony -e"f = spin { sleep }; spin { sleep 0.1; f.terminate }; f.await" 2>&1
363
+ CMD_TERMINATE_MAIN_FIBER = <<~BASH
364
+ ruby -rbundler/setup -rpolyphony -e"spin { sleep 0.1; Thread.current.main_fiber.terminate }; begin; sleep; rescue Polyphony::Terminate; STDOUT << 'terminated'; end" 2>&1
357
365
  BASH
358
366
 
359
367
  def test_terminate_main_fiber
@@ -547,24 +555,38 @@ class FiberTest < MiniTest::Test
547
555
  assert f.location =~ location
548
556
  end
549
557
 
550
- def test_when_done
551
- flag = nil
552
- values = []
553
- f = spin do
554
- snooze until flag
558
+ def test_monitor
559
+ child = nil
560
+ parent = spin do
561
+ child = spin { receive }
562
+ child.await
555
563
  end
556
- f.when_done { values << 42 }
557
564
 
558
565
  snooze
559
- assert values.empty?
560
- snooze
561
- flag = true
562
- assert values.empty?
563
- assert f.alive?
566
+ child.monitor
567
+ spin { child << :foo }
568
+
569
+ msg = receive
570
+ assert_equal [child, :foo], msg
571
+ end
564
572
 
573
+ def test_unmonitor
574
+ child = nil
575
+ parent = spin(:parent) do
576
+ child = spin(:child) { receive }
577
+ child.await
578
+ end
579
+
580
+ snooze
581
+ child.monitor
582
+ spin { child << :foo }
565
583
  snooze
566
- assert_equal [42], values
567
- assert !f.running?
584
+
585
+ child.unmonitor
586
+
587
+ Fiber.current << :bar
588
+ msg = receive
589
+ assert_equal :bar, msg
568
590
  end
569
591
 
570
592
  def test_children
@@ -732,6 +754,72 @@ class FiberTest < MiniTest::Test
732
754
  assert_equal ['bar'], buffer
733
755
  snooze
734
756
  end
757
+
758
+ def test_detach
759
+ buf = []
760
+ child = nil
761
+ parent = spin(:parent) do
762
+ buf << :hi_from_parent
763
+ child = spin(:child) do
764
+ buf << :hi_from_child
765
+ # wait for message (from main fiber)
766
+ buf << receive
767
+ end
768
+ snooze
769
+ buf << :bye_from_parent
770
+ end
771
+
772
+ snooze
773
+ assert_equal parent, child.parent
774
+ child.detach
775
+ assert_equal Fiber.current, child.parent
776
+ parent.await
777
+
778
+ child << :bye
779
+ child.await
780
+
781
+ assert_equal [
782
+ :hi_from_parent,
783
+ :hi_from_child,
784
+ :bye_from_parent,
785
+ :bye
786
+ ], buf
787
+ end
788
+
789
+ def test_attach
790
+ buf = []
791
+ child = nil
792
+ parent = spin(:parent) do
793
+ buf << :hi_from_parent
794
+ child = spin(:child) do
795
+ buf << :hi_from_child
796
+ # wait for message (from main fiber)
797
+ buf << receive
798
+ end
799
+ snooze
800
+ buf << :bye_from_parent
801
+ end
802
+
803
+ new_parent = spin(:new_parent) { buf << receive }
804
+
805
+ snooze
806
+ assert_equal parent, child.parent
807
+ child.attach(new_parent)
808
+ assert_equal new_parent, child.parent
809
+ parent.await
810
+
811
+ child << :bye
812
+ new_parent << :bye_new_parent
813
+ snooze
814
+
815
+ assert_equal [
816
+ :hi_from_parent,
817
+ :hi_from_child,
818
+ :bye_from_parent,
819
+ :bye,
820
+ :bye_new_parent
821
+ ], buf
822
+ end
735
823
  end
736
824
 
737
825
  class MailboxTest < MiniTest::Test
@@ -964,7 +1052,7 @@ class FiberControlTest < MiniTest::Test
964
1052
  assert_equal 'foo', result.message
965
1053
  assert_equal f1, result.source_fiber
966
1054
  assert_equal :dead, f1.state
967
- assert_equal :dead, f2.state
1055
+ assert_equal :waiting, f2.state
968
1056
  end
969
1057
 
970
1058
  def test_select_with_interruption