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