From 92d7f407f5fc3f888340db0257070f5184ec3303 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Tue, 23 Jan 2024 23:17:03 +0800 Subject: [PATCH] Add notes Signed-off-by: Xuanwo --- core/src/layers/timeout.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/core/src/layers/timeout.rs b/core/src/layers/timeout.rs index cd227283d5b..c4a0d5773f9 100644 --- a/core/src/layers/timeout.rs +++ b/core/src/layers/timeout.rs @@ -24,7 +24,6 @@ use std::time::Duration; use async_trait::async_trait; use bytes::Bytes; -use tokio::time::Sleep; use crate::raw::oio::ListOperation; use crate::raw::oio::ReadOperation; @@ -72,6 +71,21 @@ use crate::*; /// .with_io_timeout(Duration::from_secs(3))) /// .finish(); /// ``` +/// +/// # Implementation Notes +/// +/// TimeoutLayer is using [`tokio::time::timeout`] to implement timeout for operations. And IO +/// Operations insides `reader`, `writer` will use `Pin>` to track the +/// timeout. +/// +/// This might introduce a bit overhead for IO operations, but it's the only way to implement +/// timeout correctly. We used to implement tiemout layer in zero cost way that only stores +/// a [`std::time::Instant`] and check the timeout by comparing the instant with current time. +/// However, it doesn't works for all cases. +/// +/// For examples, users TCP connection could be in [Busy ESTAB](https://blog.cloudflare.com/when-tcp-sockets-refuse-to-die) state. In this state, no IO event will be omit. The runtime +/// will never poll our future again. From the application side, this future is hanging forever +/// until this TCP connection is closed for reaching the linux [net.ipv4.tcp_retries2](https://man7.org/linux/man-pages/man7/tcp.7.html) times. #[derive(Clone)] pub struct TimeoutLayer { timeout: Duration, @@ -256,7 +270,7 @@ pub struct TimeoutWrapper { inner: R, timeout: Duration, - sleep: Option>>, + sleep: Option>>, } impl TimeoutWrapper {