types.rs
Overview
This file defines core types and data structures essential for managing node identities, versioned key-value pairs, deletion statuses, and mutations within a distributed system cluster. It provides serialization and deserialization capabilities, versioning semantics, and status tracking to support consistent state synchronization in a gossip-based or cluster-aware environment.
The types herein are foundational for cluster membership identification, key-value state versioning, and mutation representation, facilitating communication and state sharing between nodes.
Structs and Enums
ChitchatId
Represents a unique identifier for a node in the cluster. It encapsulates three components:
node_id: A unique string identifier across the cluster.generation_id: A monotonically increasing numeric identifier that changes on each restart of the node, helping to detect node restarts.gossip_advertise_addr: The socket address peers use to perform gossip communication with this node.
pub struct ChitchatId {
pub node_id: String,
pub generation_id: u64,
pub gossip_advertise_addr: SocketAddr,
}
Key Details
Generation ID Usage: Helps differentiate between node restarts; typically incremented or set to node startup time.
Debug Implementation: Custom
fmtimplementation to displaynode_id:generation_id:gossip_advertise_addr.
Methods
new(node_id: String, generation_id: u64, gossip_advertise_addr: SocketAddr) -> SelfCreates a new
ChitchatId.Example:
let id = ChitchatId::new("node-1".to_string(), 42, "127.0.0.1:8080".parse().unwrap());(Testing-only)
advertise_port(&self) -> u16Returns the gossip advertise port, useful for assertions in tests.
(Testing-only)
for_local_test(port: u16) -> SelfGenerates a
ChitchatIdfor local testing, using localhost IP and supplied port.
DeletionStatus
An enum representing the deletion state of a key-value pair.
pub enum DeletionStatus {
Set,
Deleted(Instant),
DeleteAfterTtl(Instant),
}
Set: Entry is active and not deleted.Deleted(Instant): Entry is marked deleted; the containedInstantis a reference start time.DeleteAfterTtl(Instant): Entry is scheduled for deletion after a TTL (time to live); theInstantis a reference start time.
Important Note
The stored Instant is not the scheduled deletion time but a reference start time; the actual deletion time is obtained by adding the grace period.
Methods
time_of_start_scheduled_for_deletion(&self) -> Option<Instant>Returns the
Instantrepresenting the time deletion was scheduled to start orNoneif not applicable.Partial equality
PartialEqimplementation (test-only) compares only the variant, ignoring timestamps.
VersionedValue
A key-value pair with an associated version and deletion status.
pub struct VersionedValue {
pub value: String,
pub version: Version,
pub status: DeletionStatus,
}
value: The string value stored.version: The version number (type aliasu64).status: Current deletion status (DeletionStatus).
Methods
new(value: String, version: Version, is_tombstone: bool) -> VersionedValueCreates a new
VersionedValue. Ifis_tombstoneis true, marks the value as deleted with the current time.is_deleted(&self) -> boolReturns
trueif thestatusisDeleted.(Test-only)
for_test(value: &str, version: Version) -> SelfHelper for creating non-deleted test values.
Serialization
VersionedValue uses a custom serialization wrapper struct VersionedValueForSerialization that serializes the deletion status as a DeletionStatusMutation enum, which can result in some loss of TTL precision on deserialization.
KeyValueMutation
Represents a mutation operation to a key-value pair.
pub(crate) struct KeyValueMutation {
pub(crate) key: String,
pub(crate) value: String,
pub(crate) version: Version,
pub(crate) status: DeletionStatusMutation,
}
key: The key to mutate.value: The new value.version: Updated version for the key.status: The deletion status mutation to apply.
DeletionStatusMutation
A compact enum representing mutation states related to deletion, serialized as a u8.
pub enum DeletionStatusMutation {
Set = 0u8,
Delete = 1u8,
DeleteAfterTtl = 2u8,
}
Set: No deletion.Delete: Mark as deleted immediately.DeleteAfterTtl: Mark as deleted after TTL.
Methods
into_status(self, now: Instant) -> DeletionStatusConverts the mutation into a
DeletionStatuswith the current time reference.scheduled_for_deletion(&self) -> boolReturns
trueif the mutation represents a deletion or delayed deletion.Implements conversion traits to/from
u8for compact serialization.
KeyValueMutationRef<'a>
A reference version of KeyValueMutation for zero-copy serialization.
pub(crate) struct KeyValueMutationRef<'a> {
pub(crate) key: &'a str,
pub(crate) value: &'a str,
pub(crate) version: Version,
pub(crate) state: DeletionStatusMutation,
}
Used to serialize a mutation without cloning strings.
Implements
Serializabletrait for efficient serialization.Conversion from
&KeyValueMutationis provided.
VersionedValueForSerialization
An internal helper struct for serialization/deserialization of VersionedValue.
struct VersionedValueForSerialization {
pub value: String,
pub version: Version,
pub status: DeletionStatusMutation,
}
Serializes deletion status as
DeletionStatusMutationto avoid serializing transient timestamps.
Type Alias: Version
A type alias for the version number of a key, defined as u64.
pub type Version = u64;
Heartbeat
Represents a node's heartbeat value.
pub struct Heartbeat(pub(crate) u64);
Provides incrementing functionality with wrapping add.
Default initialized to zero.
Implements conversions to
u64.
Serialization and Deserialization
The file leverages the serde crate for serialization and deserialization of most structs and enums. Additionally, it defines custom traits Serializable and Deserializable (from other modules) to provide binary serialization for network transmission.
DeletionStatusMutationimplementsSerializableandDeserializablefor compact single-byte representation.KeyValueMutationandKeyValueMutationRefimplement these traits to serialize key, value, version, and deletion status mutation in sequence.
Interaction with Other System Parts
The
ChitchatIdidentifies nodes uniquely and is used in cluster membership and gossip protocols.VersionedValueand related mutation types are core components for state synchronization between nodes, enabling versioned updates and deletion handling.DeletionStatusandDeletionStatusMutationprovide the mechanism for marking keys as deleted or scheduled for deletion with time references, supporting eventual consistency and garbage collection.The serialization traits integrate with the system's network layer for encoding and decoding messages exchanged between nodes.
The heartbeat type is used to track node liveness and update frequencies.
Important Implementation Details
The use of
InstantinDeletionStatusis a reference point, not an absolute deletion time; this design helps manage deletion timing logic externally.The separation of
DeletionStatusandDeletionStatusMutationsupports serialized mutation commands distinct from runtime deletion states.The
PartialEqimplementations for test purposes ignore timestamps to allow equality checks based on logical state rather than exact timing.VersionedValueserialization converts deletion status to a mutation enum to avoid serializing transient timestamps, which may lead to precision loss for TTL-based deletions.The
ChitchatIdgeneration ID mechanism supports restart detection and cluster membership consistency.
Usage Examples
Creating a Node Identifier
use std::net::SocketAddr;
let addr: SocketAddr = "192.168.1.10:9000".parse().unwrap();
let node_id = ChitchatId::new("node-123".to_string(), 1, addr);
println!("{:?}", node_id); // Prints: node-123:1:192.168.1.10:9000
Creating a Versioned Value Marked as Deleted
use tokio::time::Instant;
let version = 10u64;
let val = VersionedValue::new("some data".to_string(), version, true);
assert!(val.is_deleted());
Serializing a KeyValueMutationRef
let mutation = KeyValueMutation {
key: "key1".to_string(),
value: "value1".to_string(),
version: 7,
status: DeletionStatusMutation::Set,
};
let mutation_ref: KeyValueMutationRef = (&mutation).into();
let mut buf = Vec::new();
mutation_ref.serialize(&mut buf);
Mermaid Diagram
classDiagram
class ChitchatId {
+node_id: String
+generation_id: u64
+gossip_advertise_addr: SocketAddr
+new()
}
class DeletionStatus {
<<enum>>
+Set
+Deleted
+DeleteAfterTtl
+time_of_start_scheduled_for_deletion()
}
class VersionedValue {
+value: String
+version: Version
+status: DeletionStatus
+new()
+is_deleted()
}
class KeyValueMutation {
+key: String
+value: String
+version: Version
+status: DeletionStatusMutation
}
class DeletionStatusMutation {
<<enum>>
+Set
+Delete
+DeleteAfterTtl
+into_status()
+scheduled_for_deletion()
}
class KeyValueMutationRef {
+key: &str
+value: &str
+version: Version
+state: DeletionStatusMutation
+serialize()
}
class Heartbeat {
+u64
+inc()
}
ChitchatId --> SocketAddr
VersionedValue --> DeletionStatus
KeyValueMutation --> DeletionStatusMutation
KeyValueMutationRef --> DeletionStatusMutation
VersionedValue --|> VersionedValueForSerialization
DeletionStatusMutation --|> u8
Heartbeat o-- u64
This diagram depicts the main structs and enums, their properties, and key methods, as well as their relationship to each other and primitive types. It highlights the core data structures used for node identification, state versioning, mutation, and deletion status management.