Skip to content

Commit dc61738

Browse files
Diego PardoDGPardo
authored andcommitted
Decoupling TCP Writer
1 parent 034f079 commit dc61738

12 files changed

Lines changed: 101 additions & 84 deletions

File tree

crates/hotfix/src/initiator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::config::SessionConfig;
1515
use crate::message::FixMessage;
1616
use crate::session::SessionRef;
1717
use crate::store::MessageStore;
18-
use crate::transport::FixConnection;
18+
use crate::transport::connect;
1919

2020
pub struct Initiator<M> {
2121
pub config: SessionConfig,
@@ -60,7 +60,7 @@ async fn establish_connection<M: FixMessage>(config: SessionConfig, session_ref:
6060
}
6161
session_ref.await_active_session_time().await;
6262

63-
match FixConnection::connect(&config, session_ref.clone()).await {
63+
match connect(&config, session_ref.clone()).await {
6464
Ok(conn) => {
6565
session_ref.register_writer(conn.get_writer()).await;
6666

crates/hotfix/src/session.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::message::heartbeat::Heartbeat;
2222
use crate::message::logon::{Logon, ResetSeqNumConfig};
2323
use crate::message::parser::RawFixMessage;
2424
use crate::store::MessageStore;
25-
use crate::transport::socket_writer::WriterRef;
25+
use crate::transport::writer::WriterRef;
2626

2727
use crate::error::MessageVerificationError;
2828
use crate::message::logout::Logout;

crates/hotfix/src/session/event.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use tokio::sync::oneshot;
22

33
use crate::message::parser::RawFixMessage;
4-
use crate::transport::socket_writer::WriterRef;
4+
use crate::transport::writer::WriterRef;
55

66
#[derive(Debug)]
77
pub enum SessionEvent<M> {

crates/hotfix/src/session/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::message::parser::RawFixMessage;
22
use crate::session::event::AwaitingActiveSessionResponse;
3-
use crate::transport::socket_writer::WriterRef;
3+
use crate::transport::writer::WriterRef;
44
use hotfix_message::message::Message;
55
use std::collections::VecDeque;
66
use tokio::sync::oneshot;

crates/hotfix/src/transport.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
mod connection;
2-
pub(crate) mod socket_reader;
3-
pub(crate) mod socket_writer;
4-
mod tcp;
5-
mod tls;
2+
pub mod socket;
3+
pub mod writer;
64

75
pub use connection::FixConnection;
6+
pub use socket::*;
Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,18 @@
1-
use std::io;
2-
use tokio::io::{AsyncRead, AsyncWrite};
3-
4-
use crate::config::SessionConfig;
5-
use crate::message::FixMessage;
6-
use crate::session::SessionRef;
71
use crate::transport::socket_reader::ReaderRef;
8-
use crate::transport::socket_writer::WriterRef;
9-
use crate::transport::tcp::create_tcp_connection;
10-
use crate::transport::tls::create_tcp_over_tls_connection;
2+
use crate::transport::writer::WriterRef;
113

124
pub struct FixConnection {
135
_writer: WriterRef,
146
_reader: ReaderRef,
157
}
168

179
impl FixConnection {
18-
pub async fn connect(
19-
config: &SessionConfig,
20-
session_ref: SessionRef<impl FixMessage>,
21-
) -> io::Result<Self> {
22-
let use_tls = config.tls_config.is_some();
23-
24-
let conn = if use_tls {
25-
let stream = create_tcp_over_tls_connection(config).await?;
26-
_create_io_refs(session_ref.clone(), stream).await
27-
} else {
28-
let stream = create_tcp_connection(config).await?;
29-
_create_io_refs(session_ref.clone(), stream).await
30-
};
31-
32-
Ok(conn)
10+
pub fn new(writer: WriterRef, reader: ReaderRef) -> Self {
11+
Self {
12+
_writer: writer,
13+
_reader: reader,
14+
}
3315
}
34-
3516
pub fn get_writer(&self) -> WriterRef {
3617
self._writer.clone()
3718
}
@@ -40,19 +21,3 @@ impl FixConnection {
4021
self._reader.wait_for_disconnect().await
4122
}
4223
}
43-
44-
async fn _create_io_refs<M, Stream>(session_ref: SessionRef<M>, stream: Stream) -> FixConnection
45-
where
46-
M: FixMessage,
47-
Stream: AsyncRead + AsyncWrite + Send + 'static,
48-
{
49-
let (reader, writer) = tokio::io::split(stream);
50-
51-
let writer_ref = WriterRef::new(writer);
52-
let reader_ref = ReaderRef::new(reader, session_ref);
53-
54-
FixConnection {
55-
_writer: writer_ref,
56-
_reader: reader_ref,
57-
}
58-
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
pub mod socket_reader;
2+
pub mod socket_writer;
3+
pub mod tcp;
4+
pub mod tls;
5+
6+
use std::io;
7+
use tokio::io::{AsyncRead, AsyncWrite};
8+
9+
use crate::{
10+
config::SessionConfig,
11+
message::FixMessage,
12+
session::SessionRef,
13+
transport::{
14+
FixConnection, socket_reader::ReaderRef, socket_writer::spawn_socket_writer,
15+
tcp::create_tcp_connection, tls::create_tcp_over_tls_connection,
16+
},
17+
};
18+
19+
/// Connect over TCP/TLS and return a FixConnection
20+
pub async fn connect(
21+
config: &SessionConfig,
22+
session_ref: SessionRef<impl FixMessage>,
23+
) -> io::Result<FixConnection> {
24+
let use_tls = config.tls_config.is_some();
25+
26+
let conn = if use_tls {
27+
let stream = create_tcp_over_tls_connection(config).await?;
28+
_create_io_refs(session_ref.clone(), stream).await
29+
} else {
30+
let stream = create_tcp_connection(config).await?;
31+
_create_io_refs(session_ref.clone(), stream).await
32+
};
33+
34+
Ok(conn)
35+
}
36+
37+
async fn _create_io_refs<M, Stream>(session_ref: SessionRef<M>, stream: Stream) -> FixConnection
38+
where
39+
M: FixMessage,
40+
Stream: AsyncRead + AsyncWrite + Send + 'static,
41+
{
42+
let (reader, writer) = tokio::io::split(stream);
43+
44+
let writer_ref = spawn_socket_writer(writer);
45+
let reader_ref = ReaderRef::new(reader, session_ref);
46+
47+
FixConnection::new(writer_ref, reader_ref)
48+
}
File renamed without changes.

crates/hotfix/src/transport/socket_writer.rs renamed to crates/hotfix/src/transport/socket/socket_writer.rs

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,14 @@
1+
use crate::transport::writer::{WriterMessage, WriterRef};
12
use tokio::io::{AsyncWrite, AsyncWriteExt, WriteHalf};
23
use tokio::sync::mpsc;
34
use tracing::{debug, warn};
45

5-
use crate::message::parser::RawFixMessage;
6+
pub fn spawn_socket_writer(writer: WriteHalf<impl AsyncWrite + Send + 'static>) -> WriterRef {
7+
let (sender, mailbox) = mpsc::channel(10);
8+
let actor = WriterActor::new(writer, mailbox);
9+
tokio::spawn(run_writer(actor));
610

7-
#[derive(Clone, Debug)]
8-
pub enum WriterMessage {
9-
SendMessage(RawFixMessage),
10-
Disconnect,
11-
}
12-
13-
#[derive(Clone, Debug)]
14-
pub struct WriterRef {
15-
sender: mpsc::Sender<WriterMessage>,
16-
}
17-
18-
impl WriterRef {
19-
pub fn new(writer: WriteHalf<impl AsyncWrite + Send + 'static>) -> Self {
20-
let (sender, mailbox) = mpsc::channel(10);
21-
let actor = WriterActor::new(writer, mailbox);
22-
tokio::spawn(run_writer(actor));
23-
24-
Self { sender }
25-
}
26-
27-
pub async fn send_raw_message(&self, msg: RawFixMessage) {
28-
self.sender
29-
.send(WriterMessage::SendMessage(msg))
30-
.await
31-
.expect("be able to send message");
32-
}
33-
34-
pub async fn disconnect(&self) {
35-
self.sender
36-
.send(WriterMessage::Disconnect)
37-
.await
38-
.expect("be able to disconnect")
39-
}
11+
WriterRef::new(sender)
4012
}
4113

4214
struct WriterActor<W> {

0 commit comments

Comments
 (0)