pb-mapper-server 0.6.1

Relay server implementation for pb-mapper
use std::{sync::Arc, time::Duration};

use snafu::Snafu;

use pb_mapper_core::conn_id::RemoteConnId;
// The `common::error::Error` spellings below are the source type on nearly every
// variant; aliasing keeps them as they were.
use pb_mapper_core as common;

#[derive(Debug, Snafu)]
#[snafu(visibility(pub(super)))]
pub enum Error {
    #[snafu(display("stream setup exceeded {timeout:?} for key {key}, client {conn_id}"))]
    ClientConnSetupTimeout {
        key: Arc<str>,
        conn_id: RemoteConnId,
        timeout: Duration,
    },
    #[snafu(display("administrator operation failed: {detail}"))]
    AdminOperation { detail: String },
    #[snafu(display(
        "timed out reading pb conn init request with `conn_id:{conn_id}` after {timeout:?}"
    ))]
    TaskCenterInitRequestTimeout {
        conn_id: RemoteConnId,
        timeout: Duration,
    },
    #[snafu(display("send listener task error, type:{source:?} detail:{source}"))]
    TaskCenterSendListener { source: kanal::SendError<()> },

    #[snafu(display(
        "client send server stream request error with `key:{key}` `client_id:{conn_id}`, \
         type:{source:?} detail:{source}"
    ))]
    TaskCenterClientSendStream {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display(
        "send server stream response to task manager error, `dst_id:{conn_id}`, \
         type:{source:?} detail:{source}"
    ))]
    TaskCenterSendStreamRespToManager {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display(
        "send server stream response to client error, `client_id:{conn_id}`, \
         type:{source:?} detail:{source}"
    ))]
    TaskCenterSendStreamRespToClient {
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display(
        "send server status response error with `conn_id:{conn_id}`, type:{source:?} \
         detail:{source}"
    ))]
    TaskCenterSendStatusResp {
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display(
        "send server register response error with `key:{key}` `conn_id:{conn_id}`, \
         type:{source:?} detail:{source}"
    ))]
    TaskCenterSendRegisterResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display("failed to process stream task, `dst_id:{conn_id}` does not exist"))]
    TaskCenterStreamConnIdNotExist { conn_id: RemoteConnId },
    #[snafu(display(
        "send client subcriber response error with `key:{key}` `conn_id:{conn_id}`, \
         type:{source:?} detail:{source}"
    ))]
    TaskCenterSendSubcribeResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display("remote stream to set keepalive error,when handle_listener"))]
    TaskCenterSetKeepAlive { source: std::io::Error },
    /// server handler error
    #[snafu(display("Server connection create header tool:`{tool}` fails!"))]
    ServerConnCreateHeaderTool {
        /// Must be `reader` or `writer`
        tool: &'static str,
        source: common::error::Error,
    },
    #[snafu(display(
        "server conn receive registered response error with `key:{key}` `server_id:{conn_id}`"
    ))]
    ServerConnRecvServerRegisteredResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::ReceiveError,
    },
    #[snafu(display(
        "the first message received after server registration must be the \
         `RegisterResp`,detail:`key:{key}` `conn_id:{conn_id}`"
    ))]
    ServerConnRegisteredRespNotMatch {
        key: Arc<str>,
        conn_id: RemoteConnId,
    },
    #[snafu(display(
        "server conn encode register resp error with `key:{key}` `conn_id:{conn_id}`"
    ))]
    ServerConnEncodeRegisterResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display("server conn write register resp error with `key:{key}` `conn_id:{conn_id}`"))]
    ServerConnWriteRegisteredOk {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display("server conn receive conn task error"))]
    ServerConnRecvConnTask { source: kanal::ReceiveError },
    #[snafu(display(
        "server conn write stream request to network error with `key:{key}` `server_id:{conn_id}`"
    ))]
    ServerConnWriteStreamRequest {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display(
        "server conn write pong response to local server error with `key:{key}` \
         `server_id:{conn_id}`"
    ))]
    ServerConnWritePongResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display("server conn control writer closed with `key:{key}` `server_id:{conn_id}`"))]
    ServerConnControlWriterClosed {
        key: Arc<str>,
        conn_id: RemoteConnId,
    },
    #[snafu(display(
        "server conn send stream ack to manager error with `key:{key}` `server_id:{conn_id}`"
    ))]
    ServerConnSendStreamAck {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display(
        "server conn decode stream request error with `key:{key}` `server_id:{conn_id}`"
    ))]
    ServerConnDecodeStreamRequest {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display(
        "send register task error with `key:{key}` `conn_id:{conn_id}`, \
         type:{source:?} detail:{source}"
    ))]
    ServerConnSendRegister {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    /// client handler error
    #[snafu(display("Client connection create header tool:`{tool}` fails!"))]
    ClientConnCreateHeaderTool {
        /// Must be `reader` or `writer`
        tool: &'static str,
        source: common::error::Error,
    },
    #[snafu(display("client data stream credential is inactive: {detail}"))]
    ClientConnAuthInactive { detail: String },
    #[snafu(display(
        "send subcribe task error with `key:{key}` `conn_id:{conn_id}`, type:{source:?} \
         detail:{source}"
    ))]
    ClientConnSendSubcribe {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::SendError<()>,
    },
    #[snafu(display("receive subcribe response error with `key:{key}` `client_id:{conn_id}`"))]
    ClientConnRecvSubcribeResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::ReceiveError,
    },
    #[snafu(display(
        "timed out waiting for subcribe response with `key:{key}` `client_id:{conn_id}` after \
         {timeout:?}"
    ))]
    ClientConnRecvSubcribeRespTimeout {
        key: Arc<str>,
        conn_id: RemoteConnId,
        timeout: Duration,
    },
    #[snafu(display("receive server stream error with `key:{key}` `client_id:{conn_id}`"))]
    ClientConnRecvStream {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: kanal::ReceiveError,
    },
    #[snafu(display(
        "received conn task not match! we expected subcribe response.  `key:{key}` \
         `client_id:{conn_id}`"
    ))]
    ClientConnSubcribeRespNotMatch {
        key: Arc<str>,
        conn_id: RemoteConnId,
    },
    #[snafu(display("subcribe failed with `key:{key}` `client_id:{conn_id}`, reason:{reason}"))]
    ClientConnSubcribeFailed {
        key: Arc<str>,
        conn_id: RemoteConnId,
        reason: String,
    },
    #[snafu(display(
        "received conn task not match! we expected stream response.  `key:{key}` \
         `client_id:{conn_id}`"
    ))]
    ClientConnStreamRespNotMatch {
        key: Arc<str>,
        conn_id: RemoteConnId,
    },
    #[snafu(display(
        "client conn encode subcribe resp error with `key:{key}` `conn_id:{conn_id}`"
    ))]
    ClientConnEncodeSubcribeResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display(
        "client conn encode server stream resp error with `key:{key}` `client_id:{conn_id}`"
    ))]
    ClientConnEncodeStreamResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display("client conn write subcribe resp error with `key:{key}` `conn_id:{conn_id}`"))]
    ClientConnWriteSubcribeResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    #[snafu(display(
        "client conn write server stream resp error with `key:{key}` `conn_id:{conn_id}`"
    ))]
    ClientConnWriteStreamResp {
        key: Arc<str>,
        conn_id: RemoteConnId,
        source: common::error::Error,
    },
    /// status handle error
    #[snafu(display("Status handler create header tool:`{tool}` fails!"))]
    StatusCreateHeaderTool {
        /// Must be `reader` or `writer`
        tool: &'static str,
        source: common::error::Error,
    },
    #[snafu(display("send status manager task error, type:{source:?} detail:{source}"))]
    StatusSendManagerTask { source: kanal::SendError<()> },
    #[snafu(display("receive `ConnTask::StatusResp` error"))]
    StatusRecvConnTask { source: kanal::ReceiveError },
    #[snafu(display("we expected `ConnTask::StatusResp`"))]
    StatusConnTaskNotMatch,
    #[snafu(display("encode status response error"))]
    StatusEncodeResp { source: common::error::Error },
    #[snafu(display("write status response error"))]
    StatusWriteResp { source: common::error::Error },
    #[snafu(display("Server listen error"))]
    ServerListen { source: std::io::Error },
}

pub type Result<T, E = Error> = std::result::Result<T, E>;