polyphony 0.43.5 → 0.43.6

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
  SHA256:
3
- metadata.gz: 55e44a81e7358528fabd37e1d48b6387957bc6001e4d947bf6c881d2425953d9
4
- data.tar.gz: 45af7e485891927a1e9f88e8a6342692c25f306aa60e40fa8a74c0ca8494d3d4
3
+ metadata.gz: b048cfa1e0d7cd542840ab9f2198349b2474d40a6d943b584d1bcb57593ca41d
4
+ data.tar.gz: 0d9ed9fc45ec2165018e61f8befbdefb5668cfcf4b7628a648a055f5b6052e4c
5
5
  SHA512:
6
- metadata.gz: 444675baf3131ffc843b61649b92ce5ca7d77773277db750d8c8ac80a88ccd133e6f60d61282fa38ffb91de59eaf2304ea9b0fca196a7eb61c7a53becaa1fe46
7
- data.tar.gz: f21e26a41c8dfeea0d803b5b9bc82b1e648bf0ca588225f721560c432f363020b37561c59daeefbe2d434b012f1f5f767460557939a22d04e78e40471813a8ca
6
+ metadata.gz: a962cb0db032fd58a8db4024d9a6ad2d1be5307caff72d9508bdf879bafbd6c55a5c79e9bc69a9d3bda96d2f72fda51ed2f978e96fa0ca636458284e9e9dbbaf
7
+ data.tar.gz: 2b419313309e898003399f780abcf7641de34c3350ae5d7c10c785209e3e6c12e4d741b01676a49ec1ec2f3f15ea8f9001636ec44880e13583d68168f82c9cb7
@@ -1,3 +1,11 @@
1
+ ## 0.43.6 2020-07-18
2
+
3
+ * Allow brute-force interrupting with second Ctrl-C
4
+ * Fix outgoing SSL connections (#28)
5
+ * Improve Fiber#await_all_children with many children
6
+ * Use `writev` for writing multiple strings
7
+ * Add logo (thanks [Gerald](https://webocube.com/)!)
8
+
1
9
  ## 0.43.5 2020-07-13
2
10
 
3
11
  * Fix `#read_nonblock`, `#write_nonblock` for `IO` and `Socket` (#27)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.43.5)
4
+ polyphony (0.43.6)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <p align="center"><img src="docs/polyphony-logo.png" /></p>
2
+
1
3
  # Polyphony - Fine-Grained Concurrency for Ruby
2
4
 
3
5
  [![Gem Version](https://badge.fury.io/rb/polyphony.svg)](http://rubygems.org/gems/polyphony)
@@ -0,0 +1,40 @@
1
+ <head>
2
+ <meta charset="UTF-8">
3
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge">
4
+
5
+ {% unless site.plugins contains "jekyll-seo-tag" %}
6
+ <title>{{ page.title }} - {{ site.title }}</title>
7
+
8
+ {% if page.description %}
9
+ <meta name="Description" content="{{ page.description }}">
10
+ {% endif %}
11
+ {% endunless %}
12
+
13
+ <link rel="shortcut icon" href="{{ 'polyphony-logo.png' | absolute_url }}" type="image/png">
14
+
15
+ <link rel="stylesheet" href="{{ '/assets/css/just-the-docs-default.css' | absolute_url }}">
16
+
17
+ {% if site.ga_tracking != nil %}
18
+ <script async src="https://www.googletagmanager.com/gtag/js?id={{ site.ga_tracking }}"></script>
19
+ <script>
20
+ window.dataLayer = window.dataLayer || [];
21
+ function gtag(){dataLayer.push(arguments);}
22
+ gtag('js', new Date());
23
+
24
+ gtag('config', '{{ site.ga_tracking }}'{% unless site.ga_tracking_anonymize_ip == nil %}, { 'anonymize_ip': true }{% endunless %});
25
+ </script>
26
+
27
+ {% endif %}
28
+
29
+ {% if site.search_enabled != false %}
30
+ <script type="text/javascript" src="{{ '/assets/js/vendor/lunr.min.js' | absolute_url }}"></script>
31
+ {% endif %}
32
+ <script type="text/javascript" src="{{ '/assets/js/just-the-docs.js' | absolute_url }}"></script>
33
+
34
+ <meta name="viewport" content="width=device-width, initial-scale=1">
35
+
36
+ {% seo %}
37
+
38
+ {% include head_custom.html %}
39
+
40
+ </head>
@@ -0,0 +1 @@
1
+ <img src="{{ 'polyphony-logo.png' | absolute_url }}" style="height: 1.5em; margin-right: 0.5em">Polyphony
@@ -26,9 +26,9 @@ the entire request body.
26
26
  ## A basic web server
27
27
 
28
28
  ```ruby
29
- require 'polyphony/http'
29
+ require 'tipi'
30
30
 
31
- Polyphony::HTTP::Server.serve('0.0.0.0', 1234) do |request|
31
+ Tipi.serve('0.0.0.0', 1234) do |request|
32
32
  request.respond("Hello world!\n")
33
33
  end
34
34
  ```
@@ -55,13 +55,13 @@ TLS termination can be handled by passing a `secure_context` option to the
55
55
  server:
56
56
 
57
57
  ```ruby
58
- require 'polyphony/http'
58
+ require 'tipi'
59
59
  require 'localhost/authority'
60
60
 
61
61
  authority = Localhost::Authority.fetch
62
62
  opts = { secure_context: authority.server_context }
63
63
 
64
- Polyphony::HTTP::Server.serve('0.0.0.0', 1234, opts) do |request|
64
+ Tipi.serve('0.0.0.0', 1234, opts) do |request|
65
65
  request.respond("Hello world!\n")
66
66
  end
67
67
  ```
@@ -72,8 +72,8 @@ Polyphony's web server makes it really easy to integrate websocket communication
72
72
  with normal HTTP processing:
73
73
 
74
74
  ```ruby
75
- require 'polyphony/http'
76
- require 'polyphony/websocket'
75
+ require 'tipi'
76
+ require 'tipi/websocket'
77
77
 
78
78
  ws_handler = Polyphony::Websocket.handler do |ws|
79
79
  while (msg = ws.recv)
@@ -85,7 +85,7 @@ opts = {
85
85
  upgrade: { websocket: ws_handler }
86
86
  }
87
87
 
88
- Polyphony::HTTP::Server.serve('0.0.0.0', 1234, opts) do |request|
88
+ Tipi.serve('0.0.0.0', 1234, opts) do |request|
89
89
  request.respond("Hello world!\n")
90
90
  end
91
91
  ```
@@ -93,7 +93,7 @@ end
93
93
  Polyphony also supports general-purpose HTTP upgrades using the same mechanism:
94
94
 
95
95
  ```ruby
96
- require 'polyphony/http'
96
+ require 'tipi'
97
97
 
98
98
  opts = {
99
99
  upgrade: {
@@ -105,7 +105,7 @@ opts = {
105
105
  }
106
106
  }
107
107
 
108
- Polyphony::HTTP::Server.serve('0.0.0.0', 1234, opts) do |request|
108
+ Tipi.serve('0.0.0.0', 1234, opts) do |request|
109
109
  request.respond("Hello world!\n")
110
110
  end
111
111
  ```
@@ -117,7 +117,7 @@ and enables streaming (using chunked encoding for HTTP/1.1 connections). Here's
117
117
  an example of an SSE response:
118
118
 
119
119
  ```ruby
120
- require 'polyphony/http'
120
+ require 'tipi'
121
121
 
122
122
  def sse_response(request)
123
123
  request.send_headers('Content-Type': 'text/event-stream')
@@ -131,6 +131,6 @@ ensure
131
131
  request.send_chunk("retry: 0\n\n", done: true)
132
132
  end
133
133
 
134
- Polyphony::HTTP::Server.serve('0.0.0.0', 1234, &method(:sse_response))
134
+ Tipi.serve('0.0.0.0', 1234, &method(:sse_response))
135
135
  ```
136
136
 
@@ -6,6 +6,8 @@ permalink: /
6
6
  next_title: Installing Polyphony
7
7
  ---
8
8
 
9
+ <p align="center"><img src="{{ 'polyphony-logo.png' | absolute_url }}" /></p>
10
+
9
11
  # Polyphony
10
12
  {:.text-center .logo-title}
11
13
 
@@ -21,7 +23,7 @@ for I/O, timers, and other asynchronous events.
21
23
  [Overview](getting-started/overview){: .btn .btn-green .text-gamma }
22
24
  [Take the tutorial](getting-started/tutorial){: .btn .btn-blue .text-gamma }
23
25
  [Source code](https://github.com/digital-fabric/polyphony){: .btn .btn-purple .text-gamma target="_blank" }
24
- {: .mt-6 .h-align-center }
26
+ {:.text-center .mt-6 .h-align-center }
25
27
 
26
28
  ## Focused on Developer Happiness
27
29
 
Binary file
@@ -1,37 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # idea taken from the example given in trio:
4
- # https://www.youtube.com/watch?v=oLkfnc_UMcE
5
-
6
- require 'bundler/setup'
7
3
  require 'polyphony'
8
4
 
9
- def try_connect(target, supervisor)
10
- puts "trying #{target[2]}"
11
- socket = Polyphony::Net.tcp_connect(target[2], 80)
12
- # connection successful
13
- supervisor.stop([target[2], socket])
5
+ def try_connect(ip_address, port, supervisor)
6
+ puts "trying #{ip_address}"
7
+ sleep rand * 0.2
8
+ socket = TCPSocket.new(ip_address, port)
9
+ puts "connected to #{ip_address}"
10
+ supervisor.schedule [ip_address, socket]
14
11
  rescue IOError, SystemCallError
15
12
  # ignore error
16
13
  end
17
14
 
18
- def happy_eyeballs(hostname, port, max_wait_time: 0.025)
15
+ def happy_eyeballs(hostname, port, max_wait_time: 0.010)
19
16
  targets = Socket.getaddrinfo(hostname, port, :INET, :STREAM)
20
17
  t0 = Time.now
21
- cancel_after(5) do
22
- success = supervise do |supervisor|
23
- targets.each_with_index do |t, idx|
24
- sleep(max_wait_time) if idx > 0
25
- supervisor.spin { try_connect(t, supervisor) }
26
- end
27
- end
28
- if success
29
- puts format('success: %s (%.3fs)', success[0], Time.now - t0)
30
- else
31
- puts "timed out (#{Time.now - t0}s)"
18
+ fibers = []
19
+ supervisor = Fiber.current
20
+ spin do
21
+ targets.each do |t|
22
+ spin { try_connect(t[2], t[1], supervisor) }
23
+ sleep(max_wait_time)
32
24
  end
25
+ suspend
26
+ end
27
+ target, socket = move_on_after(5) { suspend }
28
+ supervisor.shutdown_all_children
29
+ if target
30
+ puts format('success: %s (%.3fs)', target, Time.now - t0)
31
+ else
32
+ puts 'timed out'
33
33
  end
34
34
  end
35
35
 
36
- # Let's try it out:
37
36
  happy_eyeballs('debian.org', 'https')
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+ require 'zlib'
6
+
7
+ i, o = IO.pipe
8
+
9
+ w = Zlib::GzipWriter.new(o)
10
+
11
+ s = (1..1000).map { (65 + rand(26)).chr }.join
12
+ puts "full length: #{s.bytesize}"
13
+ w << s
14
+ w.close
15
+ o.close
16
+
17
+
18
+ z = i.read
19
+ puts "zipped length: #{z.bytesize}"
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ puts "pid: #{Process.pid}"
7
+ GC.disable
8
+
9
+ def mem_usage
10
+ # orig_backtick('ps -o rss #{$$}').split.last.to_i
11
+ `ps -o rss #{$$}`.split.last.to_i
12
+ end
13
+
14
+ f = File.open('spin.log', 'w+')
15
+
16
+ m0 = mem_usage
17
+
18
+ X = ARGV[0] ? ARGV[0].to_i : 10
19
+ STDOUT.orig_write "Starting #{X} fibers...\n"
20
+ t0 = Time.now
21
+ x = nil
22
+ X.times do |i|
23
+ spin { p i; suspend }
24
+ end
25
+
26
+ suspend
27
+ f.close
28
+ t1 = Time.now
29
+ m1 = mem_usage
30
+ rate = X / (t1 - t0)
31
+ mem_cost = (m1 - m0) / X.to_f
32
+ STDOUT.orig_write("#{ { time: t1 - t0, spin_rate: rate, fiber_mem_cost: mem_cost }.inspect }\n")
@@ -1,5 +1,6 @@
1
1
  #include <netdb.h>
2
2
  #include <sys/socket.h>
3
+ #include <sys/uio.h>
3
4
 
4
5
  #include "polyphony.h"
5
6
  #include "../libev/ev.h"
@@ -413,20 +414,62 @@ error:
413
414
  return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
414
415
  }
415
416
 
416
- VALUE LibevAgent_write(int argc, VALUE *argv, VALUE self) {
417
+ VALUE LibevAgent_write(VALUE self, VALUE io, VALUE str) {
417
418
  struct LibevAgent_t *agent;
418
419
  struct libev_io watcher;
419
420
  rb_io_t *fptr;
420
421
  VALUE switchpoint_result = Qnil;
421
- VALUE io;
422
422
  VALUE underlying_io;
423
+ char *buf = StringValuePtr(str);
424
+ long len = RSTRING_LEN(str);
425
+ long left = len;
426
+
427
+ underlying_io = rb_iv_get(io, "@io");
428
+ if (underlying_io != Qnil) io = underlying_io;
429
+ GetLibevAgent(self, agent);
430
+ io = rb_io_get_write_io(io);
431
+ GetOpenFile(io, fptr);
432
+ watcher.fiber = Qnil;
433
+
434
+ while (left > 0) {
435
+ ssize_t n = write(fptr->fd, buf, left);
436
+ if (n < 0) {
437
+ int e = errno;
438
+ if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
439
+ switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
440
+ if (TEST_EXCEPTION(switchpoint_result)) goto error;
441
+ }
442
+ else {
443
+ buf += n;
444
+ left -= n;
445
+ }
446
+ }
447
+
448
+ if (watcher.fiber == Qnil) {
449
+ switchpoint_result = libev_snooze();
450
+ if (TEST_EXCEPTION(switchpoint_result)) goto error;
451
+ }
452
+
453
+ RB_GC_GUARD(watcher.fiber);
454
+ RB_GC_GUARD(switchpoint_result);
455
+
456
+ return INT2NUM(len);
457
+ error:
458
+ return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
459
+ }
460
+
461
+ VALUE LibevAgent_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
462
+ struct LibevAgent_t *agent;
463
+ struct libev_io watcher;
464
+ rb_io_t *fptr;
465
+ VALUE switchpoint_result = Qnil;
466
+ VALUE underlying_io;
467
+ long total_length = 0;
423
468
  long total_written = 0;
424
- int arg_idx = 1;
469
+ struct iovec *iov = 0;
470
+ struct iovec *iov_ptr = 0;
471
+ int iov_count = argc;
425
472
 
426
- if (argc < 2)
427
- rb_raise(rb_eRuntimeError, "(wrong number of arguments (expected 2 or more))");
428
-
429
- io = argv[0];
430
473
  underlying_io = rb_iv_get(io, "@io");
431
474
  if (underlying_io != Qnil) io = underlying_io;
432
475
  GetLibevAgent(self, agent);
@@ -434,30 +477,42 @@ VALUE LibevAgent_write(int argc, VALUE *argv, VALUE self) {
434
477
  GetOpenFile(io, fptr);
435
478
  watcher.fiber = Qnil;
436
479
 
437
- while (arg_idx < argc) {
438
- VALUE str = argv[arg_idx];
439
- char *buf = StringValuePtr(str);
440
- long len = RSTRING_LEN(str);
441
- long left = len;
480
+ iov = malloc(iov_count * sizeof(struct iovec));
481
+ for (int i = 0; i < argc; i++) {
482
+ VALUE str = argv[i];
483
+ iov[i].iov_base = StringValuePtr(str);
484
+ iov[i].iov_len = RSTRING_LEN(str);
485
+ total_length += iov[i].iov_len;
486
+ }
487
+ iov_ptr = iov;
442
488
 
443
- while (left > 0) {
444
- ssize_t n = write(fptr->fd, buf, left);
445
- if (n < 0) {
446
- int e = errno;
447
- if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
489
+ while (1) {
490
+ ssize_t n = writev(fptr->fd, iov_ptr, iov_count);
491
+ if (n < 0) {
492
+ int e = errno;
493
+ if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
448
494
 
449
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
450
- if (TEST_EXCEPTION(switchpoint_result)) goto error;
451
- }
452
- else {
453
- buf += n;
454
- left -= n;
495
+ switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
496
+ if (TEST_EXCEPTION(switchpoint_result)) goto error;
497
+ }
498
+ else {
499
+ total_written += n;
500
+ if (total_written == total_length) break;
501
+
502
+ while (n > 0) {
503
+ if ((size_t) n < iov_ptr[0].iov_len) {
504
+ iov_ptr[0].iov_base = (char *) iov_ptr[0].iov_base + n;
505
+ iov_ptr[0].iov_len -= n;
506
+ n = 0;
507
+ }
508
+ else {
509
+ n -= iov_ptr[0].iov_len;
510
+ iov_ptr += 1;
511
+ iov_count -= 1;
512
+ }
455
513
  }
456
514
  }
457
- total_written += len;
458
- arg_idx++;
459
515
  }
460
-
461
516
  if (watcher.fiber == Qnil) {
462
517
  switchpoint_result = libev_snooze();
463
518
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
@@ -466,11 +521,23 @@ VALUE LibevAgent_write(int argc, VALUE *argv, VALUE self) {
466
521
  RB_GC_GUARD(watcher.fiber);
467
522
  RB_GC_GUARD(switchpoint_result);
468
523
 
524
+ free(iov);
469
525
  return INT2NUM(total_written);
470
526
  error:
527
+ free(iov);
471
528
  return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
472
529
  }
473
530
 
531
+ VALUE LibevAgent_write_m(int argc, VALUE *argv, VALUE self) {
532
+ if (argc < 2)
533
+ // TODO: raise ArgumentError
534
+ rb_raise(rb_eRuntimeError, "(wrong number of arguments (expected 2 or more))");
535
+
536
+ return (argc == 2) ?
537
+ LibevAgent_write(self, argv[0], argv[1]) :
538
+ LibevAgent_writev(self, argv[0], argc - 1, argv + 1);
539
+ }
540
+
474
541
  ///////////////////////////////////////////////////////////////////////////
475
542
 
476
543
  VALUE LibevAgent_accept(VALUE self, VALUE sock) {
@@ -738,7 +805,7 @@ void Init_LibevAgent() {
738
805
 
739
806
  rb_define_method(cLibevAgent, "read", LibevAgent_read, 4);
740
807
  rb_define_method(cLibevAgent, "read_loop", LibevAgent_read_loop, 1);
741
- rb_define_method(cLibevAgent, "write", LibevAgent_write, -1);
808
+ rb_define_method(cLibevAgent, "write", LibevAgent_write_m, -1);
742
809
  rb_define_method(cLibevAgent, "accept", LibevAgent_accept, 1);
743
810
  rb_define_method(cLibevAgent, "accept_loop", LibevAgent_accept_loop, 1);
744
811
  // rb_define_method(cLibevAgent, "connect", LibevAgent_accept, 3);
@@ -102,7 +102,10 @@ module Polyphony
102
102
 
103
103
  def install_terminating_signal_handlers
104
104
  trap('SIGTERM', SystemExit)
105
- trap('SIGINT', Interrupt)
105
+ orig_trap('SIGINT') do
106
+ orig_trap('SIGINT') { exit! }
107
+ Thread.current.break_out_of_ev_loop(Thread.main.main_fiber, Interrupt.new)
108
+ end
106
109
  end
107
110
 
108
111
  def terminate_threads
@@ -221,14 +221,14 @@ module Polyphony
221
221
  def await_all_children
222
222
  return unless @children && !@children.empty?
223
223
 
224
- # @results = @children.dup
225
- # @on_child_done = proc do |c, r|
226
- # @results[c] = r
227
- # self.schedule if @children.empty?
228
- # end
229
- # suspend
230
- # @results.values
231
- Fiber.await(*@children.keys)
224
+ @results = @children.dup
225
+ @on_child_done = proc do |c, r|
226
+ @results[c] = r
227
+ self.schedule if @children.empty?
228
+ end
229
+ suspend
230
+ @on_child_done = nil
231
+ @results.values
232
232
  end
233
233
 
234
234
  def shutdown_all_children
@@ -5,6 +5,12 @@ require_relative './socket'
5
5
 
6
6
  # Open ssl socket helper methods (to make it compatible with Socket API)
7
7
  class ::OpenSSL::SSL::SSLSocket
8
+ alias_method :orig_initialize, :initialize
9
+ def initialize(socket, context = nil)
10
+ socket = socket.respond_to?(:io) ? socket.io || socket : socket
11
+ context ? orig_initialize(socket, context) : orig_initialize(socket)
12
+ end
13
+
8
14
  def dont_linger
9
15
  io.dont_linger
10
16
  end
@@ -35,6 +41,7 @@ class ::OpenSSL::SSL::SSLSocket
35
41
  loop do
36
42
  case (result = read_nonblock(maxlen, buf, exception: false))
37
43
  when :wait_readable then Thread.current.agent.wait_io(io, false)
44
+ when :wait_writable then Thread.current.agent.wait_io(io, true)
38
45
  else return result
39
46
  end
40
47
  end
@@ -44,6 +51,7 @@ class ::OpenSSL::SSL::SSLSocket
44
51
  def syswrite(buf)
45
52
  loop do
46
53
  case (result = write_nonblock(buf, exception: false))
54
+ when :wait_readable then Thread.current.agent.wait_io(io, false)
47
55
  when :wait_writable then Thread.current.agent.wait_io(io, true)
48
56
  else
49
57
  return result
@@ -87,6 +87,8 @@ end
87
87
  class ::TCPSocket
88
88
  NO_EXCEPTION = { exception: false }.freeze
89
89
 
90
+ attr_reader :io
91
+
90
92
  def initialize(remote_host, remote_port, local_host = nil, local_port = nil)
91
93
  @io = Socket.new Socket::AF_INET, Socket::SOCK_STREAM
92
94
  if local_host && local_port
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.43.5'
4
+ VERSION = '0.43.6'
5
5
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helper'
4
+ require 'localhost/authority'
4
5
 
5
6
  class SocketTest < MiniTest::Test
6
7
  def setup
@@ -31,4 +32,46 @@ class SocketTest < MiniTest::Test
31
32
  server_fiber&.await
32
33
  server&.close
33
34
  end
35
+
36
+ def test_openssl
37
+ authority = Localhost::Authority.fetch
38
+ context = authority.server_context
39
+ port = rand(1234..5678)
40
+ sock = TCPServer.new('127.0.0.1', port)
41
+ server = OpenSSL::SSL::SSLServer.new(sock, context)
42
+
43
+ server_fiber = spin do
44
+ while (socket = server.accept)
45
+ puts "accepted: #{socket.inspect}"
46
+ spin do
47
+ while (data = socket.gets(8192))
48
+ socket << data
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ snooze
55
+ p 1
56
+ sock = TCPSocket.new('127.0.0.1', port)
57
+ p 2
58
+ sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
59
+ context = OpenSSL::SSL::SSLContext.new
60
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE
61
+ client = OpenSSL::SSL::SSLSocket.new(sock, context)
62
+ client.sync_close = true
63
+ client.hostname = 'localhost'
64
+ p 3
65
+ client.connect
66
+ p 4
67
+ client.write("GET / HTTP/1.0\r\nHost: realiteq.net\r\n\r\n")#("1234\n")
68
+ p 5
69
+ assert_equal "1234\n", client.readpartial(8192)
70
+ p 6
71
+ client.close
72
+ ensure
73
+ server_fiber&.stop
74
+ server_fiber&.await
75
+ server&.close
76
+ end
34
77
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyphony
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.43.5
4
+ version: 0.43.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-12 00:00:00.000000000 Z
11
+ date: 2020-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -242,6 +242,8 @@ files:
242
242
  - TODO.md
243
243
  - bin/polyphony-debug
244
244
  - docs/_config.yml
245
+ - docs/_includes/head.html
246
+ - docs/_includes/title.html
245
247
  - docs/_sass/custom/custom.scss
246
248
  - docs/_sass/overrides.scss
247
249
  - docs/_user-guide/all-about-timers.md
@@ -351,6 +353,7 @@ files:
351
353
  - examples/io/xx-system.rb
352
354
  - examples/io/xx-tcpserver.rb
353
355
  - examples/io/xx-tcpsocket.rb
356
+ - examples/io/xx-zip.rb
354
357
  - examples/performance/fs_read.rb
355
358
  - examples/performance/mem-usage.rb
356
359
  - examples/performance/messaging.rb
@@ -367,6 +370,7 @@ files:
367
370
  - examples/performance/xx-array.rb
368
371
  - examples/performance/xx-fiber-switch.rb
369
372
  - examples/performance/xx-snooze.rb
373
+ - examples/xx-spin.rb
370
374
  - ext/libev/Changes
371
375
  - ext/libev/LICENSE
372
376
  - ext/libev/README