@@ -32,6 +32,8 @@ UringMachine is based on my experience marrying Ruby and io_uring:
32
32
- [ IOU] ( https://github.com/digital-fabric/iou ) - a low-level asynchronous API
33
33
for using io_uring from Ruby.
34
34
35
+ ### Learnings
36
+
35
37
Some important learnings from those two projects, in no particular order:
36
38
37
39
- Monkey-patching is not a good solution, long term. You need to deal with
@@ -73,6 +75,30 @@ based on the following principles:
73
75
- Do not insist on structured concurrency, just provide the APIs necessary to
74
76
create actors and to supervise the execution of fibers.
75
77
78
+ ### Cancellation
79
+
80
+ When working with io_uring, managing the life cycle of asynchronous operations
81
+ is quite tricky, especially with regards to cancellation. This is due to the
82
+ fact each operation lives on both sides of the userspace-kernel divide. This
83
+ means that when cancelling an operation, we cannot free, or dispose of any
84
+ resources associated with the operation, until we know for sure that the kernel
85
+ side is also done with the operation.
86
+
87
+ As stated above, working with fibers allows us to keep operation metadata and
88
+ associated data (such as buffers etc) on the stack, which can greatly simplify
89
+ the managing of the operation's lifetime, as well as significantly reduce heap
90
+ allocations.
91
+
92
+ When a cancellation does occur, UringMachine issues a cancellation (using
93
+ ` io_uring_prep_cancel64 ` ), and then waits for the corresponding CQE (with a
94
+ ` -ECANCELED ` result).
95
+
96
+ ### No scheduler, no runqueue
97
+
98
+ UringMachine manages the scheduling of fibers by relying solely on io_uring
99
+ CQE's. There's no list of ready fibers, no runqueue. Manually scheduling fibers
100
+ is done by issuing ` NOP ` operations and then processing CQE's one by one.
101
+
76
102
## Example
77
103
78
104
``` ruby
0 commit comments