Repository: tikv/tikv
File: components/tikv_util/src/deadline.rs (Rust)

Code before:
        Self { deadline }
    }

    pub fn inner(&self) -> Instant {
        self.deadline
    }

    /// Returns error if the deadline is exceeded.
    pub fn check(&self) -> std::result::Result<(), DeadlineError> {
        fail_point!("deadline_check_fail", |_| Err(DeadlineError));

        let now = Instant::now_coarse();
        if self.deadline <= now {
            return Err(DeadlineError);
        }
        Ok(())
    }

    // Returns the deadline instant of the std library.
    pub fn to_std_instant(&self) -> std::time::Instant {
        std::time::Instant::now() + self.deadline.duration_since(Instant::now_coarse())
    }

    /// Returns the remaining duration of the deadline.
    pub fn remaining_duration(&self) -> Duration {
        self.deadline.duration_since(Instant::now_coarse())
    }
}

const DEADLINE_EXCEEDED: &str = "deadline is exceeded";

pub fn set_deadline_exceeded_busy_error(e: &mut errorpb::Error) {
    let mut server_is_busy_err = errorpb::ServerIsBusy::default();
    server_is_busy_err.set_reason(DEADLINE_EXCEEDED.to_owned());
    e.set_server_is_busy(server_is_busy_err);
}


Review comment (suggestion):
The `remaining_duration` method uses `duration_since` which can panic if the deadline has already passed and uses a `Monotonic` instant type. This should use `saturating_duration_since` instead to safely handle expired deadlines and return zero duration, matching the expected behavior for the timeout check at line 447.
```suggestion
        std::time::Instant::now()
            + self
                .deadline
                .saturating_duration_since(Instant::now_coarse())
    }

    /// Returns the remaining duration of the deadline.
    pub fn remaining_duration(&self) -> Duration {
        self.deadline
            .saturating_duration_since(Instant::now_coarse())
```

Code after:
        Self { deadline }
    }

    pub fn inner(&self) -> Instant {
        self.deadline
    }

    /// Returns error if the deadline is exceeded.
    pub fn check(&self) -> std::result::Result<(), DeadlineError> {
        fail_point!("deadline_check_fail", |_| Err(DeadlineError));

        let now = Instant::now_coarse();
        if self.deadline <= now {
            return Err(DeadlineError);
        }
        Ok(())
    }

    // Returns the deadline instant of the std library.
    pub fn to_std_instant(&self) -> std::time::Instant {
        std::time::Instant::now() + self.deadline.duration_since(Instant::now_coarse())
    }

    /// Returns the remaining duration of the deadline.
    pub fn remaining_duration(&self) -> Duration {
        self.deadline
            .saturating_duration_since(Instant::now_coarse())
    }
}

const DEADLINE_EXCEEDED: &str = "deadline is exceeded";

pub fn set_deadline_exceeded_busy_error(e: &mut errorpb::Error) {
    let mut server_is_busy_err = errorpb::ServerIsBusy::default();
    server_is_busy_err.set_reason(DEADLINE_EXCEEDED.to_owned());
    e.set_server_is_busy(server_is_busy_err);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_remaining_duration_with_future_deadline() {
        // Test case: deadline in the future should return positive remaining duration
        let deadline = Deadline::from_now(Duration::from_millis(100));
        let remaining = deadline.remaining_duration();

        // The remaining duration should be approximately 100ms (within some tolerance)
        // Due to coarse time precision, we allow a small tolerance
        assert!(