From aaf7b39d96b9e02992c3e8a870d7b2ae87d25f80 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 13 Aug 2025 18:52:14 +0300 Subject: [PATCH] Update manual.md --- docs/manual.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/manual.md b/docs/manual.md index 1a915c89c..06a3fea2b 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -629,16 +629,22 @@ TODO ### I/O -- Every I/O operation shall be tracked by a corresponding `Completion`. A `Completion` is just an object that tracks a particular I/O operation. The database `IO` will call it's complete callback to signal that the operation was complete, thus ensuring that every tracker can be poll to see if the operation succeeded. -- To advance the Program State Machines, you must first wait for the tracked completions to complete. This can be done either by busy polling (`io.wait_for_completion`) or polling once and then yielding - e.g +Every I/O operation shall be tracked by a corresponding `Completion`. A `Completion` is just an object that tracks a particular I/O operation. The database `IO` will call it's complete callback to signal that the operation was complete, thus ensuring that every tracker can be poll to see if the operation succeeded. + + +To advance the Program State Machines, you must first wait for the tracked completions to complete. This can be done either by busy polling (`io.wait_for_completion`) or polling once and then yielding - e.g + ```rust if !completion.is_completed { return StepResult::IO; } ``` - This allows us to be flexible in places where we do not have the state machines in place to correctly return the Completion. Thus, we can block in certain places to avoid bigger refactorings, which opens up the opportunity for such refactorings in separate PRs. -- To know if a function does any sort of I/O we just have to look at the function signature. If it returns `Completion`, `Vec` or `IOResult`, then it does I/O. -- `IOResult` has the following structure: + +This allows us to be flexible in places where we do not have the state machines in place to correctly return the Completion. Thus, we can block in certain places to avoid bigger refactorings, which opens up the opportunity for such refactorings in separate PRs. + +To know if a function does any sort of I/O we just have to look at the function signature. If it returns `Completion`, `Vec` or `IOResult`, then it does I/O. + +The `IOResult` struct looks as follows: ```rust pub enum IOCompletions { Single(Arc), @@ -651,7 +657,8 @@ TODO IO(IOCompletions), } ``` - This implies that when a function returns an `IOResult`, it must be called again until it returns an `IOResult::Done` variant. This works similarly to how `Future`s are polled in rust. When you receive a `Poll::Ready(None)`, it means that the future stopped it's execution. In a similar vein, if we receive `IOResult::Done`, the function/state machine has reached the end of it's execution. `IOCompletions` is here to signal that, if we are executing any I/O operation, that we need to propagate the completions that are generated from it. This design forces us to handle the fact that a function is asynchronous in nature. This is essentially [function coloring](https://www.tedinski.com/2018/11/13/function-coloring.html), but done at the application level instead of the compiler level. + +This implies that when a function returns an `IOResult`, it must be called again until it returns an `IOResult::Done` variant. This works similarly to how `Future`s are polled in rust. When you receive a `Poll::Ready(None)`, it means that the future stopped it's execution. In a similar vein, if we receive `IOResult::Done`, the function/state machine has reached the end of it's execution. `IOCompletions` is here to signal that, if we are executing any I/O operation, that we need to propagate the completions that are generated from it. This design forces us to handle the fact that a function is asynchronous in nature. This is essentially [function coloring](https://www.tedinski.com/2018/11/13/function-coloring.html), but done at the application level instead of the compiler level. ### References