mod topology_description;
use std::time::Duration;
use serde::Deserialize;
use crate::{
bson::{oid::ObjectId, Document},
error::Error,
options::ServerAddress,
};
pub use crate::sdam::public::TopologyType;
pub use topology_description::TopologyDescription;
pub type ServerDescription = crate::sdam::public::ServerInfo<'static>;
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct ServerDescriptionChangedEvent {
pub address: ServerAddress,
pub topology_id: ObjectId,
pub previous_description: ServerDescription,
pub new_description: ServerDescription,
}
impl ServerDescriptionChangedEvent {
#[cfg(test)]
pub(crate) fn is_marked_unknown_event(&self) -> bool {
self.previous_description
.description
.server_type
.is_available()
&& self.new_description.description.server_type == crate::ServerType::Unknown
}
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct ServerOpeningEvent {
pub address: ServerAddress,
#[serde(skip, default = "ObjectId::new")]
pub topology_id: ObjectId,
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct ServerClosedEvent {
pub address: ServerAddress,
#[serde(skip, default = "ObjectId::new")]
pub topology_id: ObjectId,
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct TopologyDescriptionChangedEvent {
pub topology_id: ObjectId,
pub previous_description: TopologyDescription,
pub new_description: TopologyDescription,
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct TopologyOpeningEvent {
#[serde(skip, default = "ObjectId::new")]
pub topology_id: ObjectId,
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct TopologyClosedEvent {
#[serde(skip, default = "ObjectId::new")]
pub topology_id: ObjectId,
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct ServerHeartbeatStartedEvent {
pub server_address: ServerAddress,
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct ServerHeartbeatSucceededEvent {
pub duration: Duration,
pub reply: Document,
pub server_address: ServerAddress,
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct ServerHeartbeatFailedEvent {
pub duration: Duration,
pub failure: Error,
pub server_address: ServerAddress,
}
#[derive(Clone, Debug)]
pub(crate) enum SdamEvent {
ServerDescriptionChanged(Box<ServerDescriptionChangedEvent>),
ServerOpening(ServerOpeningEvent),
ServerClosed(ServerClosedEvent),
TopologyDescriptionChanged(Box<TopologyDescriptionChangedEvent>),
TopologyOpening(TopologyOpeningEvent),
TopologyClosed(TopologyClosedEvent),
ServerHeartbeatStarted(ServerHeartbeatStartedEvent),
ServerHeartbeatSucceeded(ServerHeartbeatSucceededEvent),
ServerHeartbeatFailed(ServerHeartbeatFailedEvent),
}
pub trait SdamEventHandler: Send + Sync {
fn handle_server_description_changed_event(&self, _event: ServerDescriptionChangedEvent) {}
fn handle_server_opening_event(&self, _event: ServerOpeningEvent) {}
fn handle_server_closed_event(&self, _event: ServerClosedEvent) {}
fn handle_topology_description_changed_event(&self, _event: TopologyDescriptionChangedEvent) {}
fn handle_topology_opening_event(&self, _event: TopologyOpeningEvent) {}
fn handle_topology_closed_event(&self, _event: TopologyClosedEvent) {}
fn handle_server_heartbeat_started_event(&self, _event: ServerHeartbeatStartedEvent) {}
fn handle_server_heartbeat_succeeded_event(&self, _event: ServerHeartbeatSucceededEvent) {}
fn handle_server_heartbeat_failed_event(&self, _event: ServerHeartbeatFailedEvent) {}
}
pub(crate) fn handle_sdam_event(handler: &dyn SdamEventHandler, event: SdamEvent) {
match event {
SdamEvent::ServerClosed(event) => handler.handle_server_closed_event(event),
SdamEvent::ServerDescriptionChanged(e) => {
handler.handle_server_description_changed_event(*e)
}
SdamEvent::ServerOpening(e) => handler.handle_server_opening_event(e),
SdamEvent::TopologyDescriptionChanged(e) => {
handler.handle_topology_description_changed_event(*e)
}
SdamEvent::TopologyOpening(e) => handler.handle_topology_opening_event(e),
SdamEvent::TopologyClosed(e) => handler.handle_topology_closed_event(e),
SdamEvent::ServerHeartbeatStarted(e) => handler.handle_server_heartbeat_started_event(e),
SdamEvent::ServerHeartbeatSucceeded(e) => {
handler.handle_server_heartbeat_succeeded_event(e)
}
SdamEvent::ServerHeartbeatFailed(e) => handler.handle_server_heartbeat_failed_event(e),
}
}