use std::fmt;
use std::sync::Arc;
use std::time::Duration;
use crate::{
ProtocolId, SessionId,
context::SessionContext,
error::{DialerErrorKind, ListenErrorKind, ProtocolHandleErrorKind},
multiaddr::Multiaddr,
service::{TargetProtocol, TargetSession, future_task::BoxedFutureTask},
};
use bytes::Bytes;
#[derive(Debug)]
pub(crate) enum ServiceEventAndError {
Event {
event: ServiceEvent,
wait_response: Option<futures::channel::oneshot::Sender<()>>,
},
Error(ServiceError),
Update {
listen_addrs: Vec<multiaddr::MultiAddr>,
},
}
impl ServiceEventAndError {
pub fn wait_response(self, tx: futures::channel::oneshot::Sender<()>) -> Self {
if let ServiceEventAndError::Event { event, .. } = self {
ServiceEventAndError::Event {
event,
wait_response: Some(tx),
}
} else {
self
}
}
}
impl From<ServiceEvent> for ServiceEventAndError {
fn from(event: ServiceEvent) -> Self {
ServiceEventAndError::Event {
event,
wait_response: None,
}
}
}
impl From<ServiceError> for ServiceEventAndError {
fn from(event: ServiceError) -> Self {
ServiceEventAndError::Error(event)
}
}
#[derive(Debug)]
pub enum ServiceError {
DialerError {
address: Multiaddr,
error: DialerErrorKind,
},
ListenError {
address: Multiaddr,
error: ListenErrorKind,
},
ProtocolSelectError {
proto_name: Option<String>,
session_context: Arc<SessionContext>,
},
ProtocolError {
id: SessionId,
proto_id: ProtocolId,
error: std::io::Error,
},
SessionTimeout {
session_context: Arc<SessionContext>,
},
MuxerError {
session_context: Arc<SessionContext>,
error: std::io::Error,
},
ProtocolHandleError {
proto_id: ProtocolId,
error: ProtocolHandleErrorKind,
},
SessionBlocked {
session_context: Arc<SessionContext>,
},
}
#[derive(Debug)]
pub enum ServiceEvent {
SessionClose {
session_context: Arc<SessionContext>,
},
SessionOpen {
session_context: Arc<SessionContext>,
},
ListenClose {
address: Multiaddr,
},
ListenStarted {
address: Multiaddr,
},
}
pub(crate) enum ServiceTask {
ProtocolMessage {
target: TargetSession,
proto_id: ProtocolId,
data: Bytes,
},
ProtocolOpen {
session_id: SessionId,
target: TargetProtocol,
},
ProtocolClose {
session_id: SessionId,
proto_id: ProtocolId,
},
SetProtocolNotify {
proto_id: ProtocolId,
interval: Duration,
token: u64,
},
RemoveProtocolNotify {
proto_id: ProtocolId,
token: u64,
},
SetProtocolSessionNotify {
session_id: SessionId,
proto_id: ProtocolId,
interval: Duration,
token: u64,
},
RemoveProtocolSessionNotify {
session_id: SessionId,
proto_id: ProtocolId,
token: u64,
},
FutureTask {
task: BoxedFutureTask,
},
Disconnect {
session_id: SessionId,
},
Dial {
address: Multiaddr,
target: TargetProtocol,
},
Listen {
address: Multiaddr,
},
RawSession {
remote_address: Multiaddr,
raw_session: Box<dyn crate::session::AsyncRw + Send + Unpin + 'static>,
session_info: RawSessionInfo,
},
Shutdown(bool),
}
pub enum RawSessionInfo {
Inbound {
listen_addr: Multiaddr,
},
Outbound {
target: TargetProtocol,
},
}
impl RawSessionInfo {
pub fn inbound(listen_addr: Multiaddr) -> Self {
RawSessionInfo::Inbound { listen_addr }
}
pub fn outbound(target: TargetProtocol) -> Self {
RawSessionInfo::Outbound { target }
}
}
impl fmt::Debug for ServiceTask {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::ServiceTask::*;
match self {
ProtocolMessage { proto_id, data, .. } => {
write!(f, "proto_id: {}, message: {:?}", proto_id, data)
}
SetProtocolNotify {
proto_id, token, ..
} => write!(f, "set protocol({}) notify({})", proto_id, token),
RemoveProtocolNotify { proto_id, token } => {
write!(f, "remove protocol({}) notify({})", proto_id, token)
}
SetProtocolSessionNotify {
session_id,
proto_id,
token,
..
} => write!(
f,
"set protocol({}) session({}) notify({})",
proto_id, session_id, token
),
RemoveProtocolSessionNotify {
session_id,
proto_id,
token,
} => write!(
f,
"remove protocol({}) session({}) notify({})",
proto_id, session_id, token
),
FutureTask { .. } => write!(f, "Future task"),
Disconnect { session_id } => write!(f, "Disconnect session [{}]", session_id),
Dial { address, .. } => write!(f, "Dial address: {}", address),
Listen { address } => write!(f, "Listen address: {}", address),
RawSession { remote_address, .. } => write!(f, "Raw session from: {}", remote_address),
ProtocolOpen { session_id, .. } => write!(f, "Open session [{}] proto", session_id),
ProtocolClose {
session_id,
proto_id,
} => write!(f, "Close session [{}] proto [{}]", session_id, proto_id),
Shutdown(_) => write!(f, "Try close service"),
}
}
}