Skip to content

Commit

Permalink
refactor: sort and rename component clients into dedicated dirs
Browse files Browse the repository at this point in the history
  • Loading branch information
uriel-starkware committed Jul 23, 2024
1 parent d09a690 commit f50696c
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 211 deletions.
198 changes: 0 additions & 198 deletions crates/mempool_infra/src/component_client.rs

This file was deleted.

21 changes: 21 additions & 0 deletions crates/mempool_infra/src/component_client/definitions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use bincode::ErrorKind;
use hyper::{Error as HyperError, StatusCode};
use thiserror::Error;

use crate::component_definitions::ServerError;

#[derive(Debug, Error)]
pub enum ClientError {
#[error("Communication error: {0}")]
CommunicationFailure(HyperError),
#[error("Could not deserialize server response: {0}")]
ResponseDeserializationFailure(Box<ErrorKind>),
#[error("Could not parse the response: {0}")]
ResponseParsingFailure(HyperError),
#[error("Got status code: {0}, with server error: {1}")]
ResponseError(StatusCode, ServerError),
#[error("Got an unexpected response type.")]
UnexpectedResponse,
}

pub type ClientResult<T> = Result<T, ClientError>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use tokio::sync::mpsc::{channel, Sender};

use crate::component_definitions::ComponentRequestAndResponseSender;

/// The `LocalComponentClient` struct is a generic client for sending component requests and
/// receiving responses asynchronously.
///
/// # Type Parameters
/// - `Request`: The type of the request. This type must implement both `Send` and `Sync` traits.
/// - `Response`: The type of the response. This type must implement both `Send` and `Sync` traits.
///
/// # Fields
/// - `tx`: An asynchronous sender channel for transmitting
/// `ComponentRequestAndResponseSender<Request, Response>` messages.
///
/// # Example
/// ```rust
/// // Example usage of the LocalComponentClient
/// use tokio::sync::mpsc::Sender;
///
/// use crate::starknet_mempool_infra::component_client::local_component_client::LocalComponentClient;
/// use crate::starknet_mempool_infra::component_definitions::ComponentRequestAndResponseSender;
///
/// // Define your request and response types
/// struct MyRequest {
/// pub content: String,
/// }
///
/// struct MyResponse {
/// content: String,
/// }
///
/// #[tokio::main]
/// async fn main() {
/// // Create a channel for sending requests and receiving responses
/// let (tx, _rx) = tokio::sync::mpsc::channel::<
/// ComponentRequestAndResponseSender<MyRequest, MyResponse>,
/// >(100);
///
/// // Instantiate the client.
/// let client = LocalComponentClient::new(tx);
///
/// // Instantiate a request.
/// let request = MyRequest { content: "Hello, world!".to_string() };
///
/// // Send the request; typically, the client should await for a response.
/// client.send(request);
/// }
/// ```
///
/// # Notes
/// - The `LocalComponentClient` struct is designed to work in an asynchronous environment,
/// utilizing Tokio's async runtime and channels.
pub struct LocalComponentClient<Request, Response>
where
Request: Send + Sync,
Response: Send + Sync,
{
tx: Sender<ComponentRequestAndResponseSender<Request, Response>>,
}

impl<Request, Response> LocalComponentClient<Request, Response>
where
Request: Send + Sync,
Response: Send + Sync,
{
pub fn new(tx: Sender<ComponentRequestAndResponseSender<Request, Response>>) -> Self {
Self { tx }
}

// TODO(Tsabary, 1/5/2024): Consider implementation for messages without expected responses.

pub async fn send(&self, request: Request) -> Response {
let (res_tx, mut res_rx) = channel::<Response>(1);
let request_and_res_tx = ComponentRequestAndResponseSender { request, tx: res_tx };
self.tx.send(request_and_res_tx).await.expect("Outbound connection should be open.");

res_rx.recv().await.expect("Inbound connection should be open.")
}
}

// Can't derive because derive forces the generics to also be `Clone`, which we prefer not to do
// since it'll require transactions to be cloneable.
impl<Request, Response> Clone for LocalComponentClient<Request, Response>
where
Request: Send + Sync,
Response: Send + Sync,
{
fn clone(&self) -> Self {
Self { tx: self.tx.clone() }
}
}
3 changes: 3 additions & 0 deletions crates/mempool_infra/src/component_client/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod definitions;
pub mod local_component_client;
pub mod remote_component_client;
Loading

0 comments on commit f50696c

Please sign in to comment.