use async_channel::Sender;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use crate::{
error::{Error, ErrorKind},
gossip::GossipEvent,
storage_engine::EntryValue,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ShardEvent {
Gossip(GossipEvent),
Set(String, Vec<u8>, Vec<u8>, OffsetDateTime),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ShardRequest {
Ping,
GetMetadata,
GetCollections,
CreateCollection(String, u16),
DropCollection(String),
Set(String, Vec<u8>, Vec<u8>, OffsetDateTime),
Delete(String, Vec<u8>, OffsetDateTime),
Get(String, Vec<u8>),
}
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct NodeMetadata {
pub name: String,
pub ip: String,
pub remote_shard_base_port: u16,
pub ids: Vec<u16>,
pub gossip_port: u16,
pub db_port: u16,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ShardResponse {
Pong,
GetMetadata(Vec<NodeMetadata>),
GetCollections(Vec<(String, u16)>),
CreateCollection,
DropCollection,
Set,
Delete,
Get(Option<EntryValue>),
Error(ErrorKind, String),
}
impl ShardResponse {
pub fn new_err(e: &Error) -> Self {
Self::Error(e.kind(), e.to_string())
}
}
#[macro_export]
macro_rules! response_to_result {
($response:expr, $identifier:path) => {
match $response {
$identifier(inner_value) => Ok(inner_value),
ShardResponse::Error(kind, e) => Err(Error::ResponseError(kind, e)),
_ => Err(Error::ResponseWrongType),
}
};
}
#[macro_export]
macro_rules! response_to_empty_result {
($response:expr, $identifier:path) => {
match $response {
$identifier => Ok(()),
ShardResponse::Error(kind, e) => Err(Error::ResponseError(kind, e)),
_ => Err(Error::ResponseWrongType),
}
};
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ShardMessage {
Event(ShardEvent),
Request(ShardRequest),
Response(ShardResponse),
}
#[derive(Debug)]
pub struct ShardPacket {
pub source_id: u16,
pub message: ShardMessage,
pub response_sender: Option<Sender<ShardResponse>>,
}
impl ShardPacket {
#[must_use]
pub fn new(id: u16, message: ShardMessage) -> Self {
Self {
source_id: id,
message,
response_sender: None,
}
}
#[must_use]
pub fn new_request(
id: u16,
message: ShardMessage,
sender: Sender<ShardResponse>,
) -> Self {
Self {
source_id: id,
message,
response_sender: Some(sender),
}
}
}