uringmachine 0.20.0 → 0.22.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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +3 -4
  3. data/.rubocop.yml +2 -0
  4. data/CHANGELOG.md +34 -0
  5. data/TODO.md +132 -26
  6. data/benchmark/README.md +173 -0
  7. data/benchmark/bm_io_pipe.rb +70 -0
  8. data/benchmark/bm_io_socketpair.rb +71 -0
  9. data/benchmark/bm_mutex_cpu.rb +57 -0
  10. data/benchmark/bm_mutex_io.rb +64 -0
  11. data/benchmark/bm_pg_client.rb +109 -0
  12. data/benchmark/bm_queue.rb +76 -0
  13. data/benchmark/chart.png +0 -0
  14. data/benchmark/common.rb +135 -0
  15. data/benchmark/dns_client.rb +47 -0
  16. data/{examples/bm_http_parse.rb → benchmark/http_parse.rb} +1 -1
  17. data/benchmark/run_bm.rb +8 -0
  18. data/benchmark/sqlite.rb +108 -0
  19. data/{examples/bm_write.rb → benchmark/write.rb} +6 -3
  20. data/ext/um/extconf.rb +1 -1
  21. data/ext/um/um.c +404 -95
  22. data/ext/um/um.h +77 -24
  23. data/ext/um/um_async_op.c +2 -2
  24. data/ext/um/um_class.c +168 -18
  25. data/ext/um/um_op.c +43 -0
  26. data/ext/um/um_sync.c +10 -16
  27. data/ext/um/um_utils.c +16 -0
  28. data/grant-2025/journal.md +242 -1
  29. data/grant-2025/tasks.md +136 -41
  30. data/lib/uringmachine/actor.rb +8 -0
  31. data/lib/uringmachine/dns_resolver.rb +1 -2
  32. data/lib/uringmachine/fiber_scheduler.rb +283 -110
  33. data/lib/uringmachine/version.rb +1 -1
  34. data/lib/uringmachine.rb +32 -3
  35. data/test/helper.rb +7 -18
  36. data/test/test_actor.rb +12 -3
  37. data/test/test_async_op.rb +10 -10
  38. data/test/test_fiber.rb +84 -1
  39. data/test/test_fiber_scheduler.rb +1425 -20
  40. data/test/test_um.rb +565 -113
  41. data/uringmachine.gemspec +6 -5
  42. data/vendor/liburing/src/include/liburing/io_uring.h +1 -0
  43. data/vendor/liburing/src/include/liburing.h +13 -0
  44. data/vendor/liburing/src/liburing-ffi.map +1 -0
  45. data/vendor/liburing/test/bind-listen.c +175 -13
  46. data/vendor/liburing/test/read-write.c +4 -4
  47. data/vendor/liburing/test/ringbuf-read.c +4 -4
  48. data/vendor/liburing/test/send_recv.c +8 -7
  49. metadata +50 -28
  50. data/examples/bm_fileno.rb +0 -33
  51. data/examples/bm_queue.rb +0 -110
  52. data/examples/bm_side_running.rb +0 -83
  53. data/examples/bm_sqlite.rb +0 -89
  54. data/examples/dns_client.rb +0 -12
  55. /data/{examples/bm_mutex.rb → benchmark/mutex.rb} +0 -0
  56. /data/{examples/bm_mutex_single.rb → benchmark/mutex_single.rb} +0 -0
  57. /data/{examples/bm_send.rb → benchmark/send.rb} +0 -0
  58. /data/{examples/bm_snooze.rb → benchmark/snooze.rb} +0 -0
@@ -11,22 +11,22 @@ class AsyncOpTest < UMBaseTest
11
11
  end
12
12
 
13
13
  def test_async_op_await
14
- assert_equal 1, machine.pending_count
14
+ assert_equal 1, machine.metrics[:ops_pending]
15
15
  res = @op.await
16
16
  t1 = monotonic_clock
17
17
  assert_in_range 0.04..0.08, t1 - @t0
18
- assert_equal 0, machine.pending_count
18
+ assert_equal 0, machine.metrics[:ops_pending]
19
19
  assert_equal (-ETIME), res
20
20
  assert_equal true, @op.done?
21
21
  assert_equal false, @op.cancelled?
22
22
  end
23
23
 
24
24
  def test_async_op_join
25
- assert_equal 1, machine.pending_count
25
+ assert_equal 1, machine.metrics[:ops_pending]
26
26
  res = @op.join
27
27
  t1 = monotonic_clock
28
28
  assert_in_range 0.04..0.08, t1 - @t0
29
- assert_equal 0, machine.pending_count
29
+ assert_equal 0, machine.metrics[:ops_pending]
30
30
  assert_equal (-ETIME), res
31
31
  assert_equal true, @op.done?
32
32
  assert_equal false, @op.cancelled?
@@ -34,13 +34,13 @@ class AsyncOpTest < UMBaseTest
34
34
 
35
35
  def test_async_op_cancel
36
36
  machine.sleep(0.01)
37
- assert_equal 1, machine.pending_count
37
+ assert_equal 1, machine.metrics[:ops_pending]
38
38
  @op.cancel
39
39
  assert_equal false, @op.done?
40
40
 
41
41
  machine.sleep(0.01)
42
42
 
43
- assert_equal 0, machine.pending_count
43
+ assert_equal 0, machine.metrics[:ops_pending]
44
44
  assert_equal true, @op.done?
45
45
  assert_equal (-ECANCELED), @op.result
46
46
  assert_equal true, @op.cancelled?
@@ -53,7 +53,7 @@ class AsyncOpTest < UMBaseTest
53
53
 
54
54
  res = @op.await
55
55
 
56
- assert_equal 0, machine.pending_count
56
+ assert_equal 0, machine.metrics[:ops_pending]
57
57
  assert_equal true, @op.done?
58
58
  assert_equal (-ECANCELED), res
59
59
  assert_equal true, @op.cancelled?
@@ -71,7 +71,7 @@ class AsyncOpTest < UMBaseTest
71
71
  rescue => e
72
72
  end
73
73
 
74
- assert_equal 0, machine.pending_count
74
+ assert_equal 0, machine.metrics[:ops_pending]
75
75
  assert_kind_of TOError, e
76
76
  assert_equal true, @op.done?
77
77
  assert_equal (-ECANCELED), @op.result
@@ -89,7 +89,7 @@ class AsyncOpTest < UMBaseTest
89
89
  end
90
90
 
91
91
  # machine.timeout is cancelled async, so CQE is not yet reaped
92
- assert_equal 1, machine.pending_count
92
+ assert_equal 1, machine.metrics[:ops_pending]
93
93
  assert_nil e
94
94
  assert_equal true, @op.done?
95
95
  assert_equal (-ETIME), @op.result
@@ -97,7 +97,7 @@ class AsyncOpTest < UMBaseTest
97
97
 
98
98
  # wait for timeout cancellation
99
99
  machine.sleep(0.01)
100
- assert_equal 0, machine.pending_count
100
+ assert_equal 0, machine.metrics[:ops_pending]
101
101
  end
102
102
  end
103
103
 
data/test/test_fiber.rb CHANGED
@@ -141,9 +141,92 @@ class FiberJoinTest < UMBaseTest
141
141
  end
142
142
  end
143
143
 
144
+ class WaitFibersTest < UMBaseTest
145
+ def test_await_fibers
146
+ q = UM::Queue.new
147
+ x = nil
148
+
149
+ f = machine.spin do
150
+ x = 1
151
+ machine.push q, machine.shift(q) + 1
152
+ 42
153
+ ensure
154
+ x = 0
155
+ end
156
+
157
+ assert_nil x
158
+ machine.snooze
159
+ assert_equal 1, x
160
+
161
+ machine.spin do
162
+ x = 2
163
+ machine.push q, 2
164
+ end
165
+
166
+ res = machine.await_fibers([f])
167
+ assert_equal 0, x
168
+ assert_equal 3, machine.shift(q)
169
+ assert_equal 1, res
170
+
171
+ done = nil
172
+ f = machine.spin { machine.snooze; done = true }
173
+ res = machine.await_fibers(f)
174
+ assert done
175
+ assert_equal 1, res
176
+ end
177
+
178
+ def test_await_fibers_multiple
179
+ f1 = machine.spin do
180
+ :foo
181
+ end
182
+
183
+ f2 = machine.spin do
184
+ machine.sleep(0.001)
185
+ :bar
186
+ end
187
+
188
+ f3 = machine.spin do
189
+ :baz
190
+ end
191
+
192
+ res = machine.await_fibers([f1, f2, f3])
193
+ assert_equal 3, res
194
+ end
195
+
196
+ def test_await_fibers_cross_thread
197
+ q = UM::Queue.new
198
+
199
+ t2 = Thread.new do
200
+ m2 = UM.new
201
+ f = m2.spin do
202
+ m2.push(q, f)
203
+ m2.snooze
204
+ :foo
205
+ end
206
+ m2.await_fibers(f)
207
+ end
208
+
209
+ f = machine.shift(q)
210
+ assert_kind_of Fiber, f
211
+ res = machine.await_fibers(f)
212
+ assert_equal 1, res
213
+ ensure
214
+ t2.join
215
+ end
216
+
217
+ def test_await_fibers_with_exception
218
+ f = machine.spin do
219
+ raise "Foobar"
220
+ end
221
+
222
+ res = machine.await_fibers(f)
223
+ assert_equal 1, res
224
+ end
225
+ end
226
+
144
227
  class ScopeTest < UMBaseTest
145
228
  def test_scope
146
- skip
229
+ skip("UM#scope not yet implemented")
147
230
 
148
231
  x1 = nil
149
232
  x2 = nil