uringmachine 0.5 → 0.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 +4 -4
- data/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/TODO.md +4 -0
- data/examples/bm_http_parse.rb +149 -0
- data/examples/bm_queue.rb +111 -0
- data/examples/bm_sqlite.rb +89 -0
- data/examples/http_server.rb +1 -1
- data/examples/pg.rb +85 -0
- data/examples/stream.rb +85 -0
- data/ext/um/extconf.rb +57 -0
- data/ext/um/um.c +75 -4
- data/ext/um/um.h +29 -7
- data/ext/um/um_async_op.c +40 -0
- data/ext/um/um_async_op_class.c +136 -0
- data/ext/um/um_class.c +45 -31
- data/ext/um/um_const.c +145 -9
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_op.c +5 -2
- data/ext/um/um_ssl.c +850 -0
- data/ext/um/um_ssl.h +22 -0
- data/ext/um/um_ssl_class.c +138 -0
- data/lib/uringmachine/actor.rb +52 -0
- data/lib/uringmachine/ssl/context_builder.rb +96 -0
- data/lib/uringmachine/ssl.rb +394 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +10 -2
- data/test/helper.rb +6 -0
- data/test/test_actor.rb +63 -0
- data/test/test_async_op.rb +119 -0
- data/test/test_ssl.rb +155 -0
- data/test/test_um.rb +71 -2
- data/uringmachine.gemspec +4 -3
- metadata +39 -13
data/lib/uringmachine/version.rb
CHANGED
data/lib/uringmachine.rb
CHANGED
@@ -8,8 +8,12 @@ UM = UringMachine
|
|
8
8
|
class UringMachine
|
9
9
|
@@fiber_map = {}
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def fiber_map
|
12
|
+
@@fiber_map
|
13
|
+
end
|
14
|
+
|
15
|
+
def spin(value = nil, fiber_class = Fiber, &block)
|
16
|
+
f = fiber_class.new do |resume_value|
|
13
17
|
block.(resume_value)
|
14
18
|
rescue Exception => e
|
15
19
|
STDERR.puts "Unhandled fiber exception: #{e.inspect}"
|
@@ -30,4 +34,8 @@ class UringMachine
|
|
30
34
|
@resolver ||= DNSResolver.new(self)
|
31
35
|
@resolver.resolve(hostname, type)
|
32
36
|
end
|
37
|
+
|
38
|
+
def ssl_accept(fd, ssl_ctx)
|
39
|
+
SSL::Connection.new(self, fd, ssl_ctx)
|
40
|
+
end
|
33
41
|
end
|
data/test/helper.rb
CHANGED
data/test/test_actor.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require 'socket'
|
5
|
+
require 'uringmachine/actor'
|
6
|
+
|
7
|
+
class ActorTest < UMBaseTest
|
8
|
+
module Counter
|
9
|
+
def setup
|
10
|
+
@count = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def incr
|
14
|
+
@count += 1
|
15
|
+
end
|
16
|
+
|
17
|
+
def get
|
18
|
+
@count
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset
|
22
|
+
@count = 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_basic_actor_functionality
|
27
|
+
actor = @machine.spin_actor(Counter)
|
28
|
+
|
29
|
+
assert_kind_of Fiber, actor
|
30
|
+
|
31
|
+
assert_equal 0, actor.call(:get)
|
32
|
+
assert_equal 1, actor.call(:incr)
|
33
|
+
assert_equal actor, actor.cast(:incr)
|
34
|
+
assert_equal 2, actor.call(:get)
|
35
|
+
assert_equal actor, actor.cast(:reset)
|
36
|
+
assert_equal 0, actor.call(:get)
|
37
|
+
end
|
38
|
+
|
39
|
+
module Counter2
|
40
|
+
def setup(count)
|
41
|
+
@count = count
|
42
|
+
end
|
43
|
+
|
44
|
+
def incr
|
45
|
+
@count += 1
|
46
|
+
end
|
47
|
+
|
48
|
+
def get
|
49
|
+
@count
|
50
|
+
end
|
51
|
+
|
52
|
+
def reset
|
53
|
+
@count = 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def test_actor_with_args
|
59
|
+
actor = @machine.spin_actor(Counter2, 43)
|
60
|
+
|
61
|
+
assert_equal 43, actor.call(:get)
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
require 'socket'
|
5
|
+
|
6
|
+
class AsyncOpTest < UMBaseTest
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
@t0 = monotonic_clock
|
10
|
+
@op = machine.prep_timeout(0.05)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_async_op_await
|
14
|
+
assert_equal 1, machine.pending_count
|
15
|
+
res = @op.await
|
16
|
+
t1 = monotonic_clock
|
17
|
+
assert_in_range 0.04..0.08, t1 - @t0
|
18
|
+
assert_equal 0, machine.pending_count
|
19
|
+
assert_equal (-ETIME), res
|
20
|
+
assert_equal true, @op.done?
|
21
|
+
assert_equal false, @op.cancelled?
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_async_op_join
|
25
|
+
assert_equal 1, machine.pending_count
|
26
|
+
res = @op.join
|
27
|
+
t1 = monotonic_clock
|
28
|
+
assert_in_range 0.04..0.08, t1 - @t0
|
29
|
+
assert_equal 0, machine.pending_count
|
30
|
+
assert_equal (-ETIME), res
|
31
|
+
assert_equal true, @op.done?
|
32
|
+
assert_equal false, @op.cancelled?
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_async_op_cancel
|
36
|
+
machine.sleep(0.01)
|
37
|
+
assert_equal 1, machine.pending_count
|
38
|
+
@op.cancel
|
39
|
+
assert_equal false, @op.done?
|
40
|
+
|
41
|
+
machine.sleep(0.01)
|
42
|
+
|
43
|
+
assert_equal 0, machine.pending_count
|
44
|
+
assert_equal true, @op.done?
|
45
|
+
assert_equal (-ECANCELED), @op.result
|
46
|
+
assert_equal true, @op.cancelled?
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_async_op_await_with_cancel
|
50
|
+
machine.spin do
|
51
|
+
@op.cancel
|
52
|
+
end
|
53
|
+
|
54
|
+
res = @op.await
|
55
|
+
|
56
|
+
assert_equal 0, machine.pending_count
|
57
|
+
assert_equal true, @op.done?
|
58
|
+
assert_equal (-ECANCELED), res
|
59
|
+
assert_equal true, @op.cancelled?
|
60
|
+
end
|
61
|
+
|
62
|
+
class TOError < RuntimeError; end
|
63
|
+
|
64
|
+
def test_async_op_await_with_timeout
|
65
|
+
e = nil
|
66
|
+
|
67
|
+
begin
|
68
|
+
machine.timeout(0.01, TOError) do
|
69
|
+
@op.await
|
70
|
+
end
|
71
|
+
rescue => e
|
72
|
+
end
|
73
|
+
|
74
|
+
assert_equal 0, machine.pending_count
|
75
|
+
assert_kind_of TOError, e
|
76
|
+
assert_equal true, @op.done?
|
77
|
+
assert_equal (-ECANCELED), @op.result
|
78
|
+
assert_equal true, @op.cancelled?
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_async_op_await_with_timeout2
|
82
|
+
e = nil
|
83
|
+
|
84
|
+
begin
|
85
|
+
machine.timeout(0.1, TOError) do
|
86
|
+
@op.await
|
87
|
+
end
|
88
|
+
rescue => e
|
89
|
+
end
|
90
|
+
|
91
|
+
# machine.timeout is cancelled async, so CQE is not yet reaped
|
92
|
+
assert_equal 1, machine.pending_count
|
93
|
+
assert_nil e
|
94
|
+
assert_equal true, @op.done?
|
95
|
+
assert_equal (-ETIME), @op.result
|
96
|
+
assert_equal false, @op.cancelled?
|
97
|
+
|
98
|
+
# wait for timeout cancellation
|
99
|
+
machine.sleep(0.01)
|
100
|
+
assert_equal 0, machine.pending_count
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class PrepTimeoutTest < UMBaseTest
|
105
|
+
def test_prep_timeout
|
106
|
+
op = machine.prep_timeout(0.03)
|
107
|
+
assert_kind_of UM::AsyncOp, op
|
108
|
+
assert_equal :timeout, op.kind
|
109
|
+
|
110
|
+
assert_equal false, op.done?
|
111
|
+
assert_nil op.result
|
112
|
+
|
113
|
+
machine.sleep(0.05)
|
114
|
+
|
115
|
+
assert_equal true, op.done?
|
116
|
+
assert_equal (-ETIME), op.result
|
117
|
+
assert_equal false, op.cancelled?
|
118
|
+
end
|
119
|
+
end
|
data/test/test_ssl.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require_relative "helper"
|
2
|
+
|
3
|
+
__END__
|
4
|
+
|
5
|
+
require 'uringmachine/ssl'
|
6
|
+
require 'openssl'
|
7
|
+
require 'localhost'
|
8
|
+
|
9
|
+
class TestSSLContext < Minitest::Test
|
10
|
+
|
11
|
+
if false
|
12
|
+
def test_raises_with_invalid_keystore_file
|
13
|
+
ctx = UM::SSL::Context.new
|
14
|
+
|
15
|
+
exception = assert_raises(ArgumentError) { ctx.keystore = "/no/such/keystore" }
|
16
|
+
assert_equal("Keystore file '/no/such/keystore' does not exist", exception.message)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_raises_with_unreadable_keystore_file
|
20
|
+
ctx = UM::SSL::Context.new
|
21
|
+
|
22
|
+
File.stub(:exist?, true) do
|
23
|
+
File.stub(:readable?, false) do
|
24
|
+
exception = assert_raises(ArgumentError) { ctx.keystore = "/unreadable/keystore" }
|
25
|
+
assert_equal("Keystore file '/unreadable/keystore' is not readable", exception.message)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
else
|
30
|
+
def test_raises_with_invalid_key_file
|
31
|
+
ctx = UM::SSL::Context.new
|
32
|
+
|
33
|
+
exception = assert_raises(ArgumentError) { ctx.key = "/no/such/key" }
|
34
|
+
assert_equal("Key file '/no/such/key' does not exist", exception.message)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_raises_with_unreadable_key_file
|
38
|
+
ctx = UM::SSL::Context.new
|
39
|
+
|
40
|
+
File.stub(:exist?, true) do
|
41
|
+
File.stub(:readable?, false) do
|
42
|
+
exception = assert_raises(ArgumentError) { ctx.key = "/unreadable/key" }
|
43
|
+
assert_equal("Key file '/unreadable/key' is not readable", exception.message)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_raises_with_invalid_cert_file
|
49
|
+
ctx = UM::SSL::Context.new
|
50
|
+
|
51
|
+
exception = assert_raises(ArgumentError) { ctx.cert = "/no/such/cert" }
|
52
|
+
assert_equal("Cert file '/no/such/cert' does not exist", exception.message)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_raises_with_unreadable_cert_file
|
56
|
+
ctx = UM::SSL::Context.new
|
57
|
+
|
58
|
+
File.stub(:exist?, true) do
|
59
|
+
File.stub(:readable?, false) do
|
60
|
+
exception = assert_raises(ArgumentError) { ctx.key = "/unreadable/cert" }
|
61
|
+
assert_equal("Key file '/unreadable/cert' is not readable", exception.message)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_raises_with_invalid_key_pem
|
67
|
+
ctx = UM::SSL::Context.new
|
68
|
+
|
69
|
+
exception = assert_raises(ArgumentError) { ctx.key_pem = nil }
|
70
|
+
assert_equal("'key_pem' is not a String", exception.message)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_raises_with_unreadable_ca_file
|
74
|
+
ctx = UM::SSL::Context.new
|
75
|
+
|
76
|
+
File.stub(:exist?, true) do
|
77
|
+
File.stub(:readable?, false) do
|
78
|
+
exception = assert_raises(ArgumentError) { ctx.ca = "/unreadable/cert" }
|
79
|
+
assert_equal("ca file '/unreadable/cert' is not readable", exception.message)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_raises_with_invalid_cert_pem
|
85
|
+
ctx = UM::SSL::Context.new
|
86
|
+
|
87
|
+
exception = assert_raises(ArgumentError) { ctx.cert_pem = nil }
|
88
|
+
assert_equal("'cert_pem' is not a String", exception.message)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_raises_with_invalid_key_password_command
|
92
|
+
ctx = UM::SSL::Context.new
|
93
|
+
ctx.key_password_command = '/unreadable/decrypt_command'
|
94
|
+
|
95
|
+
assert_raises(Errno::ENOENT) { ctx.key_password }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class TestSSLServer < UMBaseTest
|
101
|
+
def setup
|
102
|
+
super
|
103
|
+
@port = assign_port
|
104
|
+
@ssl_ctx = create_ssl_ctx
|
105
|
+
end
|
106
|
+
|
107
|
+
def create_ssl_ctx
|
108
|
+
authority = Localhost::Authority.fetch
|
109
|
+
authority.server_context
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_ssl_accept
|
113
|
+
server_fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
114
|
+
machine.bind(server_fd, '127.0.0.1', @port)
|
115
|
+
res = machine.listen(server_fd, 5)
|
116
|
+
assert_equal 0, res
|
117
|
+
assert_equal 0, machine.pending_count
|
118
|
+
|
119
|
+
fd = nil
|
120
|
+
sock = nil
|
121
|
+
|
122
|
+
reply = nil
|
123
|
+
t = Thread.new do
|
124
|
+
p 21
|
125
|
+
sleep 0.1
|
126
|
+
p 22
|
127
|
+
sock = TCPSocket.new('127.0.0.1', @port)
|
128
|
+
p 23
|
129
|
+
sleep 0.1
|
130
|
+
p 24
|
131
|
+
client = OpenSSL::SSL::SSLSocket.new(sock)
|
132
|
+
p 25
|
133
|
+
client.connect
|
134
|
+
p 26
|
135
|
+
client.write('foobar')
|
136
|
+
p 27
|
137
|
+
reply = client.read(8192)
|
138
|
+
p 28
|
139
|
+
end
|
140
|
+
|
141
|
+
p 11
|
142
|
+
fd = machine.accept(server_fd)
|
143
|
+
p 12
|
144
|
+
sock = machine.ssl_accept(fd, @ssl_ctx)
|
145
|
+
msg = +''
|
146
|
+
p 13
|
147
|
+
ret = sock.recv(msg, 8192)
|
148
|
+
p 14
|
149
|
+
sock.send("Hello: #{msg} (#{ret})", 0)
|
150
|
+
p 15
|
151
|
+
machine.close(fd)
|
152
|
+
|
153
|
+
assert_equal 'Hello: foobar (6)', reply
|
154
|
+
end
|
155
|
+
end
|
data/test/test_um.rb
CHANGED
@@ -212,6 +212,57 @@ class SleepTest < UMBaseTest
|
|
212
212
|
end
|
213
213
|
end
|
214
214
|
|
215
|
+
class PeriodicallyTest < UMBaseTest
|
216
|
+
class Cancel < StandardError; end
|
217
|
+
|
218
|
+
def test_periodically
|
219
|
+
count = 0
|
220
|
+
cancel = 0
|
221
|
+
|
222
|
+
t0 = monotonic_clock
|
223
|
+
assert_equal 0, machine.pending_count
|
224
|
+
begin
|
225
|
+
machine.periodically(0.01) do
|
226
|
+
count += 1
|
227
|
+
raise Cancel if count >= 5
|
228
|
+
end
|
229
|
+
rescue Cancel
|
230
|
+
cancel = 1
|
231
|
+
end
|
232
|
+
machine.snooze
|
233
|
+
assert_equal 0, machine.pending_count
|
234
|
+
t1 = monotonic_clock
|
235
|
+
assert_in_range 0.05..0.09, t1 - t0
|
236
|
+
assert_equal 5, count
|
237
|
+
assert_equal 1, cancel
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_periodically_with_timeout
|
241
|
+
count = 0
|
242
|
+
cancel = 0
|
243
|
+
|
244
|
+
t0 = monotonic_clock
|
245
|
+
assert_equal 0, machine.pending_count
|
246
|
+
begin
|
247
|
+
machine.timeout(0.05, Cancel) do
|
248
|
+
machine.periodically(0.01) do
|
249
|
+
count += 1
|
250
|
+
raise Cancel if count >= 5
|
251
|
+
end
|
252
|
+
end
|
253
|
+
rescue Cancel
|
254
|
+
cancel = 1
|
255
|
+
end
|
256
|
+
machine.snooze
|
257
|
+
assert_equal 0, machine.pending_count
|
258
|
+
t1 = monotonic_clock
|
259
|
+
assert_in_range 0.05..0.08, t1 - t0
|
260
|
+
assert_in_range 4..6, count
|
261
|
+
assert_equal 1, cancel
|
262
|
+
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
215
266
|
class ReadTest < UMBaseTest
|
216
267
|
def test_read
|
217
268
|
r, w = IO.pipe
|
@@ -274,6 +325,26 @@ class ReadTest < UMBaseTest
|
|
274
325
|
assert_equal 3, result
|
275
326
|
assert_equal 'foobar', buffer
|
276
327
|
end
|
328
|
+
|
329
|
+
def test_read_with_string_io
|
330
|
+
require 'stringio'
|
331
|
+
|
332
|
+
buffer = +'foo'
|
333
|
+
sio = StringIO.new(buffer)
|
334
|
+
|
335
|
+
r, w = IO.pipe
|
336
|
+
w << 'bar'
|
337
|
+
|
338
|
+
result = machine.read(r.fileno, buffer, 100, -1)
|
339
|
+
assert_equal 3, result
|
340
|
+
assert_equal 'foobar', sio.read
|
341
|
+
|
342
|
+
w << 'baz'
|
343
|
+
|
344
|
+
result = machine.read(r.fileno, buffer, 100, -1)
|
345
|
+
assert_equal 3, result
|
346
|
+
assert_equal 'baz', sio.read
|
347
|
+
end
|
277
348
|
end
|
278
349
|
|
279
350
|
class ReadEachTest < UMBaseTest
|
@@ -1048,6 +1119,4 @@ class WaitTest < UMBaseTest
|
|
1048
1119
|
|
1049
1120
|
assert_raises(Errno::ECHILD) { machine.waitpid(1, UM::WEXITED) }
|
1050
1121
|
end
|
1051
|
-
|
1052
1122
|
end
|
1053
|
-
|
data/uringmachine.gemspec
CHANGED
@@ -20,8 +20,9 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
s.required_ruby_version = '>= 3.3'
|
22
22
|
|
23
|
-
s.add_development_dependency 'rake-compiler', '1.2.
|
24
|
-
s.add_development_dependency 'minitest', '5.25.
|
23
|
+
s.add_development_dependency 'rake-compiler', '1.2.9'
|
24
|
+
s.add_development_dependency 'minitest', '5.25.4'
|
25
25
|
s.add_development_dependency 'http_parser.rb', '0.8.0'
|
26
|
-
s.add_development_dependency 'benchmark-ips', '2.
|
26
|
+
s.add_development_dependency 'benchmark-ips', '2.14.0'
|
27
|
+
s.add_development_dependency 'localhost', '1.3.1'
|
27
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uringmachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-04-23 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rake-compiler
|
@@ -16,28 +15,28 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - '='
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.2.
|
18
|
+
version: 1.2.9
|
20
19
|
type: :development
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - '='
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.2.
|
25
|
+
version: 1.2.9
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
27
|
name: minitest
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
30
|
- - '='
|
32
31
|
- !ruby/object:Gem::Version
|
33
|
-
version: 5.25.
|
32
|
+
version: 5.25.4
|
34
33
|
type: :development
|
35
34
|
prerelease: false
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
37
36
|
requirements:
|
38
37
|
- - '='
|
39
38
|
- !ruby/object:Gem::Version
|
40
|
-
version: 5.25.
|
39
|
+
version: 5.25.4
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
41
|
name: http_parser.rb
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,15 +57,28 @@ dependencies:
|
|
58
57
|
requirements:
|
59
58
|
- - '='
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.
|
60
|
+
version: 2.14.0
|
62
61
|
type: :development
|
63
62
|
prerelease: false
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
65
64
|
requirements:
|
66
65
|
- - '='
|
67
66
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
69
|
-
|
67
|
+
version: 2.14.0
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: localhost
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.3.1
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.3.1
|
70
82
|
email: sharon@noteflakes.com
|
71
83
|
executables: []
|
72
84
|
extensions:
|
@@ -84,19 +96,26 @@ files:
|
|
84
96
|
- README.md
|
85
97
|
- Rakefile
|
86
98
|
- TODO.md
|
99
|
+
- examples/bm_http_parse.rb
|
100
|
+
- examples/bm_queue.rb
|
87
101
|
- examples/bm_snooze.rb
|
102
|
+
- examples/bm_sqlite.rb
|
88
103
|
- examples/bm_write.rb
|
89
104
|
- examples/dns_client.rb
|
90
105
|
- examples/echo_server.rb
|
91
106
|
- examples/http_server.rb
|
92
107
|
- examples/inout.rb
|
93
108
|
- examples/nc.rb
|
109
|
+
- examples/pg.rb
|
94
110
|
- examples/server_client.rb
|
95
111
|
- examples/snooze.rb
|
112
|
+
- examples/stream.rb
|
96
113
|
- examples/write_dev_null.rb
|
97
114
|
- ext/um/extconf.rb
|
98
115
|
- ext/um/um.c
|
99
116
|
- ext/um/um.h
|
117
|
+
- ext/um/um_async_op.c
|
118
|
+
- ext/um/um_async_op_class.c
|
100
119
|
- ext/um/um_buffer.c
|
101
120
|
- ext/um/um_class.c
|
102
121
|
- ext/um/um_const.c
|
@@ -104,13 +123,22 @@ files:
|
|
104
123
|
- ext/um/um_mutex_class.c
|
105
124
|
- ext/um/um_op.c
|
106
125
|
- ext/um/um_queue_class.c
|
126
|
+
- ext/um/um_ssl.c
|
127
|
+
- ext/um/um_ssl.h
|
128
|
+
- ext/um/um_ssl_class.c
|
107
129
|
- ext/um/um_sync.c
|
108
130
|
- ext/um/um_utils.c
|
109
131
|
- lib/uringmachine.rb
|
132
|
+
- lib/uringmachine/actor.rb
|
110
133
|
- lib/uringmachine/dns_resolver.rb
|
134
|
+
- lib/uringmachine/ssl.rb
|
135
|
+
- lib/uringmachine/ssl/context_builder.rb
|
111
136
|
- lib/uringmachine/version.rb
|
112
137
|
- supressions/ruby.supp
|
113
138
|
- test/helper.rb
|
139
|
+
- test/test_actor.rb
|
140
|
+
- test/test_async_op.rb
|
141
|
+
- test/test_ssl.rb
|
114
142
|
- test/test_um.rb
|
115
143
|
- uringmachine.gemspec
|
116
144
|
- vendor/liburing/.github/actions/codespell/stopwords
|
@@ -413,7 +441,6 @@ metadata:
|
|
413
441
|
source_code_uri: https://github.com/digital-fabric/uringmachine
|
414
442
|
documentation_uri: https://www.rubydoc.info/gems/uringmachine
|
415
443
|
changelog_uri: https://github.com/digital-fabric/uringmachine/blob/master/CHANGELOG.md
|
416
|
-
post_install_message:
|
417
444
|
rdoc_options:
|
418
445
|
- "--title"
|
419
446
|
- UringMachine
|
@@ -432,8 +459,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
432
459
|
- !ruby/object:Gem::Version
|
433
460
|
version: '0'
|
434
461
|
requirements: []
|
435
|
-
rubygems_version: 3.
|
436
|
-
signing_key:
|
462
|
+
rubygems_version: 3.6.2
|
437
463
|
specification_version: 4
|
438
464
|
summary: A lean, mean io_uring machine
|
439
465
|
test_files: []
|