uringmachine 0.29.2 → 0.31.0
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 +4 -4
- data/CHANGELOG.md +18 -4
- data/README.md +46 -38
- data/TODO.md +68 -75
- data/benchmark/bm_io_ssl.rb +128 -0
- data/benchmark/bm_redis_client.rb +76 -0
- data/benchmark/common.rb +1 -0
- data/benchmark/gets.rb +7 -7
- data/benchmark/gets_concurrent.rb +10 -10
- data/benchmark/http_parse.rb +15 -15
- data/benchmark/http_server_accept_queue.rb +11 -7
- data/benchmark/http_server_multi_accept.rb +7 -7
- data/benchmark/http_server_multi_ractor.rb +7 -7
- data/benchmark/http_server_single_thread.rb +7 -7
- data/benchmark/openssl.rb +50 -22
- data/docs/design/buffer_pool.md +1 -1
- data/examples/fiber_concurrency_io.rb +52 -0
- data/examples/fiber_concurrency_naive.rb +26 -0
- data/examples/fiber_concurrency_runqueue.rb +33 -0
- data/examples/io_uring_simple.c +24 -0
- data/examples/pg.rb +2 -2
- data/examples/stream.rb +2 -2
- data/ext/um/um.c +71 -3
- data/ext/um/um.h +34 -22
- data/ext/um/um_buffer_pool.c +11 -11
- data/ext/um/um_class.c +57 -0
- data/ext/um/um_connection.c +775 -0
- data/ext/um/um_connection_class.c +394 -0
- data/ext/um/um_ssl.c +43 -7
- data/ext/um/um_utils.c +1 -1
- data/grant-2025/final-report.md +269 -0
- data/grant-2025/journal.md +1 -1
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +47 -6
- data/test/{test_stream.rb → test_connection.rb} +321 -151
- data/test/test_ssl.rb +27 -0
- data/test/test_um.rb +174 -17
- metadata +13 -6
- data/ext/um/um_stream.c +0 -674
- data/ext/um/um_stream_class.c +0 -303
data/test/test_ssl.rb
CHANGED
|
@@ -82,4 +82,31 @@ class SSLTest < UMBaseTest
|
|
|
82
82
|
sock1&.close rescue nil
|
|
83
83
|
sock2&.close rescue nil
|
|
84
84
|
end
|
|
85
|
+
|
|
86
|
+
def test_ssl_write_0
|
|
87
|
+
sock1, sock2 = UNIXSocket.pair
|
|
88
|
+
|
|
89
|
+
s1 = OpenSSL::SSL::SSLSocket.new(sock1, @server_ctx)
|
|
90
|
+
s1.sync_close = true
|
|
91
|
+
s2 = OpenSSL::SSL::SSLSocket.new(sock2, OpenSSL::SSL::SSLContext.new)
|
|
92
|
+
s2.sync_close = true
|
|
93
|
+
|
|
94
|
+
@machine.ssl_set_bio(s2)
|
|
95
|
+
assert_equal true, s2.instance_variable_get(:@__um_bio__)
|
|
96
|
+
|
|
97
|
+
t = Thread.new { s1.accept rescue nil }
|
|
98
|
+
|
|
99
|
+
assert_equal 0, @machine.metrics[:total_ops]
|
|
100
|
+
s2.connect
|
|
101
|
+
refute_equal 0, @machine.metrics[:total_ops]
|
|
102
|
+
|
|
103
|
+
assert_equal 6, @machine.ssl_write(s1, 'foobar', 0)
|
|
104
|
+
buf = +''
|
|
105
|
+
assert_equal 6, @machine.ssl_read(s2, buf, 6)
|
|
106
|
+
assert_equal 'foobar', buf
|
|
107
|
+
ensure
|
|
108
|
+
t&.join(0.1)
|
|
109
|
+
sock1&.close rescue nil
|
|
110
|
+
sock2&.close rescue nil
|
|
111
|
+
end
|
|
85
112
|
end
|
data/test/test_um.rb
CHANGED
|
@@ -3506,54 +3506,211 @@ class SetChildSubreaperTest < Minitest::Test
|
|
|
3506
3506
|
end
|
|
3507
3507
|
end
|
|
3508
3508
|
|
|
3509
|
-
class
|
|
3509
|
+
class ConnectionMethodTest < UMBaseTest
|
|
3510
3510
|
def setup
|
|
3511
3511
|
super
|
|
3512
3512
|
@rfd, @wfd = UM.pipe
|
|
3513
3513
|
end
|
|
3514
3514
|
|
|
3515
3515
|
def teardown
|
|
3516
|
-
@
|
|
3516
|
+
@conn = nil
|
|
3517
3517
|
machine.close(@rfd) rescue nil
|
|
3518
3518
|
machine.close(@wfd) rescue nil
|
|
3519
3519
|
super
|
|
3520
3520
|
end
|
|
3521
3521
|
|
|
3522
|
-
def
|
|
3522
|
+
def test_connection_method
|
|
3523
3523
|
machine.write(@wfd, "foobar")
|
|
3524
3524
|
machine.close(@wfd)
|
|
3525
3525
|
|
|
3526
|
-
|
|
3527
|
-
assert_kind_of UM::
|
|
3526
|
+
conn = machine.connection(@rfd)
|
|
3527
|
+
assert_kind_of UM::Connection, conn
|
|
3528
3528
|
|
|
3529
|
-
buf =
|
|
3529
|
+
buf = conn.read(3)
|
|
3530
3530
|
assert_equal 'foo', buf
|
|
3531
3531
|
|
|
3532
|
-
buf =
|
|
3532
|
+
buf = conn.read(-6)
|
|
3533
3533
|
assert_equal 'bar', buf
|
|
3534
|
-
assert
|
|
3534
|
+
assert conn.eof?
|
|
3535
3535
|
|
|
3536
|
-
|
|
3536
|
+
conn.clear
|
|
3537
3537
|
end
|
|
3538
3538
|
|
|
3539
|
-
def
|
|
3539
|
+
def test_connection_method_with_block
|
|
3540
3540
|
machine.write(@wfd, "foobar")
|
|
3541
3541
|
machine.close(@wfd)
|
|
3542
3542
|
|
|
3543
3543
|
bufs = []
|
|
3544
|
-
|
|
3545
|
-
res = machine.
|
|
3546
|
-
|
|
3544
|
+
conn_obj = nil
|
|
3545
|
+
res = machine.connection(@rfd) do |s|
|
|
3546
|
+
conn_obj = s
|
|
3547
3547
|
|
|
3548
|
-
bufs << s.
|
|
3549
|
-
bufs << s.
|
|
3548
|
+
bufs << s.read(3)
|
|
3549
|
+
bufs << s.read(-6)
|
|
3550
3550
|
|
|
3551
3551
|
:foo
|
|
3552
3552
|
end
|
|
3553
3553
|
|
|
3554
|
-
assert_kind_of UM::
|
|
3555
|
-
assert
|
|
3554
|
+
assert_kind_of UM::Connection, conn_obj
|
|
3555
|
+
assert conn_obj.eof?
|
|
3556
3556
|
assert_equal ['foo', 'bar'], bufs
|
|
3557
3557
|
assert_equal :foo, res
|
|
3558
3558
|
end
|
|
3559
|
+
end
|
|
3560
|
+
|
|
3561
|
+
class TCPHelperMethodsTest < UMBaseTest
|
|
3562
|
+
def setup
|
|
3563
|
+
super
|
|
3564
|
+
@port = assign_port
|
|
3565
|
+
end
|
|
3566
|
+
|
|
3567
|
+
def test_tcp_listen
|
|
3568
|
+
server_fd = machine.tcp_listen('0.0.0.0', @port)
|
|
3569
|
+
assert_kind_of Integer, server_fd
|
|
3570
|
+
|
|
3571
|
+
fd_c = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
|
3572
|
+
machine.connect(fd_c, '127.0.0.1', @port)
|
|
3573
|
+
|
|
3574
|
+
fd_s = machine.accept(server_fd)
|
|
3575
|
+
assert_equal 3, machine.send(fd_s, 'foo', 3, 0)
|
|
3576
|
+
|
|
3577
|
+
buf = +''
|
|
3578
|
+
machine.recv(fd_c, buf, 8192, 0)
|
|
3579
|
+
assert_equal 'foo', buf
|
|
3580
|
+
ensure
|
|
3581
|
+
machine.close(fd_s) rescue nil
|
|
3582
|
+
machine.close(fd_c) rescue nil
|
|
3583
|
+
machine.close(server_fd) rescue nil
|
|
3584
|
+
end
|
|
3585
|
+
|
|
3586
|
+
def test_tcp_listen_invalid_args
|
|
3587
|
+
assert_raises(TypeError) { machine.tcp_listen('0.0.0.0', :foo) }
|
|
3588
|
+
assert_raises(TypeError) { machine.tcp_listen(1234, 5678) }
|
|
3589
|
+
end
|
|
3590
|
+
|
|
3591
|
+
def test_tcp_connect
|
|
3592
|
+
server_fd = machine.tcp_listen('0.0.0.0', @port)
|
|
3593
|
+
assert_kind_of Integer, server_fd
|
|
3594
|
+
|
|
3595
|
+
fd_c = machine.tcp_connect('127.0.0.1', @port)
|
|
3596
|
+
assert_kind_of Integer, fd_c
|
|
3597
|
+
|
|
3598
|
+
fd_s = machine.accept(server_fd)
|
|
3599
|
+
assert_equal 3, machine.send(fd_s, 'foo', 3, 0)
|
|
3600
|
+
|
|
3601
|
+
buf = +''
|
|
3602
|
+
machine.recv(fd_c, buf, 8192, 0)
|
|
3603
|
+
assert_equal 'foo', buf
|
|
3604
|
+
ensure
|
|
3605
|
+
machine.close(fd_s) rescue nil
|
|
3606
|
+
machine.close(fd_c) rescue nil
|
|
3607
|
+
machine.close(server_fd) rescue nil
|
|
3608
|
+
end
|
|
3609
|
+
|
|
3610
|
+
def test_tcp_connect_invalid_args
|
|
3611
|
+
server_fd = machine.tcp_listen('0.0.0.0', @port)
|
|
3612
|
+
|
|
3613
|
+
assert_raises(Errno::ECONNREFUSED) {
|
|
3614
|
+
machine.tcp_connect('127.0.0.1', @port + 1)
|
|
3615
|
+
}
|
|
3616
|
+
assert_raises(TypeError) { machine.tcp_connect('127.0.0.1', :foo) }
|
|
3617
|
+
assert_raises(TypeError) { machine.tcp_connect(1234, 5678) }
|
|
3618
|
+
ensure
|
|
3619
|
+
machine.close(server_fd)
|
|
3620
|
+
end
|
|
3621
|
+
end
|
|
3622
|
+
|
|
3623
|
+
class SpliceTest < UMBaseTest
|
|
3624
|
+
def test_splice
|
|
3625
|
+
i1, o1 = UM.pipe
|
|
3626
|
+
i2, o2 = UM.pipe
|
|
3627
|
+
len = nil
|
|
3628
|
+
|
|
3629
|
+
f = machine.spin do
|
|
3630
|
+
len = machine.splice(i1, o2, 1000)
|
|
3631
|
+
ensure
|
|
3632
|
+
machine.close(o2)
|
|
3633
|
+
end
|
|
3634
|
+
|
|
3635
|
+
machine.write(o1, 'foobar')
|
|
3636
|
+
buf = +''
|
|
3637
|
+
machine.read(i2, buf, 1000)
|
|
3638
|
+
|
|
3639
|
+
assert_equal 'foobar', buf
|
|
3640
|
+
assert_equal 6, len
|
|
3641
|
+
ensure
|
|
3642
|
+
machine.terminate(f)
|
|
3643
|
+
machine.join(f)
|
|
3644
|
+
[i1, o1, i2, o2].each { machine.close(it) rescue nil }
|
|
3645
|
+
end
|
|
3646
|
+
|
|
3647
|
+
def test_splice_bad_args
|
|
3648
|
+
fn = "/tmp/um_#{SecureRandom.hex}"
|
|
3649
|
+
IO.write(fn, 'foo')
|
|
3650
|
+
f1 = machine.open(fn, UM::O_RDWR)
|
|
3651
|
+
f2 = machine.open(fn, UM::O_RDWR)
|
|
3652
|
+
assert_raises(Errno::EINVAL) { machine.splice(f1, f2, 1000) }
|
|
3653
|
+
|
|
3654
|
+
i1, o1 = UM.pipe
|
|
3655
|
+
i2, o2 = UM.pipe
|
|
3656
|
+
machine.write(o1, 'foo')
|
|
3657
|
+
|
|
3658
|
+
assert_raises(Errno::EBADF) { machine.splice(i1, o2 + 1, 1000) }
|
|
3659
|
+
ensure
|
|
3660
|
+
[f1, f2, i1, o1, i2, o2].each { machine.close(it) rescue nil }
|
|
3661
|
+
end
|
|
3662
|
+
end
|
|
3663
|
+
|
|
3664
|
+
class TeeTest < UMBaseTest
|
|
3665
|
+
def test_tee
|
|
3666
|
+
i_src, o_src = UM.pipe
|
|
3667
|
+
i_dest1, o_dest1 = UM.pipe
|
|
3668
|
+
i_dest2, o_dest2 = UM.pipe
|
|
3669
|
+
|
|
3670
|
+
len1 = len2 = nil
|
|
3671
|
+
|
|
3672
|
+
f = machine.spin do
|
|
3673
|
+
len1 = machine.tee(i_src, o_dest1, 1000)
|
|
3674
|
+
len2 = machine.splice(i_src, o_dest2, 1000)
|
|
3675
|
+
ensure
|
|
3676
|
+
machine.close(o_dest1)
|
|
3677
|
+
machine.close(o_dest2)
|
|
3678
|
+
end
|
|
3679
|
+
|
|
3680
|
+
machine.write(o_src, 'foobar')
|
|
3681
|
+
machine.close(o_src)
|
|
3682
|
+
result1 = +''
|
|
3683
|
+
machine.read(i_dest1, result1, 1000)
|
|
3684
|
+
result2 = +''
|
|
3685
|
+
machine.read(i_dest2, result2, 1000)
|
|
3686
|
+
|
|
3687
|
+
assert_equal 'foobar', result1
|
|
3688
|
+
assert_equal 6, len1
|
|
3689
|
+
|
|
3690
|
+
assert_equal 'foobar', result2
|
|
3691
|
+
assert_equal 6, len2
|
|
3692
|
+
ensure
|
|
3693
|
+
machine.terminate(f)
|
|
3694
|
+
machine.join(f)
|
|
3695
|
+
[i_src, o_src, i_dest1, o_dest1, i_dest2, o_dest2].each {
|
|
3696
|
+
machine.close(it) rescue nil
|
|
3697
|
+
}
|
|
3698
|
+
end
|
|
3699
|
+
end
|
|
3700
|
+
|
|
3701
|
+
class FsyncTest < UMBaseTest
|
|
3702
|
+
def test_fsync
|
|
3703
|
+
fn = "/tmp/um_#{SecureRandom.hex}"
|
|
3704
|
+
fd = machine.open(fn, UM::O_CREAT | UM::O_WRONLY)
|
|
3705
|
+
|
|
3706
|
+
machine.write(fd, 'foo')
|
|
3707
|
+
assert_equal 0, machine.fsync(fd)
|
|
3708
|
+
ensure
|
|
3709
|
+
machine.close(fd)
|
|
3710
|
+
FileUtils.rm(fn) rescue nil
|
|
3711
|
+
end
|
|
3712
|
+
|
|
3713
|
+
def test_fsync_bad_args
|
|
3714
|
+
assert_raises(Errno::EINVAL) { machine.fsync(1) }
|
|
3715
|
+
end
|
|
3559
3716
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: uringmachine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.31.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sharon Rosner
|
|
@@ -26,6 +26,8 @@ extra_rdoc_files:
|
|
|
26
26
|
- ext/um/um_async_op_class.c
|
|
27
27
|
- ext/um/um_buffer_pool.c
|
|
28
28
|
- ext/um/um_class.c
|
|
29
|
+
- ext/um/um_connection.c
|
|
30
|
+
- ext/um/um_connection_class.c
|
|
29
31
|
- ext/um/um_const.c
|
|
30
32
|
- ext/um/um_ext.c
|
|
31
33
|
- ext/um/um_mutex_class.c
|
|
@@ -33,8 +35,6 @@ extra_rdoc_files:
|
|
|
33
35
|
- ext/um/um_queue_class.c
|
|
34
36
|
- ext/um/um_sidecar.c
|
|
35
37
|
- ext/um/um_ssl.c
|
|
36
|
-
- ext/um/um_stream.c
|
|
37
|
-
- ext/um/um_stream_class.c
|
|
38
38
|
- ext/um/um_sync.c
|
|
39
39
|
- ext/um/um_utils.c
|
|
40
40
|
- lib/uringmachine.rb
|
|
@@ -58,10 +58,12 @@ files:
|
|
|
58
58
|
- benchmark/README.md
|
|
59
59
|
- benchmark/bm_io_pipe.rb
|
|
60
60
|
- benchmark/bm_io_socketpair.rb
|
|
61
|
+
- benchmark/bm_io_ssl.rb
|
|
61
62
|
- benchmark/bm_mutex_cpu.rb
|
|
62
63
|
- benchmark/bm_mutex_io.rb
|
|
63
64
|
- benchmark/bm_pg_client.rb
|
|
64
65
|
- benchmark/bm_queue.rb
|
|
66
|
+
- benchmark/bm_redis_client.rb
|
|
65
67
|
- benchmark/chart_all.png
|
|
66
68
|
- benchmark/chart_bm_io_pipe_x.png
|
|
67
69
|
- benchmark/common.rb
|
|
@@ -88,12 +90,16 @@ files:
|
|
|
88
90
|
- docs/um_api.md
|
|
89
91
|
- docs/wroclove.rb.md
|
|
90
92
|
- examples/echo_server.rb
|
|
93
|
+
- examples/fiber_concurrency_io.rb
|
|
94
|
+
- examples/fiber_concurrency_naive.rb
|
|
95
|
+
- examples/fiber_concurrency_runqueue.rb
|
|
91
96
|
- examples/fiber_scheduler_demo.rb
|
|
92
97
|
- examples/fiber_scheduler_file_io.rb
|
|
93
98
|
- examples/fiber_scheduler_file_io_async.rb
|
|
94
99
|
- examples/fiber_scheduler_fork.rb
|
|
95
100
|
- examples/http_server.rb
|
|
96
101
|
- examples/inout.rb
|
|
102
|
+
- examples/io_uring_simple.c
|
|
97
103
|
- examples/nc.rb
|
|
98
104
|
- examples/nc_ssl.rb
|
|
99
105
|
- examples/pg.rb
|
|
@@ -108,6 +114,8 @@ files:
|
|
|
108
114
|
- ext/um/um_async_op_class.c
|
|
109
115
|
- ext/um/um_buffer_pool.c
|
|
110
116
|
- ext/um/um_class.c
|
|
117
|
+
- ext/um/um_connection.c
|
|
118
|
+
- ext/um/um_connection_class.c
|
|
111
119
|
- ext/um/um_const.c
|
|
112
120
|
- ext/um/um_ext.c
|
|
113
121
|
- ext/um/um_mutex_class.c
|
|
@@ -115,10 +123,9 @@ files:
|
|
|
115
123
|
- ext/um/um_queue_class.c
|
|
116
124
|
- ext/um/um_sidecar.c
|
|
117
125
|
- ext/um/um_ssl.c
|
|
118
|
-
- ext/um/um_stream.c
|
|
119
|
-
- ext/um/um_stream_class.c
|
|
120
126
|
- ext/um/um_sync.c
|
|
121
127
|
- ext/um/um_utils.c
|
|
128
|
+
- grant-2025/final-report.md
|
|
122
129
|
- grant-2025/interim-report.md
|
|
123
130
|
- grant-2025/journal.md
|
|
124
131
|
- grant-2025/tasks.md
|
|
@@ -132,10 +139,10 @@ files:
|
|
|
132
139
|
- test/run.rb
|
|
133
140
|
- test/test_actor.rb
|
|
134
141
|
- test/test_async_op.rb
|
|
142
|
+
- test/test_connection.rb
|
|
135
143
|
- test/test_fiber.rb
|
|
136
144
|
- test/test_fiber_scheduler.rb
|
|
137
145
|
- test/test_ssl.rb
|
|
138
|
-
- test/test_stream.rb
|
|
139
146
|
- test/test_um.rb
|
|
140
147
|
- uringmachine.gemspec
|
|
141
148
|
- vendor/liburing/.github/actions/codespell/stopwords
|