polyphony 0.47.4 → 0.49.1

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +321 -296
  3. data/Gemfile.lock +1 -1
  4. data/LICENSE +1 -1
  5. data/TODO.md +38 -29
  6. data/examples/core/supervisor.rb +3 -3
  7. data/examples/core/worker-thread.rb +3 -4
  8. data/examples/io/tcp_proxy.rb +32 -0
  9. data/examples/performance/line_splitting.rb +34 -0
  10. data/examples/performance/loop.rb +32 -0
  11. data/examples/performance/thread-vs-fiber/polyphony_server.rb +6 -0
  12. data/ext/polyphony/backend_common.h +2 -22
  13. data/ext/polyphony/backend_io_uring.c +38 -78
  14. data/ext/polyphony/backend_libev.c +22 -67
  15. data/ext/polyphony/event.c +1 -1
  16. data/ext/polyphony/polyphony.c +0 -2
  17. data/ext/polyphony/polyphony.h +5 -4
  18. data/ext/polyphony/queue.c +2 -2
  19. data/ext/polyphony/thread.c +9 -28
  20. data/lib/polyphony.rb +2 -1
  21. data/lib/polyphony/adapters/postgres.rb +3 -3
  22. data/lib/polyphony/adapters/process.rb +2 -0
  23. data/lib/polyphony/core/global_api.rb +14 -2
  24. data/lib/polyphony/core/thread_pool.rb +3 -1
  25. data/lib/polyphony/core/throttler.rb +1 -1
  26. data/lib/polyphony/core/timer.rb +72 -0
  27. data/lib/polyphony/extensions/fiber.rb +32 -8
  28. data/lib/polyphony/extensions/io.rb +8 -14
  29. data/lib/polyphony/extensions/openssl.rb +4 -4
  30. data/lib/polyphony/extensions/socket.rb +13 -10
  31. data/lib/polyphony/net.rb +3 -6
  32. data/lib/polyphony/version.rb +1 -1
  33. data/polyphony.gemspec +1 -1
  34. data/test/helper.rb +1 -0
  35. data/test/test_backend.rb +1 -1
  36. data/test/test_fiber.rb +64 -1
  37. data/test/test_global_api.rb +30 -0
  38. data/test/test_io.rb +26 -0
  39. data/test/test_socket.rb +32 -6
  40. data/test/test_supervise.rb +2 -1
  41. data/test/test_timer.rb +124 -0
  42. metadata +8 -4
  43. data/ext/polyphony/backend.h +0 -26
@@ -92,6 +92,32 @@ class IOTest < MiniTest::Test
92
92
  assert_raises(EOFError) { i.readpartial(1) }
93
93
  end
94
94
 
95
+ def test_gets
96
+ i, o = IO.pipe
97
+
98
+ buf = []
99
+ f = spin do
100
+ while (l = i.gets)
101
+ buf << l
102
+ end
103
+ end
104
+
105
+ snooze
106
+ assert_equal [], buf
107
+
108
+ o << 'fab'
109
+ snooze
110
+ assert_equal [], buf
111
+
112
+ o << "ulous\n"
113
+ 10.times { snooze }
114
+ assert_equal ["fabulous\n"], buf
115
+
116
+ o.close
117
+ f.await
118
+ assert_equal ["fabulous\n"], buf
119
+ end
120
+
95
121
  def test_getc
96
122
  i, o = IO.pipe
97
123
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helper'
4
+ require 'fileutils'
4
5
 
5
6
  class SocketTest < MiniTest::Test
6
7
  def setup
@@ -24,7 +25,32 @@ class SocketTest < MiniTest::Test
24
25
  snooze
25
26
  client = TCPSocket.new('127.0.0.1', port)
26
27
  client.write("1234\n")
27
- assert_equal "1234\n", client.readpartial(8192)
28
+ assert_equal "1234\n", client.recv(8192)
29
+ client.close
30
+ ensure
31
+ server_fiber&.stop
32
+ server_fiber&.await
33
+ server&.close
34
+ end
35
+
36
+ def test_unix_socket
37
+ path = '/tmp/test_unix_socket'
38
+ FileUtils.rm(path) rescue nil
39
+ server = UNIXServer.new(path)
40
+ server_fiber = spin do
41
+ server.accept_loop do |socket|
42
+ spin do
43
+ while (data = socket.gets(8192))
44
+ socket << data
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ snooze
51
+ client = UNIXSocket.new(path)
52
+ client.write("1234\n")
53
+ assert_equal "1234\n", client.recv(8192)
28
54
  client.close
29
55
  ensure
30
56
  server_fiber&.stop
@@ -34,18 +60,18 @@ class SocketTest < MiniTest::Test
34
60
  end
35
61
 
36
62
  class HTTPClientTest < MiniTest::Test
37
- require 'httparty'
38
63
  require 'json'
39
64
 
40
65
  def test_http
41
- res = HTTParty.get('http://worldtimeapi.org/api/timezone/Europe/Paris')
66
+ res = HTTParty.get('http://ipinfo.io/')
67
+
42
68
  response = JSON.load(res.body)
43
- assert_equal "CET", response['abbreviation']
69
+ assert_equal 'https://ipinfo.io/missingauth', response['readme']
44
70
  end
45
71
 
46
72
  def test_https
47
- res = HTTParty.get('https://worldtimeapi.org/api/timezone/Europe/Paris')
73
+ res = HTTParty.get('https://ipinfo.io/')
48
74
  response = JSON.load(res.body)
49
- assert_equal "CET", response['abbreviation']
75
+ assert_equal 'https://ipinfo.io/missingauth', response['readme']
50
76
  end
51
77
  end
@@ -20,9 +20,10 @@ class SuperviseTest < MiniTest::Test
20
20
 
21
21
  f2 << 'bar'
22
22
  f2.await
23
+ assert_equal :runnable, p.state
23
24
  snooze
24
25
 
25
- assert_equal :waiting, p.state
26
+ assert_equal :dead, p.state
26
27
  end
27
28
 
28
29
  def test_supervise_with_restart
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ class TimerMoveOnAfterTest < MiniTest::Test
6
+ def setup
7
+ @timer = Polyphony::Timer.new(resolution: 0.01)
8
+ end
9
+
10
+ def teardown
11
+ @timer.stop
12
+ end
13
+
14
+ def test_move_on_after
15
+ t0 = Time.now
16
+ v = @timer.move_on_after(0.1) do
17
+ sleep 1
18
+ :foo
19
+ end
20
+ t1 = Time.now
21
+
22
+ assert_in_range 0.1..0.15, t1 - t0
23
+ assert_nil v
24
+ end
25
+
26
+ def test_move_on_after_with_value
27
+ t0 = Time.now
28
+ v = @timer.move_on_after(0.01, with_value: :bar) do
29
+ sleep 1
30
+ :foo
31
+ end
32
+ t1 = Time.now
33
+
34
+ assert_in_range 0.01..0.025, t1 - t0
35
+ assert_equal :bar, v
36
+ end
37
+
38
+ def test_move_on_after_with_reset
39
+ t0 = Time.now
40
+ v = @timer.move_on_after(0.01, with_value: :moved_on) do
41
+ sleep 0.007
42
+ @timer.reset
43
+ sleep 0.007
44
+ @timer.reset
45
+ sleep 0.007
46
+ nil
47
+ end
48
+ t1 = Time.now
49
+
50
+ assert_nil v
51
+ assert_in_range 0.02..0.03, t1 - t0
52
+ end
53
+ end
54
+
55
+ class TimerCancelAfterTest < MiniTest::Test
56
+ def setup
57
+ @timer = Polyphony::Timer.new(resolution: 0.01)
58
+ end
59
+
60
+ def teardown
61
+ @timer.stop
62
+ end
63
+
64
+ def test_cancel_after
65
+ t0 = Time.now
66
+
67
+ assert_raises Polyphony::Cancel do
68
+ @timer.cancel_after(0.01) do
69
+ sleep 1
70
+ :foo
71
+ end
72
+ end
73
+ t1 = Time.now
74
+ assert_in_range 0.01..0.03, t1 - t0
75
+ end
76
+
77
+ def test_cancel_after_with_reset
78
+ t0 = Time.now
79
+ @timer.cancel_after(0.01) do
80
+ sleep 0.007
81
+ @timer.reset
82
+ sleep 0.007
83
+ end
84
+ t1 = Time.now
85
+ assert_in_range 0.014..0.024, t1 - t0
86
+ end
87
+
88
+ class CustomException < Exception
89
+ end
90
+
91
+ def test_cancel_after_with_custom_exception
92
+ assert_raises CustomException do
93
+ @timer.cancel_after(0.01, with_exception: CustomException) do
94
+ sleep 1
95
+ :foo
96
+ end
97
+ end
98
+
99
+ begin
100
+ err = nil
101
+ @timer.cancel_after(0.01, with_exception: [CustomException, 'custom message']) do
102
+ sleep 1
103
+ :foo
104
+ end
105
+ rescue Exception => err
106
+ ensure
107
+ assert_kind_of CustomException, err
108
+ assert_equal 'custom message', err.message
109
+ end
110
+
111
+
112
+ begin
113
+ e = nil
114
+ @timer.cancel_after(0.01, with_exception: 'foo') do
115
+ sleep 1
116
+ :foo
117
+ end
118
+ rescue => e
119
+ ensure
120
+ assert_kind_of RuntimeError, e
121
+ assert_equal 'foo', e.message
122
+ end
123
+ end
124
+ 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.47.4
4
+ version: 0.49.1
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-11-14 00:00:00.000000000 Z
11
+ date: 2021-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -269,7 +269,7 @@ dependencies:
269
269
  - !ruby/object:Gem::Version
270
270
  version: 0.3.0
271
271
  description:
272
- email: ciconia@gmail.com
272
+ email: sharon@noteflakes.com
273
273
  executables: []
274
274
  extensions:
275
275
  - ext/polyphony/extconf.rb
@@ -383,6 +383,7 @@ files:
383
383
  - examples/io/raw.rb
384
384
  - examples/io/reline.rb
385
385
  - examples/io/system.rb
386
+ - examples/io/tcp_proxy.rb
386
387
  - examples/io/tcpserver.rb
387
388
  - examples/io/tcpsocket.rb
388
389
  - examples/io/tunnel.rb
@@ -391,6 +392,8 @@ files:
391
392
  - examples/performance/fiber_resume.rb
392
393
  - examples/performance/fiber_transfer.rb
393
394
  - examples/performance/fs_read.rb
395
+ - examples/performance/line_splitting.rb
396
+ - examples/performance/loop.rb
394
397
  - examples/performance/mem-usage.rb
395
398
  - examples/performance/messaging.rb
396
399
  - examples/performance/multi_snooze.rb
@@ -433,7 +436,6 @@ files:
433
436
  - ext/liburing/setup.c
434
437
  - ext/liburing/syscall.c
435
438
  - ext/liburing/syscall.h
436
- - ext/polyphony/backend.h
437
439
  - ext/polyphony/backend_common.h
438
440
  - ext/polyphony/backend_io_uring.c
439
441
  - ext/polyphony/backend_io_uring_context.c
@@ -474,6 +476,7 @@ files:
474
476
  - lib/polyphony/core/sync.rb
475
477
  - lib/polyphony/core/thread_pool.rb
476
478
  - lib/polyphony/core/throttler.rb
479
+ - lib/polyphony/core/timer.rb
477
480
  - lib/polyphony/extensions/core.rb
478
481
  - lib/polyphony/extensions/debug.rb
479
482
  - lib/polyphony/extensions/fiber.rb
@@ -508,6 +511,7 @@ files:
508
511
  - test/test_thread.rb
509
512
  - test/test_thread_pool.rb
510
513
  - test/test_throttler.rb
514
+ - test/test_timer.rb
511
515
  - test/test_trace.rb
512
516
  homepage: https://digital-fabric.github.io/polyphony
513
517
  licenses:
@@ -1,26 +0,0 @@
1
- #ifndef BACKEND_H
2
- #define BACKEND_H
3
-
4
- #include "ruby.h"
5
-
6
- typedef VALUE (* backend_pending_count_t)(VALUE self);
7
- typedef VALUE (*backend_poll_t)(VALUE self, VALUE nowait, VALUE current_fiber, VALUE runqueue);
8
- typedef VALUE (* backend_ref_t)(VALUE self);
9
- typedef int (* backend_ref_count_t)(VALUE self);
10
- typedef void (* backend_reset_ref_count_t)(VALUE self);
11
- typedef VALUE (* backend_unref_t)(VALUE self);
12
- typedef VALUE (* backend_wait_event_t)(VALUE self, VALUE raise_on_exception);
13
- typedef VALUE (* backend_wakeup_t)(VALUE self);
14
-
15
- typedef struct backend_interface {
16
- backend_pending_count_t pending_count;
17
- backend_poll_t poll;
18
- backend_ref_t ref;
19
- backend_ref_count_t ref_count;
20
- backend_reset_ref_count_t reset_ref_count;
21
- backend_unref_t unref;
22
- backend_wait_event_t wait_event;
23
- backend_wakeup_t wakeup;
24
- } backend_interface_t;
25
-
26
- #endif /* BACKEND_H */