summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorihc童鞋@提不起劲 <[email protected]>2022-10-16 17:44:44 +0800
committerGitHub <[email protected]>2022-10-16 17:44:44 +0800
commitdc2dadb875a4c9a302ab99e984f17011de118a3f (patch)
treece34951ae3fcdb0855e066d3a3fd439fef6a9c65 /docs
parent1802184e966f1e0dd5fed34b7c050e141481b9fe (diff)
fully compactable tcp_safe (#113)
* fully compactable tcp_safe * make a more generic compat layer: StreamWrapper; add h2 as example; update related docs
Diffstat (limited to 'docs')
-rw-r--r--docs/en/compatiable-with-tokio-eco.md10
-rw-r--r--docs/zh/compatiable-with-tokio-eco.md10
2 files changed, 8 insertions, 12 deletions
diff --git a/docs/en/compatiable-with-tokio-eco.md b/docs/en/compatiable-with-tokio-eco.md
index 6ee451d..c014084 100644
--- a/docs/en/compatiable-with-tokio-eco.md
+++ b/docs/en/compatiable-with-tokio-eco.md
@@ -15,16 +15,16 @@ In Monoio, since the bottom layer is an asynchronous system call, we chose a sim
### How it works
For `poll_read`, the remaining capacity of the slice passed by the user will be read first, and then the buffer held by the user will be limited to this capacity and a future will be generated. After that, every time the user `poll_read` again, it will be forwarded to the `poll` method of this future. When returning to `Ready`, the contents of the buffer are copied to the slice passed by the user.
+For `poll_write`, the content of the slice passed by the user is copied to its own buffer first, then a future is generated and stored, and Ready is returned immediately. After that, every time the user `poll_write` again, it will first wait for the last content to be sent, then copy the data and return to Ready immediately. It behaves like BufWriter, and may causing errors to be delayed to be perceived.
+
+At the cost, using this compatibility layer will cost you an extra buffer copy.
+
For `poll_write`, the content of the slice passed by the user is first copied to its own buffer, and then a future is generated and stored. After that, every time the user `poll_write` again, it will be forwarded to the `poll` method of this future. Return the result to the user when returning `Ready`.
In other words, using this compatibility layer will cost you an extra buffer copy overhead.
### Usage restrictions
-The user must ensure that if the previous call to `poll_read` or `poll_write` returns `Pending`, the same slice must be used next time.
-
-There is a very simple length check inside compat, if it does not match, it will panic directly. Of course, this does not guarantee that all problems will be detected. The user must ensure that this complies with the above usage restrictions, otherwise undefined behavior may occur.
-
-For example, some optimizations are used in `h2`: when `poll_write` sends a frame and returns `Pending`, then next time you continue to try `poll_write`, if there is a higher priority data frame, this will be sent first Data Frame. This does not meet our usage restrictions, so it is problematic to work on our compatibility layer.
+For write operations, users need to manually call poll_flush or poll_shutdown of AsyncWrite at the end (or the corresponding flush or shutdown methods of AsyncWriteExt), otherwise the data may not be submitted to the kernel (continuous writes do not require manual flushing).
## Poll-oriented interface and asynchronous system call
There are two ways to express asynchrony in Rust, one is based on `poll` and the other is based on `async`. `poll` is synchronous, semantically expressing an immediate attempt; while `async` is essentially the syntactic sugar of poll, it will swallow the future and generate a state machine, which is executed in a loop during await.
diff --git a/docs/zh/compatiable-with-tokio-eco.md b/docs/zh/compatiable-with-tokio-eco.md
index e2c9f76..94712d3 100644
--- a/docs/zh/compatiable-with-tokio-eco.md
+++ b/docs/zh/compatiable-with-tokio-eco.md
@@ -15,16 +15,12 @@ author: ihciah
### 工作原理
对于 `poll_read`,这里会先读到用户传递的 slice 的剩余容量,之后将自己持有的 buffer 限制为该容量并生成 future。之后每次用户再次 `poll_read`,都会转发到这个 future 的 `poll` 方法。在返回 `Ready` 时将 buffer 的内容拷贝到用户传递的 slice 中。
-对于 `poll_write`,会将用户传递 slice 的内容先拷贝至自有 buffer,之后生成 future 并存储。之后每次用户再次 `poll_write`,都会转发到这个 future 的 `poll` 方法。在返回 `Ready` 时返回结果给用户。
+对于 `poll_write`,会将用户传递 slice 的内容先拷贝至自有 buffer,之后生成 future 并存储,并立刻返回 Ready。之后每次用户再次 `poll_write`,都会首先等待上一次的内容发送完毕,之后再拷贝数据并立刻返回 Ready。行为上有种类似 BufWriter 的效果,会导致 error 被延迟感知。
-也就是说,使用这个兼容层会让你额外付出一次 buffer 拷贝开销。
+代价上,使用这个兼容层会让你额外付出一次 buffer 拷贝开销。
### 使用限制
-用户必须保证,如果上次调用 `poll_read` 或 `poll_write` 返回了 `Pending`,那么下次调用必须使用相同的 slice。
-
-compat 内部有非常简单的长度检查,如果不符会直接 panic。当然这并不能保证检测出所有的问题,用户务必保证这符合上述使用限制,否则可能会产生未定义行为。
-
-例如,在 `h2` 里使用了一些优化:当 `poll_write` 发送一个帧并返回了 `Pending`,那么在下次继续尝试 `poll_write` 时,如果有优先级更高的数据帧,会优先发送这个数据帧。这不符合我们的使用限制,所以在我们的兼容层上工作起来是有问题的。
+对于写操作,用户需要在最后手动调用 AsyncWrite 的 poll_flush 或 poll_shutdown(或 AsyncWriteExt 的对应 flush 或 shutdown 方法),否则数据有可能不会被提交至内核(连续的写入不需要手动 flush)。
## 面向 poll 的接口与异步系统调用
Rust 中有两种表达异步的方式,一种是基于 `poll` 的,一种是基于 `async` 的。`poll` 是同步的,语义上表达立即尝试;而 `async` 本质上是 poll 的语法糖,它会吞掉 future 并生成状态机,await 的时候是在循环执行这个状态机。