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 124 125 126 127 128 129
use std::hash::Hash;
use std::time::Duration;
use crate::cache::key_description::KeyDescription;
use crate::cache::types::{KeyId, Weight};
pub mod acknowledgement;
pub mod error;
pub mod command_executor;
/// CommandType defines various write commands including:
/// Put : attempts to put the new key/value pair in the cache
/// PutWithTTL : attempts to put the new key/value pair with time_to_live in the cache
/// Delete : attempts to delete the key
/// UpdateWeight : updates the weight of the key. This command is sent as a part of `put_or_update` operation
/// Shutdown : informs the `crate::cache::command::command_executor::CommandExecutor` that the cache is being shutdown
pub(crate) enum CommandType<Key, Value>
where Key: Hash + Eq + Clone {
Put(KeyDescription<Key>, Value),
PutWithTTL(KeyDescription<Key>, Value, Duration),
Delete(Key),
UpdateWeight(KeyId, Weight),
Shutdown,
}
/// Provides the description of each command
/// `description` is used if there is an error in sending a command to the `crate::cache::command::command_executor::CommandExecutor`
impl<Key, Value> CommandType<Key, Value>
where Key: Hash + Eq + Clone {
fn description(&self) -> String {
match self {
CommandType::Put(_, _) => "Put".to_string(),
CommandType::PutWithTTL(_, _, _) => "PutWithTTL".to_string(),
CommandType::Delete(_) => "Delete".to_string(),
CommandType::UpdateWeight(_, _) => "UpdateWeight".to_string(),
CommandType::Shutdown => "Shutdown".to_string(),
}
}
}
/// CommandStatus defines the status of each command.
///
/// `Pending`: the initial status of the command, before a command is acted upon.
///
/// `Accepted`: the command is successfully completed.
///
/// `Rejected`: the command is rejected. `RejectionReason` is now available with the `Rejected` status (v0.0.2)
/// - `Put` may be rejected for various reasons. One reason is: the weight of the the incoming key/value pair is more than the total cache weight.
/// - `Delete` will be rejected if the key to be deleted is not preset in the cache.
///
/// `ShuttingDown`: all the commands that could sneak in while the cache is being shutdown will be returned with `ShuttingDown` status.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum CommandStatus {
Pending,
Accepted,
Rejected(RejectionReason),
ShuttingDown,
}
/// RejectionReason defines the reason for a command getting rejected. Available since v0.0.2.
///
/// `EnoughSpaceIsNotAvailableAndKeyFailedToEvictOthers`: If the cache weight is full, and the incoming key can not evict others.
///
/// `KeyWeightIsGreaterThanCacheWeight`: The weight of the incoming key is greater than the total cache weight.
///
/// `KeyDoesNotExist`: Key does not exist during delete operation.
///
/// `KeyAlreadyExists`: Key already exists during put operation.
#[non_exhaustive]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum RejectionReason {
EnoughSpaceIsNotAvailableAndKeyFailedToEvictOthers,
KeyWeightIsGreaterThanCacheWeight,
KeyDoesNotExist,
KeyAlreadyExists,
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use crate::cache::command::CommandType;
use crate::cache::key_description::KeyDescription;
#[test]
fn command_description_put() {
let put = CommandType::Put(
KeyDescription::new(
"topic", 1, 2090, 10,
),
"microservices");
assert_eq!("Put", put.description());
}
#[test]
fn command_description_put_with_ttl() {
let put = CommandType::PutWithTTL(
KeyDescription::new(
"topic", 1, 2090, 10,
),
"microservices",
Duration::from_millis(10),
);
assert_eq!("PutWithTTL", put.description());
}
#[test]
fn command_description_delete() {
let delete: CommandType<&str, &str> = CommandType::Delete("topic");
assert_eq!("Delete", delete.description());
}
#[test]
fn command_description_update_weight() {
let update_weight: CommandType<&str, &str> = CommandType::UpdateWeight(10, 200);
assert_eq!("UpdateWeight", update_weight.description());
}
#[test]
fn command_description_shutdown() {
let shutdown: CommandType<&str, &str> = CommandType::Shutdown;
assert_eq!("Shutdown", shutdown.description());
}
}