monoio/time/
error.rs

1//! Time error types.
2
3use std::{error, fmt};
4
5use self::Kind::*;
6
7/// Errors encountered by the timer implementation.
8///
9/// Currently, there are two different errors that can occur:
10///
11/// * `shutdown` occurs when a timer operation is attempted, but the timer instance has been
12///   dropped. In this case, the operation will never be able to complete and the `shutdown` error
13///   is returned. This is a permanent error, i.e., once this error is observed, timer operations
14///   will never succeed in the future.
15///
16/// * `at_capacity` occurs when a timer operation is attempted, but the timer instance is currently
17///   handling its maximum number of outstanding sleep instances. In this case, the operation is not
18///   able to be performed at the current moment, and `at_capacity` is returned. This is a transient
19///   error, i.e., at some point in the future, if the operation is attempted again, it might
20///   succeed. Callers that observe this error should attempt to [shed load]. One way to do this
21///   would be dropping the future that issued the timer operation.
22///
23/// [shed load]: https://en.wikipedia.org/wiki/Load_Shedding
24#[derive(Debug, Copy, Clone)]
25pub struct Error(Kind);
26
27#[derive(Debug, Clone, Copy, Eq, PartialEq)]
28#[repr(u8)]
29pub(crate) enum Kind {
30    Shutdown = 1,
31    AtCapacity = 2,
32    Invalid = 3,
33}
34
35impl From<Kind> for Error {
36    fn from(k: Kind) -> Self {
37        Error(k)
38    }
39}
40
41/// Error returned by `Timeout`.
42#[derive(Debug, PartialEq, Eq)]
43pub struct Elapsed(());
44
45#[derive(Debug)]
46pub(crate) enum InsertError {
47    Elapsed,
48}
49
50// ===== impl Error =====
51
52impl Error {
53    /// Creates an error representing a shutdown timer.
54    pub fn shutdown() -> Error {
55        Error(Shutdown)
56    }
57
58    /// Returns `true` if the error was caused by the timer being shutdown.
59    pub fn is_shutdown(&self) -> bool {
60        matches!(self.0, Kind::Shutdown)
61    }
62
63    /// Creates an error representing a timer at capacity.
64    pub fn at_capacity() -> Error {
65        Error(AtCapacity)
66    }
67
68    /// Returns `true` if the error was caused by the timer being at capacity.
69    pub fn is_at_capacity(&self) -> bool {
70        matches!(self.0, Kind::AtCapacity)
71    }
72
73    /// Create an error representing a misconfigured timer.
74    pub fn invalid() -> Error {
75        Error(Invalid)
76    }
77
78    /// Returns `true` if the error was caused by the timer being misconfigured.
79    pub fn is_invalid(&self) -> bool {
80        matches!(self.0, Kind::Invalid)
81    }
82}
83
84impl error::Error for Error {}
85
86impl fmt::Display for Error {
87    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
88        use self::Kind::*;
89        let descr = match self.0 {
90            Shutdown => "the timer is shutdown, must be called from the context of Monoio runtime",
91            AtCapacity => "timer is at capacity and cannot create a new entry",
92            Invalid => "timer duration exceeds maximum duration",
93        };
94        write!(fmt, "{descr}")
95    }
96}
97
98// ===== impl Elapsed =====
99
100impl Elapsed {
101    pub(crate) fn new() -> Self {
102        Elapsed(())
103    }
104}
105
106impl fmt::Display for Elapsed {
107    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
108        "deadline has elapsed".fmt(fmt)
109    }
110}
111
112impl std::error::Error for Elapsed {}
113
114impl From<Elapsed> for std::io::Error {
115    fn from(_err: Elapsed) -> std::io::Error {
116        std::io::ErrorKind::TimedOut.into()
117    }
118}