From cfc97de774b2d87ae088d64fda32e272f24d16dc Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sat, 28 Jun 2025 14:27:28 +0200 Subject: [PATCH 1/8] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Rename=20Socket(?= =?UTF-8?q?Acceptor|Initator)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename SocketAcceptor to Acceptor, and SocketInitator to Initator. The idea is to provide support for Threaded version of this classes. BREAKING CHANGE: ๐Ÿงจ API Change --- .../examples/cb-order-sender.rs | 2 +- examples/executor/src/main.rs | 2 +- examples/single-order-sender/src/main.rs | 2 +- quickfix-ffi/examples/demo_basic_binding.c | 8 ++-- quickfix-ffi/examples/demo_basic_ffi.rs | 8 ++-- .../quickfix-bind/include/quickfix_bind.h | 46 +++++++++--------- .../quickfix-bind/src/quickfix_bind.cpp | 40 ++++++++-------- quickfix-ffi/src/lib.rs | 48 +++++++++---------- quickfix/README.md | 2 +- quickfix/examples/demo_config.rs | 7 ++- quickfix/examples/fix_getting_started.rs | 2 +- quickfix/examples/fix_repl/main.rs | 8 ++-- .../src/{socket_acceptor.rs => acceptor.rs} | 36 +++++++------- .../src/{socket_initiator.rs => initiator.rs} | 37 +++++++------- quickfix/src/lib.rs | 10 ++-- quickfix/tests/test_send_receive.rs | 4 +- quickfix/tests/test_session.rs | 4 +- quickfix/tests/test_socket.rs | 4 +- quickfix/tests/utils/checker.rs | 4 +- 19 files changed, 136 insertions(+), 138 deletions(-) rename quickfix/src/{socket_acceptor.rs => acceptor.rs} (68%) rename quickfix/src/{socket_initiator.rs => initiator.rs} (68%) diff --git a/examples/coinbase-example/examples/cb-order-sender.rs b/examples/coinbase-example/examples/cb-order-sender.rs index 432bcb5..290c094 100644 --- a/examples/coinbase-example/examples/cb-order-sender.rs +++ b/examples/coinbase-example/examples/cb-order-sender.rs @@ -160,7 +160,7 @@ fn main() -> anyhow::Result<()> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&my_app)?; - let mut acceptor = SocketInitiator::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Initiator::try_new(&settings, &app, &store_factory, &log_factory)?; // Start the engine. println!(">> Starting FIX engine ๐Ÿš€"); diff --git a/examples/executor/src/main.rs b/examples/executor/src/main.rs index e522cb4..0b7fedd 100644 --- a/examples/executor/src/main.rs +++ b/examples/executor/src/main.rs @@ -148,7 +148,7 @@ fn main() -> Result<(), QuickFixError> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&executor)?; - let mut acceptor = SocketAcceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; acceptor.start()?; println!(">> App running, press 'q' to quit"); diff --git a/examples/single-order-sender/src/main.rs b/examples/single-order-sender/src/main.rs index 7830b2c..8ea4158 100644 --- a/examples/single-order-sender/src/main.rs +++ b/examples/single-order-sender/src/main.rs @@ -80,7 +80,7 @@ fn main() -> anyhow::Result<()> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&single_order_sender)?; - let mut acceptor = SocketInitiator::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Initiator::try_new(&settings, &app, &store_factory, &log_factory)?; // Start the engine. println!(">> Starting FIX engine ๐Ÿš€"); diff --git a/quickfix-ffi/examples/demo_basic_binding.c b/quickfix-ffi/examples/demo_basic_binding.c index d80a200..ae83459 100644 --- a/quickfix-ffi/examples/demo_basic_binding.c +++ b/quickfix-ffi/examples/demo_basic_binding.c @@ -71,20 +71,20 @@ int main(int argc, char **argv) { FixMessageStoreFactory_t *storeFactory = FixFileMessageStoreFactory_new(settings); FixLogFactory_t *logFactory = FixLogFactory_new((void *)0xFEED, &LOG_CALLBACKS); FixApplication_t *application = FixApplication_new((void *)0xBEEF, &APP_CALLBACKS); - FixSocketAcceptor_t *acceptor = FixSocketAcceptor_new(application, storeFactory, settings, logFactory); + FixAcceptor_t *acceptor = FixAcceptor_new(application, storeFactory, settings, logFactory); printf(">> Acceptor START\n"); - FixSocketAcceptor_start(acceptor); + FixAcceptor_start(acceptor); printf(">> Press Q to exit\n"); while (getchar() != 'q') { } printf(">> Acceptor STOP\n"); - FixSocketAcceptor_stop(acceptor); + FixAcceptor_stop(acceptor); printf(">> Cleaning resources\n"); - FixSocketAcceptor_delete(acceptor); + FixAcceptor_delete(acceptor); FixApplication_delete(application); FixLogFactory_delete(logFactory); FixMessageStoreFactory_delete(storeFactory); diff --git a/quickfix-ffi/examples/demo_basic_ffi.rs b/quickfix-ffi/examples/demo_basic_ffi.rs index ee0d976..dc886d0 100644 --- a/quickfix-ffi/examples/demo_basic_ffi.rs +++ b/quickfix-ffi/examples/demo_basic_ffi.rs @@ -117,11 +117,11 @@ fn main() { .expect("Fail to build log factory"); let application = FixApplication_new(0xFEED as *const ffi::c_void, &APP_CALLBACKS) .expect("Fail to build application"); - let acceptor = FixSocketAcceptor_new(application, store_factory, settings, log_factory) + let acceptor = FixAcceptor_new(application, store_factory, settings, log_factory) .expect("Fail to build acceptor"); println!(">> Acceptor START"); - assert_eq!(FixSocketAcceptor_start(acceptor), 0); + assert_eq!(FixAcceptor_start(acceptor), 0); println!(">> Press Q to exit"); loop { @@ -132,10 +132,10 @@ fn main() { } println!(">> Acceptor STOP"); - assert_eq!(FixSocketAcceptor_stop(acceptor), 0); + assert_eq!(FixAcceptor_stop(acceptor), 0); println!(">> Cleaning resources"); - FixSocketAcceptor_delete(acceptor); + FixAcceptor_delete(acceptor); FixApplication_delete(application); FixLogFactory_delete(log_factory); FixMessageStoreFactory_delete(store_factory); diff --git a/quickfix-ffi/quickfix-bind/include/quickfix_bind.h b/quickfix-ffi/quickfix-bind/include/quickfix_bind.h index 9d13ac0..0b6fd6b 100644 --- a/quickfix-ffi/quickfix-bind/include/quickfix_bind.h +++ b/quickfix-ffi/quickfix-bind/include/quickfix_bind.h @@ -60,8 +60,8 @@ typedef struct DataDictionary FixDataDictionary_t; typedef struct MessageStoreFactory FixMessageStoreFactory_t; typedef struct LogFactory FixLogFactory_t; typedef struct Application FixApplication_t; -typedef struct SocketAcceptor FixSocketAcceptor_t; -typedef struct SocketInitiator FixSocketInitiator_t; +typedef struct Acceptor FixAcceptor_t; +typedef struct Initiator FixInitiator_t; typedef struct Session FixSession_t; typedef struct SessionID FixSessionID_t; typedef struct Message FixMessage_t; @@ -136,27 +136,27 @@ void FixLogFactory_delete(const FixLogFactory_t *obj); FixApplication_t *FixApplication_new(const void *data, const FixApplicationCallbacks_t *callbacks); void FixApplication_delete(const FixApplication_t *obj); -FixSocketAcceptor_t *FixSocketAcceptor_new(FixApplication_t *application, FixMessageStoreFactory_t *storeFactory, - const FixSessionSettings_t *settings, FixLogFactory_t *logFactory); -int8_t FixSocketAcceptor_start(FixSocketAcceptor_t *obj); -int8_t FixSocketAcceptor_block(FixSocketAcceptor_t *obj); -int8_t FixSocketAcceptor_poll(FixSocketAcceptor_t *obj); -int8_t FixSocketAcceptor_stop(FixSocketAcceptor_t *obj); -int8_t FixSocketAcceptor_isLoggedOn(const FixSocketAcceptor_t *obj); -int8_t FixSocketAcceptor_isStopped(const FixSocketAcceptor_t *obj); -FixSession_t *FixSocketAcceptor_getSession(const FixSocketAcceptor_t *obj, const FixSessionID_t *sessionId); -void FixSocketAcceptor_delete(const FixSocketAcceptor_t *obj); - -FixSocketInitiator_t *FixSocketInitiator_new(FixApplication_t *application, FixMessageStoreFactory_t *storeFactory, - const FixSessionSettings_t *settings, FixLogFactory_t *logFactory); -int8_t FixSocketInitiator_start(FixSocketInitiator_t *obj); -int8_t FixSocketInitiator_block(FixSocketInitiator_t *obj); -int8_t FixSocketInitiator_poll(FixSocketInitiator_t *obj); -int8_t FixSocketInitiator_stop(FixSocketInitiator_t *obj); -int8_t FixSocketInitiator_isLoggedOn(const FixSocketInitiator_t *obj); -int8_t FixSocketInitiator_isStopped(const FixSocketInitiator_t *obj); -FixSession_t *FixSocketInitiator_getSession(const FixSocketInitiator_t *obj, const FixSessionID_t *sessionId); -void FixSocketInitiator_delete(const FixSocketInitiator_t *obj); +FixAcceptor_t *FixAcceptor_new(FixApplication_t *application, FixMessageStoreFactory_t *storeFactory, + const FixSessionSettings_t *settings, FixLogFactory_t *logFactory); +int8_t FixAcceptor_start(FixAcceptor_t *obj); +int8_t FixAcceptor_block(FixAcceptor_t *obj); +int8_t FixAcceptor_poll(FixAcceptor_t *obj); +int8_t FixAcceptor_stop(FixAcceptor_t *obj); +int8_t FixAcceptor_isLoggedOn(const FixAcceptor_t *obj); +int8_t FixAcceptor_isStopped(const FixAcceptor_t *obj); +FixSession_t *FixAcceptor_getSession(const FixAcceptor_t *obj, const FixSessionID_t *sessionId); +void FixAcceptor_delete(const FixAcceptor_t *obj); + +FixInitiator_t *FixInitiator_new(FixApplication_t *application, FixMessageStoreFactory_t *storeFactory, + const FixSessionSettings_t *settings, FixLogFactory_t *logFactory); +int8_t FixInitiator_start(FixInitiator_t *obj); +int8_t FixInitiator_block(FixInitiator_t *obj); +int8_t FixInitiator_poll(FixInitiator_t *obj); +int8_t FixInitiator_stop(FixInitiator_t *obj); +int8_t FixInitiator_isLoggedOn(const FixInitiator_t *obj); +int8_t FixInitiator_isStopped(const FixInitiator_t *obj); +FixSession_t *FixInitiator_getSession(const FixInitiator_t *obj, const FixSessionID_t *sessionId); +void FixInitiator_delete(const FixInitiator_t *obj); FixSessionID_t *FixSessionID_new(const char *beginString, const char *senderCompID, const char *targetCompID, const char *sessionQualifier); diff --git a/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp b/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp index 8232d2f..4a01ed3 100644 --- a/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp +++ b/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp @@ -539,8 +539,8 @@ void FixApplication_delete(const Application *obj) { delete obj; } -SocketAcceptor *FixSocketAcceptor_new(Application *application, MessageStoreFactory *storeFactory, - const SessionSettings *settings, LogFactory *logFactory) { +Acceptor *FixAcceptor_new(Application *application, MessageStoreFactory *storeFactory, const SessionSettings *settings, + LogFactory *logFactory) { RETURN_VAL_IF_NULL(application, NULL); RETURN_VAL_IF_NULL(storeFactory, NULL); RETURN_VAL_IF_NULL(logFactory, NULL); @@ -549,7 +549,7 @@ SocketAcceptor *FixSocketAcceptor_new(Application *application, MessageStoreFact CATCH_OR_RETURN_NULL({ return new SocketAcceptor(*application, *storeFactory, *settings, *logFactory); }); } -int8_t FixSocketAcceptor_start(SocketAcceptor *obj) { +int8_t FixAcceptor_start(Acceptor *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ obj->start(); @@ -557,7 +557,7 @@ int8_t FixSocketAcceptor_start(SocketAcceptor *obj) { }); } -int8_t FixSocketAcceptor_block(SocketAcceptor *obj) { +int8_t FixAcceptor_block(Acceptor *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ obj->block(); @@ -565,12 +565,12 @@ int8_t FixSocketAcceptor_block(SocketAcceptor *obj) { }); } -int8_t FixSocketAcceptor_poll(SocketAcceptor *obj) { +int8_t FixAcceptor_poll(Acceptor *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ return obj->poll(); }); } -int8_t FixSocketAcceptor_stop(SocketAcceptor *obj) { +int8_t FixAcceptor_stop(Acceptor *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ obj->stop(); @@ -578,29 +578,29 @@ int8_t FixSocketAcceptor_stop(SocketAcceptor *obj) { }); } -int8_t FixSocketAcceptor_isLoggedOn(const SocketAcceptor *obj) { +int8_t FixAcceptor_isLoggedOn(const Acceptor *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ return obj->isLoggedOn(); }); } -int8_t FixSocketAcceptor_isStopped(const SocketAcceptor *obj) { +int8_t FixAcceptor_isStopped(const Acceptor *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ return obj->isStopped(); }); } -FixSession_t *FixSocketAcceptor_getSession(const FixSocketAcceptor_t *obj, const FixSessionID_t *sessionId) { +FixSession_t *FixAcceptor_getSession(const FixAcceptor_t *obj, const FixSessionID_t *sessionId) { RETURN_VAL_IF_NULL(obj, NULL); RETURN_VAL_IF_NULL(sessionId, NULL); CATCH_OR_RETURN_NULL({ return obj->getSession(*sessionId); }); } -void FixSocketAcceptor_delete(const SocketAcceptor *obj) { +void FixAcceptor_delete(const Acceptor *obj) { RETURN_IF_NULL(obj); delete obj; } -SocketInitiator *FixSocketInitiator_new(Application *application, MessageStoreFactory *storeFactory, - const SessionSettings *settings, LogFactory *logFactory) { +Initiator *FixInitiator_new(Application *application, MessageStoreFactory *storeFactory, + const SessionSettings *settings, LogFactory *logFactory) { RETURN_VAL_IF_NULL(application, NULL); RETURN_VAL_IF_NULL(storeFactory, NULL); RETURN_VAL_IF_NULL(logFactory, NULL); @@ -609,7 +609,7 @@ SocketInitiator *FixSocketInitiator_new(Application *application, MessageStoreFa CATCH_OR_RETURN_NULL({ return new SocketInitiator(*application, *storeFactory, *settings, *logFactory); }); } -int8_t FixSocketInitiator_start(SocketInitiator *obj) { +int8_t FixInitiator_start(Initiator *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ obj->start(); @@ -617,7 +617,7 @@ int8_t FixSocketInitiator_start(SocketInitiator *obj) { }); } -int8_t FixSocketInitiator_block(SocketInitiator *obj) { +int8_t FixInitiator_block(Initiator *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ obj->block(); @@ -625,12 +625,12 @@ int8_t FixSocketInitiator_block(SocketInitiator *obj) { }); } -int8_t FixSocketInitiator_poll(SocketInitiator *obj) { +int8_t FixInitiator_poll(Initiator *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ return obj->poll(); }); } -int8_t FixSocketInitiator_stop(SocketInitiator *obj) { +int8_t FixInitiator_stop(Initiator *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ obj->stop(); @@ -638,23 +638,23 @@ int8_t FixSocketInitiator_stop(SocketInitiator *obj) { }); } -int8_t FixSocketInitiator_isLoggedOn(const SocketInitiator *obj) { +int8_t FixInitiator_isLoggedOn(const Initiator *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ return obj->isLoggedOn(); }); } -int8_t FixSocketInitiator_isStopped(const SocketInitiator *obj) { +int8_t FixInitiator_isStopped(const Initiator *obj) { RETURN_VAL_IF_NULL(obj, ERRNO_INVAL); CATCH_OR_RETURN_ERRNO({ return obj->isStopped(); }); } -FixSession_t *FixSocketInitiator_getSession(const FixSocketInitiator_t *obj, const FixSessionID_t *sessionId) { +FixSession_t *FixInitiator_getSession(const FixInitiator_t *obj, const FixSessionID_t *sessionId) { RETURN_VAL_IF_NULL(obj, NULL); RETURN_VAL_IF_NULL(sessionId, NULL); CATCH_OR_RETURN_NULL({ return obj->getSession(*sessionId); }); } -void FixSocketInitiator_delete(const SocketInitiator *obj) { +void FixInitiator_delete(const Initiator *obj) { RETURN_IF_NULL(obj); delete obj; } diff --git a/quickfix-ffi/src/lib.rs b/quickfix-ffi/src/lib.rs index 480bac2..94a55af 100644 --- a/quickfix-ffi/src/lib.rs +++ b/quickfix-ffi/src/lib.rs @@ -56,11 +56,11 @@ pub struct FixMessage_t(NonNull); #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(transparent)] -pub struct FixSocketAcceptor_t(NonNull); +pub struct FixAcceptor_t(NonNull); #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(transparent)] -pub struct FixSocketInitiator_t(NonNull); +pub struct FixInitiator_t(NonNull); #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(transparent)] @@ -242,71 +242,71 @@ extern "C" { // Socket acceptor - pub fn FixSocketAcceptor_new( + pub fn FixAcceptor_new( application: FixApplication_t, storeFactory: FixMessageStoreFactory_t, settings: FixSessionSettings_t, logFactory: FixLogFactory_t, - ) -> Option; + ) -> Option; #[must_use] - pub fn FixSocketAcceptor_start(obj: FixSocketAcceptor_t) -> i8; + pub fn FixAcceptor_start(obj: FixAcceptor_t) -> i8; #[must_use] - pub fn FixSocketAcceptor_block(obj: FixSocketAcceptor_t) -> i8; + pub fn FixAcceptor_block(obj: FixAcceptor_t) -> i8; #[must_use] - pub fn FixSocketAcceptor_poll(obj: FixSocketAcceptor_t) -> i8; + pub fn FixAcceptor_poll(obj: FixAcceptor_t) -> i8; #[must_use] - pub fn FixSocketAcceptor_stop(obj: FixSocketAcceptor_t) -> i8; + pub fn FixAcceptor_stop(obj: FixAcceptor_t) -> i8; #[must_use] - pub fn FixSocketAcceptor_isLoggedOn(obj: FixSocketAcceptor_t) -> i8; + pub fn FixAcceptor_isLoggedOn(obj: FixAcceptor_t) -> i8; #[must_use] - pub fn FixSocketAcceptor_isStopped(obj: FixSocketAcceptor_t) -> i8; + pub fn FixAcceptor_isStopped(obj: FixAcceptor_t) -> i8; - pub fn FixSocketAcceptor_getSession( - obj: FixSocketAcceptor_t, + pub fn FixAcceptor_getSession( + obj: FixAcceptor_t, sessionId: FixSessionID_t, ) -> Option; - pub fn FixSocketAcceptor_delete(obj: FixSocketAcceptor_t); + pub fn FixAcceptor_delete(obj: FixAcceptor_t); // Socket initiator - pub fn FixSocketInitiator_new( + pub fn FixInitiator_new( application: FixApplication_t, storeFactory: FixMessageStoreFactory_t, settings: FixSessionSettings_t, logFactory: FixLogFactory_t, - ) -> Option; + ) -> Option; #[must_use] - pub fn FixSocketInitiator_start(obj: FixSocketInitiator_t) -> i8; + pub fn FixInitiator_start(obj: FixInitiator_t) -> i8; #[must_use] - pub fn FixSocketInitiator_block(obj: FixSocketInitiator_t) -> i8; + pub fn FixInitiator_block(obj: FixInitiator_t) -> i8; #[must_use] - pub fn FixSocketInitiator_poll(obj: FixSocketInitiator_t) -> i8; + pub fn FixInitiator_poll(obj: FixInitiator_t) -> i8; #[must_use] - pub fn FixSocketInitiator_stop(obj: FixSocketInitiator_t) -> i8; + pub fn FixInitiator_stop(obj: FixInitiator_t) -> i8; #[must_use] - pub fn FixSocketInitiator_isLoggedOn(obj: FixSocketInitiator_t) -> i8; + pub fn FixInitiator_isLoggedOn(obj: FixInitiator_t) -> i8; #[must_use] - pub fn FixSocketInitiator_isStopped(obj: FixSocketInitiator_t) -> i8; + pub fn FixInitiator_isStopped(obj: FixInitiator_t) -> i8; - pub fn FixSocketInitiator_getSession( - obj: FixSocketInitiator_t, + pub fn FixInitiator_getSession( + obj: FixInitiator_t, sessionId: FixSessionID_t, ) -> Option; - pub fn FixSocketInitiator_delete(obj: FixSocketInitiator_t); + pub fn FixInitiator_delete(obj: FixInitiator_t); // Session ID diff --git a/quickfix/README.md b/quickfix/README.md index 3d582de..9ee46a0 100644 --- a/quickfix/README.md +++ b/quickfix/README.md @@ -87,7 +87,7 @@ fn main() -> Result<(), QuickFixError> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&MyApplication)?; - let mut acceptor = SocketAcceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; acceptor.start()?; println!(">> App running, press 'q' to quit"); diff --git a/quickfix/examples/demo_config.rs b/quickfix/examples/demo_config.rs index fcd7487..daa80ea 100644 --- a/quickfix/examples/demo_config.rs +++ b/quickfix/examples/demo_config.rs @@ -1,9 +1,8 @@ use std::io::{stdin, Read}; use quickfix::{ - dictionary_item::*, Application, ApplicationCallback, ConnectionHandler, Dictionary, - LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, SessionSettings, - SocketAcceptor, StdLogger, + dictionary_item::*, Acceptor, Application, ApplicationCallback, ConnectionHandler, Dictionary, + LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, SessionSettings, StdLogger, }; #[derive(Default)] @@ -53,7 +52,7 @@ fn main() -> Result<(), QuickFixError> { let callbacks = MyApplication; let app = Application::try_new(&callbacks)?; - let mut acceptor = SocketAcceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; println!(">> connection handler START"); acceptor.start()?; diff --git a/quickfix/examples/fix_getting_started.rs b/quickfix/examples/fix_getting_started.rs index e10c330..8642186 100644 --- a/quickfix/examples/fix_getting_started.rs +++ b/quickfix/examples/fix_getting_started.rs @@ -31,7 +31,7 @@ fn main() -> Result<(), QuickFixError> { let callbacks = MyApplication; let app = Application::try_new(&callbacks)?; - let mut acceptor = SocketAcceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; println!(">> connection handler START"); acceptor.start()?; diff --git a/quickfix/examples/fix_repl/main.rs b/quickfix/examples/fix_repl/main.rs index a5efda4..56698fa 100644 --- a/quickfix/examples/fix_repl/main.rs +++ b/quickfix/examples/fix_repl/main.rs @@ -1,8 +1,8 @@ use std::{env, process::exit}; use quickfix::{ - Application, ConnectionHandler, FileMessageStoreFactory, LogFactory, QuickFixError, - SessionSettings, SocketAcceptor, SocketInitiator, StdLogger, + Acceptor, Application, ConnectionHandler, FileMessageStoreFactory, Initiator, LogFactory, + QuickFixError, SessionSettings, StdLogger, }; use crate::{command_exec::FixShell, fix_app::MyApplication}; @@ -29,13 +29,13 @@ fn main() -> Result<(), QuickFixError> { let app = Application::try_new(&callbacks)?; match connect_mode.as_str() { - "initiator" => server_loop(SocketInitiator::try_new( + "initiator" => server_loop(Initiator::try_new( &settings, &app, &store_factory, &log_factory, )?), - "acceptor" => server_loop(SocketAcceptor::try_new( + "acceptor" => server_loop(Acceptor::try_new( &settings, &app, &store_factory, diff --git a/quickfix/src/socket_acceptor.rs b/quickfix/src/acceptor.rs similarity index 68% rename from quickfix/src/socket_acceptor.rs rename to quickfix/src/acceptor.rs index e36767b..4559b59 100644 --- a/quickfix/src/socket_acceptor.rs +++ b/quickfix/src/acceptor.rs @@ -1,9 +1,9 @@ use std::marker::PhantomData; use quickfix_ffi::{ - FixSocketAcceptor_block, FixSocketAcceptor_delete, FixSocketAcceptor_getSession, - FixSocketAcceptor_isLoggedOn, FixSocketAcceptor_isStopped, FixSocketAcceptor_new, - FixSocketAcceptor_poll, FixSocketAcceptor_start, FixSocketAcceptor_stop, FixSocketAcceptor_t, + FixAcceptor_block, FixAcceptor_delete, FixAcceptor_getSession, FixAcceptor_isLoggedOn, + FixAcceptor_isStopped, FixAcceptor_new, FixAcceptor_poll, FixAcceptor_start, FixAcceptor_stop, + FixAcceptor_t, }; use crate::{ @@ -14,19 +14,19 @@ use crate::{ /// Socket implementation of incoming connections handler. #[derive(Debug)] -pub struct SocketAcceptor<'a, A, L, S> +pub struct Acceptor<'a, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, L: LogCallback, { - inner: FixSocketAcceptor_t, + inner: FixAcceptor_t, phantom_application: PhantomData<&'a A>, phantom_message_store_factory: PhantomData<&'a S>, phantom_log_factory: PhantomData<&'a L>, } -impl<'a, A, L, S> SocketAcceptor<'a, A, L, S> +impl<'a, A, L, S> Acceptor<'a, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, @@ -40,7 +40,7 @@ where log_factory: &'a LogFactory, ) -> Result { match unsafe { - FixSocketAcceptor_new( + FixAcceptor_new( application.0, store_factory.as_ffi_ptr(), settings.0, @@ -58,38 +58,38 @@ where } } -impl ConnectionHandler for SocketAcceptor<'_, A, L, S> +impl ConnectionHandler for Acceptor<'_, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, L: LogCallback, { fn start(&mut self) -> Result<(), QuickFixError> { - ffi_code_to_result(unsafe { FixSocketAcceptor_start(self.inner) }) + ffi_code_to_result(unsafe { FixAcceptor_start(self.inner) }) } fn block(&mut self) -> Result<(), QuickFixError> { - ffi_code_to_result(unsafe { FixSocketAcceptor_block(self.inner) }) + ffi_code_to_result(unsafe { FixAcceptor_block(self.inner) }) } fn poll(&mut self) -> Result { - ffi_code_to_bool(unsafe { FixSocketAcceptor_poll(self.inner) }) + ffi_code_to_bool(unsafe { FixAcceptor_poll(self.inner) }) } fn stop(&mut self) -> Result<(), QuickFixError> { - ffi_code_to_result(unsafe { FixSocketAcceptor_stop(self.inner) }) + ffi_code_to_result(unsafe { FixAcceptor_stop(self.inner) }) } fn is_logged_on(&self) -> Result { - ffi_code_to_bool(unsafe { FixSocketAcceptor_isLoggedOn(self.inner) }) + ffi_code_to_bool(unsafe { FixAcceptor_isLoggedOn(self.inner) }) } fn is_stopped(&self) -> Result { - ffi_code_to_bool(unsafe { FixSocketAcceptor_isStopped(self.inner) }) + ffi_code_to_bool(unsafe { FixAcceptor_isStopped(self.inner) }) } } -impl SessionContainer for SocketAcceptor<'_, A, L, S> +impl SessionContainer for Acceptor<'_, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, @@ -97,7 +97,7 @@ where { fn session(&self, session_id: SessionId) -> Result, QuickFixError> { unsafe { - FixSocketAcceptor_getSession(self.inner, session_id.0) + FixAcceptor_getSession(self.inner, session_id.0) .map(|inner| Session { inner, phantom_container: PhantomData, @@ -109,7 +109,7 @@ where } } -impl Drop for SocketAcceptor<'_, A, L, S> +impl Drop for Acceptor<'_, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, @@ -117,6 +117,6 @@ where { fn drop(&mut self) { let _ = self.stop(); - unsafe { FixSocketAcceptor_delete(self.inner) } + unsafe { FixAcceptor_delete(self.inner) } } } diff --git a/quickfix/src/socket_initiator.rs b/quickfix/src/initiator.rs similarity index 68% rename from quickfix/src/socket_initiator.rs rename to quickfix/src/initiator.rs index 55d8d32..d8a548d 100644 --- a/quickfix/src/socket_initiator.rs +++ b/quickfix/src/initiator.rs @@ -1,10 +1,9 @@ use std::marker::PhantomData; use quickfix_ffi::{ - FixSocketInitiator_block, FixSocketInitiator_delete, FixSocketInitiator_getSession, - FixSocketInitiator_isLoggedOn, FixSocketInitiator_isStopped, FixSocketInitiator_new, - FixSocketInitiator_poll, FixSocketInitiator_start, FixSocketInitiator_stop, - FixSocketInitiator_t, + FixInitiator_block, FixInitiator_delete, FixInitiator_getSession, FixInitiator_isLoggedOn, + FixInitiator_isStopped, FixInitiator_new, FixInitiator_poll, FixInitiator_start, + FixInitiator_stop, FixInitiator_t, }; use crate::{ @@ -15,19 +14,19 @@ use crate::{ /// Socket implementation of establishing connections handler. #[derive(Debug)] -pub struct SocketInitiator<'a, A, L, S> +pub struct Initiator<'a, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, L: LogCallback, { - inner: FixSocketInitiator_t, + inner: FixInitiator_t, phantom_application: PhantomData<&'a A>, phantom_message_store_factory: PhantomData<&'a S>, phantom_log_factory: PhantomData<&'a L>, } -impl<'a, A, L, S> SocketInitiator<'a, A, L, S> +impl<'a, A, L, S> Initiator<'a, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, @@ -41,7 +40,7 @@ where log_factory: &'a LogFactory, ) -> Result { match unsafe { - FixSocketInitiator_new( + FixInitiator_new( application.0, store_factory.as_ffi_ptr(), settings.0, @@ -59,38 +58,38 @@ where } } -impl ConnectionHandler for SocketInitiator<'_, A, L, S> +impl ConnectionHandler for Initiator<'_, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, L: LogCallback, { fn start(&mut self) -> Result<(), QuickFixError> { - ffi_code_to_result(unsafe { FixSocketInitiator_start(self.inner) }) + ffi_code_to_result(unsafe { FixInitiator_start(self.inner) }) } fn block(&mut self) -> Result<(), QuickFixError> { - ffi_code_to_result(unsafe { FixSocketInitiator_block(self.inner) }) + ffi_code_to_result(unsafe { FixInitiator_block(self.inner) }) } fn poll(&mut self) -> Result { - ffi_code_to_bool(unsafe { FixSocketInitiator_poll(self.inner) }) + ffi_code_to_bool(unsafe { FixInitiator_poll(self.inner) }) } fn stop(&mut self) -> Result<(), QuickFixError> { - ffi_code_to_result(unsafe { FixSocketInitiator_stop(self.inner) }) + ffi_code_to_result(unsafe { FixInitiator_stop(self.inner) }) } fn is_logged_on(&self) -> Result { - ffi_code_to_bool(unsafe { FixSocketInitiator_isLoggedOn(self.inner) }) + ffi_code_to_bool(unsafe { FixInitiator_isLoggedOn(self.inner) }) } fn is_stopped(&self) -> Result { - ffi_code_to_bool(unsafe { FixSocketInitiator_isStopped(self.inner) }) + ffi_code_to_bool(unsafe { FixInitiator_isStopped(self.inner) }) } } -impl SessionContainer for SocketInitiator<'_, A, L, S> +impl SessionContainer for Initiator<'_, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, @@ -98,7 +97,7 @@ where { fn session(&self, session_id: SessionId) -> Result, QuickFixError> { unsafe { - FixSocketInitiator_getSession(self.inner, session_id.0) + FixInitiator_getSession(self.inner, session_id.0) .map(|inner| Session { inner, phantom_container: PhantomData, @@ -110,7 +109,7 @@ where } } -impl Drop for SocketInitiator<'_, A, L, S> +impl Drop for Initiator<'_, A, L, S> where A: ApplicationCallback, S: FfiMessageStoreFactory, @@ -118,6 +117,6 @@ where { fn drop(&mut self) { let _ = self.stop(); - unsafe { FixSocketInitiator_delete(self.inner) } + unsafe { FixInitiator_delete(self.inner) } } } diff --git a/quickfix/src/lib.rs b/quickfix/src/lib.rs index b3a62b7..8fe8657 100644 --- a/quickfix/src/lib.rs +++ b/quickfix/src/lib.rs @@ -81,7 +81,7 @@ let store_factory = MemoryMessageStoreFactory::new(); let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&MyApplication)?; -let mut acceptor = SocketAcceptor::try_new(&settings, &app, &store_factory, &log_factory)?; +let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; // Start session. acceptor.start()?; @@ -98,6 +98,7 @@ acceptor.stop()?; */ +mod acceptor; mod application; mod data_dictionary; mod days; @@ -107,20 +108,20 @@ pub mod dictionary_item; mod error; mod group; mod header; +mod initiator; mod log_factory; mod message; mod message_store_factory; mod session; mod session_id; mod session_settings; -mod socket_acceptor; -mod socket_initiator; mod trailer; mod utils; use std::ffi::{CString, NulError}; +pub use acceptor::Acceptor; pub use application::{ Application, ApplicationCallback, MsgFromAdminError, MsgFromAppError, MsgToAppError, }; @@ -130,6 +131,7 @@ pub use dictionary::Dictionary; pub use error::QuickFixError; pub use group::Group; pub use header::Header; +pub use initiator::Initiator; pub use log_factory::{LogCallback, LogFactory, NullLogger, StdLogger}; pub use message::Message; pub use message_store_factory::{ @@ -139,8 +141,6 @@ pub use message_store_factory::{ pub use session::{send_to_target, Session}; pub use session_id::SessionId; pub use session_settings::SessionSettings; -pub use socket_acceptor::SocketAcceptor; -pub use socket_initiator::SocketInitiator; pub use trailer::Trailer; #[cfg(feature = "log")] diff --git a/quickfix/tests/test_send_receive.rs b/quickfix/tests/test_send_receive.rs index 9edcd47..425117a 100644 --- a/quickfix/tests/test_send_receive.rs +++ b/quickfix/tests/test_send_receive.rs @@ -32,13 +32,13 @@ fn test_full_fix_application() -> Result<(), QuickFixError> { assert_eq!(receiver.user_msg_count(), MsgCounter::default()); // Init socket acceptor / initiator. - let mut socket_sender = SocketInitiator::try_new( + let mut socket_sender = Initiator::try_new( &settings_sender, &app_sender, &message_store_factory_sender, &log_factory, )?; - let mut socket_receiver = SocketAcceptor::try_new( + let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, diff --git a/quickfix/tests/test_session.rs b/quickfix/tests/test_session.rs index bf55cac..f467ab7 100644 --- a/quickfix/tests/test_session.rs +++ b/quickfix/tests/test_session.rs @@ -28,13 +28,13 @@ fn test_session_login_logout() -> Result<(), QuickFixError> { assert_eq!(receiver.session_created(), 0); // Init socket acceptor / initiator. - let mut socket_sender = SocketInitiator::try_new( + let mut socket_sender = Initiator::try_new( &settings_sender, &app_sender, &message_store_factory_sender, &log_factory, )?; - let mut socket_receiver = SocketAcceptor::try_new( + let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, diff --git a/quickfix/tests/test_socket.rs b/quickfix/tests/test_socket.rs index f1cc5e5..ef86b4a 100644 --- a/quickfix/tests/test_socket.rs +++ b/quickfix/tests/test_socket.rs @@ -35,7 +35,7 @@ fn test_handler() { let logger = LogFactory::try_new(&StdLogger::Stdout).unwrap(); check_connection_handler( - SocketAcceptor::try_new(&settings, &app, &message_store, &logger).unwrap(), + Acceptor::try_new(&settings, &app, &message_store, &logger).unwrap(), ); } @@ -46,7 +46,7 @@ fn test_handler() { let logger = LogFactory::try_new(&StdLogger::Stdout).unwrap(); check_connection_handler( - SocketInitiator::try_new(&settings, &app, &message_store, &logger).unwrap(), + Initiator::try_new(&settings, &app, &message_store, &logger).unwrap(), ); } } diff --git a/quickfix/tests/utils/checker.rs b/quickfix/tests/utils/checker.rs index d8a04ed..3eb04e0 100644 --- a/quickfix/tests/utils/checker.rs +++ b/quickfix/tests/utils/checker.rs @@ -35,13 +35,13 @@ pub fn run( let app_receiver = Application::try_new(&receiver)?; // Init socket acceptor / initiator. - let mut socket_sender = SocketInitiator::try_new( + let mut socket_sender = Initiator::try_new( &settings_sender, &app_sender, &message_store_factory_sender, &log_factory, )?; - let mut socket_receiver = SocketAcceptor::try_new( + let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, From cd5f370d0e8f19b0be470647978c8165ea924631 Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sat, 28 Jun 2025 14:33:17 +0200 Subject: [PATCH 2/8] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Do=20not=20exclu?= =?UTF-8?q?ded=20ThreadSocket*=20files=20from=20C++=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quickfix-ffi/Cargo.toml | 2 -- quickfix-ffi/build.rs | 7 ------- 2 files changed, 9 deletions(-) diff --git a/quickfix-ffi/Cargo.toml b/quickfix-ffi/Cargo.toml index fb30ab8..6789fab 100644 --- a/quickfix-ffi/Cargo.toml +++ b/quickfix-ffi/Cargo.toml @@ -25,8 +25,6 @@ include = [ "!/libquickfix/**/*.sh", # Exclude SSL related code (we will inject dummy files to replace them in build.rs) "!/libquickfix/src/C++/*SSL*.*", - # Exclude Threaded socket application related code (we will inject dummy files to replace them in build.rs) - "!/libquickfix/src/C++/ThreadedSocket*.*", # Do not include auto generated message files. "!/libquickfix/src/C++/fix40", "!/libquickfix/src/C++/fix41", diff --git a/quickfix-ffi/build.rs b/quickfix-ffi/build.rs index 6c6142c..9ee2a27 100644 --- a/quickfix-ffi/build.rs +++ b/quickfix-ffi/build.rs @@ -53,13 +53,6 @@ fn main() { touch_file(libquickfix_cpp_dir.join("ThreadedSSLSocketInitiator.h")); touch_file(libquickfix_cpp_dir.join("UtilitySSL.h")); - touch_file(libquickfix_cpp_dir.join("ThreadedSocketAcceptor.h")); - touch_file(libquickfix_cpp_dir.join("ThreadedSocketAcceptor.cpp")); - touch_file(libquickfix_cpp_dir.join("ThreadedSocketConnection.h")); - touch_file(libquickfix_cpp_dir.join("ThreadedSocketConnection.cpp")); - touch_file(libquickfix_cpp_dir.join("ThreadedSocketInitiator.h")); - touch_file(libquickfix_cpp_dir.join("ThreadedSocketInitiator.cpp")); - // Build quickfix as a static library let quickfix_dst = Config::new(libquickfix_build_dir) .define("CMAKE_POLICY_VERSION_MINIMUM", "3.10") From 7454ba3e23d6aa0d49e82fd7fe10aad963c54706 Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sat, 28 Jun 2025 14:34:39 +0200 Subject: [PATCH 3/8] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20Update=20ABOUT?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ABOUT.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/doc/ABOUT.md b/doc/ABOUT.md index 5c2fccc..a90aadb 100644 --- a/doc/ABOUT.md +++ b/doc/ABOUT.md @@ -27,17 +27,12 @@ What I do **not** plan to bind from this crate: Use original library instead obviously. -3. Threaded versions of socket acceptor / initiator. - - Multithreading model is just too different between Rust / C++. - It is much more simple to handle correctly multithreading from Rust side and use single thread C++ socket handler. - -4. Autotools build toolchain. +3. Autotools build toolchain. Just use `cmake` once and for all ! We are in 2023+ and not targeting OS from the 80s. -5. FIX 5x messages generated code. +4. FIX 5x messages generated code. FIX 5x XML definition is a little bit weird ... For example: @@ -48,20 +43,20 @@ What I do **not** plan to bind from this crate: You can edit XML spec to your need and create a package with desired spec locally.\ Check FAQ for more info on this. -6. All binding of `LogFactory`. +5. All binding of `LogFactory`. I just provide Rust standard trait. You can implement whatever you want using standard Rust crate and impl 3 callbacks (logger / redis / syslog / sql / ...). Moreover Rust file descriptor are protected by mutex, so this avoid mixing log from C++ / Rust in the same program. -7. Custom `MessageStoreFactory` from rust. +6. Custom `MessageStoreFactory` from rust. For now, only `FileMessageStoreFactory` and `MemoryMessageStoreFactory` are bind. You can use also use `MySqlMessageStoreFactory` and `PostgresMessageStoreFactory` when enabling crate feature flag. Implementing message store from rust side is a little bit tricky and I am not 100% sure of the correct way to proceed. -8. Exotic operating system. +7. Exotic operating system. AIX / Solaris are not targeted. They are not Rust [Tier1](https://doc.rust-lang.org/nightly/rustc/platform-support.html) for now. From ee71e8a348b4140c6a8c159c5016225fc215e7e2 Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sat, 28 Jun 2025 15:16:57 +0200 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20multi=20thread?= =?UTF-8?q?ed=20connection=20mode=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 29 +++++++++++++++++++ .../examples/cb-order-sender.rs | 8 ++++- examples/executor/src/main.rs | 8 ++++- examples/single-order-sender/src/main.rs | 8 ++++- quickfix-ffi/examples/demo_basic_binding.c | 2 +- quickfix-ffi/examples/demo_basic_ffi.rs | 2 +- .../quickfix-bind/include/quickfix_bind.h | 6 ++-- .../quickfix-bind/src/quickfix_bind.cpp | 22 +++++++++++--- quickfix-ffi/src/lib.rs | 2 ++ quickfix/Cargo.toml | 1 + quickfix/README.md | 8 ++++- quickfix/examples/demo_config.rs | 11 +++++-- quickfix/examples/fix_getting_started.rs | 8 ++++- quickfix/examples/fix_repl/main.rs | 4 ++- quickfix/src/acceptor.rs | 6 ++-- quickfix/src/initiator.rs | 6 ++-- quickfix/src/lib.rs | 28 +++++++++++++++++- quickfix/tests/test_send_receive.rs | 10 ++----- quickfix/tests/test_session.rs | 2 ++ quickfix/tests/test_socket.rs | 18 ++++++++++-- quickfix/tests/utils/checker.rs | 2 ++ 21 files changed, 161 insertions(+), 30 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..594cd95 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +## v0.2.0 + +### Breaking changes + +Add support for multi threaded socket acceptor and initiator. + +To create socket acceptor and initiator you must change below code: + +```diff +- let mut acceptor = SocketInitiator::try_new(&settings, &app, &store_factory, &log_factory)?; ++ let mut acceptor = Initiator::try_new( ++ &settings, ++ &app, ++ &store_factory, ++ &log_factory, ++ ConnectionMode::SingleThreaded, ++ )?; + +- let mut initiator = SocketInitiator::try_new(&settings, &app, &message_store, &logger)?; ++ let mut initiator = Initiator::try_new( ++ &settings, ++ &app, ++ &message_store, ++ &logger, ++ ConnectionMode::default(), ++ )?; +``` diff --git a/examples/coinbase-example/examples/cb-order-sender.rs b/examples/coinbase-example/examples/cb-order-sender.rs index 290c094..78fc55b 100644 --- a/examples/coinbase-example/examples/cb-order-sender.rs +++ b/examples/coinbase-example/examples/cb-order-sender.rs @@ -160,7 +160,13 @@ fn main() -> anyhow::Result<()> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&my_app)?; - let mut acceptor = Initiator::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Initiator::try_new( + &settings, + &app, + &store_factory, + &log_factory, + ConnectionMode::SingleThreaded, + )?; // Start the engine. println!(">> Starting FIX engine ๐Ÿš€"); diff --git a/examples/executor/src/main.rs b/examples/executor/src/main.rs index 0b7fedd..e096e65 100644 --- a/examples/executor/src/main.rs +++ b/examples/executor/src/main.rs @@ -148,7 +148,13 @@ fn main() -> Result<(), QuickFixError> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&executor)?; - let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new( + &settings, + &app, + &store_factory, + &log_factory, + ConnectionMode::SingleThreaded, + )?; acceptor.start()?; println!(">> App running, press 'q' to quit"); diff --git a/examples/single-order-sender/src/main.rs b/examples/single-order-sender/src/main.rs index 8ea4158..41bf493 100644 --- a/examples/single-order-sender/src/main.rs +++ b/examples/single-order-sender/src/main.rs @@ -80,7 +80,13 @@ fn main() -> anyhow::Result<()> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&single_order_sender)?; - let mut acceptor = Initiator::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Initiator::try_new( + &settings, + &app, + &store_factory, + &log_factory, + ConnectionMode::SingleThreaded, + )?; // Start the engine. println!(">> Starting FIX engine ๐Ÿš€"); diff --git a/quickfix-ffi/examples/demo_basic_binding.c b/quickfix-ffi/examples/demo_basic_binding.c index ae83459..2770f5c 100644 --- a/quickfix-ffi/examples/demo_basic_binding.c +++ b/quickfix-ffi/examples/demo_basic_binding.c @@ -71,7 +71,7 @@ int main(int argc, char **argv) { FixMessageStoreFactory_t *storeFactory = FixFileMessageStoreFactory_new(settings); FixLogFactory_t *logFactory = FixLogFactory_new((void *)0xFEED, &LOG_CALLBACKS); FixApplication_t *application = FixApplication_new((void *)0xBEEF, &APP_CALLBACKS); - FixAcceptor_t *acceptor = FixAcceptor_new(application, storeFactory, settings, logFactory); + FixAcceptor_t *acceptor = FixAcceptor_new(application, storeFactory, settings, logFactory, false); printf(">> Acceptor START\n"); FixAcceptor_start(acceptor); diff --git a/quickfix-ffi/examples/demo_basic_ffi.rs b/quickfix-ffi/examples/demo_basic_ffi.rs index dc886d0..b27e508 100644 --- a/quickfix-ffi/examples/demo_basic_ffi.rs +++ b/quickfix-ffi/examples/demo_basic_ffi.rs @@ -117,7 +117,7 @@ fn main() { .expect("Fail to build log factory"); let application = FixApplication_new(0xFEED as *const ffi::c_void, &APP_CALLBACKS) .expect("Fail to build application"); - let acceptor = FixAcceptor_new(application, store_factory, settings, log_factory) + let acceptor = FixAcceptor_new(application, store_factory, settings, log_factory, 0) .expect("Fail to build acceptor"); println!(">> Acceptor START"); diff --git a/quickfix-ffi/quickfix-bind/include/quickfix_bind.h b/quickfix-ffi/quickfix-bind/include/quickfix_bind.h index 0b6fd6b..2835b20 100644 --- a/quickfix-ffi/quickfix-bind/include/quickfix_bind.h +++ b/quickfix-ffi/quickfix-bind/include/quickfix_bind.h @@ -137,7 +137,8 @@ FixApplication_t *FixApplication_new(const void *data, const FixApplicationCallb void FixApplication_delete(const FixApplication_t *obj); FixAcceptor_t *FixAcceptor_new(FixApplication_t *application, FixMessageStoreFactory_t *storeFactory, - const FixSessionSettings_t *settings, FixLogFactory_t *logFactory); + const FixSessionSettings_t *settings, FixLogFactory_t *logFactory, + int8_t isMultiThreaded); int8_t FixAcceptor_start(FixAcceptor_t *obj); int8_t FixAcceptor_block(FixAcceptor_t *obj); int8_t FixAcceptor_poll(FixAcceptor_t *obj); @@ -148,7 +149,8 @@ FixSession_t *FixAcceptor_getSession(const FixAcceptor_t *obj, const FixSessionI void FixAcceptor_delete(const FixAcceptor_t *obj); FixInitiator_t *FixInitiator_new(FixApplication_t *application, FixMessageStoreFactory_t *storeFactory, - const FixSessionSettings_t *settings, FixLogFactory_t *logFactory); + const FixSessionSettings_t *settings, FixLogFactory_t *logFactory, + int8_t isMultiThreaded); int8_t FixInitiator_start(FixInitiator_t *obj); int8_t FixInitiator_block(FixInitiator_t *obj); int8_t FixInitiator_poll(FixInitiator_t *obj); diff --git a/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp b/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp index 4a01ed3..3e35bcb 100644 --- a/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp +++ b/quickfix-ffi/quickfix-bind/src/quickfix_bind.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #ifdef HAVE_MYSQL #include @@ -540,13 +542,19 @@ void FixApplication_delete(const Application *obj) { } Acceptor *FixAcceptor_new(Application *application, MessageStoreFactory *storeFactory, const SessionSettings *settings, - LogFactory *logFactory) { + LogFactory *logFactory, int8_t isMultiThreaded) { RETURN_VAL_IF_NULL(application, NULL); RETURN_VAL_IF_NULL(storeFactory, NULL); RETURN_VAL_IF_NULL(logFactory, NULL); RETURN_VAL_IF_NULL(settings, NULL); - CATCH_OR_RETURN_NULL({ return new SocketAcceptor(*application, *storeFactory, *settings, *logFactory); }); + CATCH_OR_RETURN_NULL({ + if (isMultiThreaded) { + return new ThreadedSocketAcceptor(*application, *storeFactory, *settings, *logFactory); + } else { + return new SocketAcceptor(*application, *storeFactory, *settings, *logFactory); + } + }); } int8_t FixAcceptor_start(Acceptor *obj) { @@ -600,13 +608,19 @@ void FixAcceptor_delete(const Acceptor *obj) { } Initiator *FixInitiator_new(Application *application, MessageStoreFactory *storeFactory, - const SessionSettings *settings, LogFactory *logFactory) { + const SessionSettings *settings, LogFactory *logFactory, int8_t isMultiThreaded) { RETURN_VAL_IF_NULL(application, NULL); RETURN_VAL_IF_NULL(storeFactory, NULL); RETURN_VAL_IF_NULL(logFactory, NULL); RETURN_VAL_IF_NULL(settings, NULL); - CATCH_OR_RETURN_NULL({ return new SocketInitiator(*application, *storeFactory, *settings, *logFactory); }); + CATCH_OR_RETURN_NULL({ + if (isMultiThreaded) { + return new ThreadedSocketInitiator(*application, *storeFactory, *settings, *logFactory); + } else { + return new SocketInitiator(*application, *storeFactory, *settings, *logFactory); + } + }); } int8_t FixInitiator_start(Initiator *obj) { diff --git a/quickfix-ffi/src/lib.rs b/quickfix-ffi/src/lib.rs index 94a55af..ed22521 100644 --- a/quickfix-ffi/src/lib.rs +++ b/quickfix-ffi/src/lib.rs @@ -247,6 +247,7 @@ extern "C" { storeFactory: FixMessageStoreFactory_t, settings: FixSessionSettings_t, logFactory: FixLogFactory_t, + isMultiThreaded: i8, ) -> Option; #[must_use] @@ -281,6 +282,7 @@ extern "C" { storeFactory: FixMessageStoreFactory_t, settings: FixSessionSettings_t, logFactory: FixLogFactory_t, + isMultiThreaded: i8, ) -> Option; #[must_use] diff --git a/quickfix/Cargo.toml b/quickfix/Cargo.toml index adf55b1..0eb6330 100644 --- a/quickfix/Cargo.toml +++ b/quickfix/Cargo.toml @@ -20,3 +20,4 @@ default = ["log"] build-with-mysql = ["quickfix-ffi/build-with-mysql"] build-with-postgres = ["quickfix-ffi/build-with-postgres"] log = ["dep:log"] +experimental-multi-thread-support = [] diff --git a/quickfix/README.md b/quickfix/README.md index 9ee46a0..7abc18a 100644 --- a/quickfix/README.md +++ b/quickfix/README.md @@ -87,7 +87,13 @@ fn main() -> Result<(), QuickFixError> { let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&MyApplication)?; - let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new( + &settings, + &app, + &store_factory, + &log_factory, + ConnectionMode::SingleThreaded, + )?; acceptor.start()?; println!(">> App running, press 'q' to quit"); diff --git a/quickfix/examples/demo_config.rs b/quickfix/examples/demo_config.rs index daa80ea..3148460 100644 --- a/quickfix/examples/demo_config.rs +++ b/quickfix/examples/demo_config.rs @@ -2,7 +2,8 @@ use std::io::{stdin, Read}; use quickfix::{ dictionary_item::*, Acceptor, Application, ApplicationCallback, ConnectionHandler, Dictionary, - LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, SessionSettings, StdLogger, + LogFactory, MemoryMessageStoreFactory, QuickFixError, ConnectionMode, SessionId, SessionSettings, + StdLogger, }; #[derive(Default)] @@ -52,7 +53,13 @@ fn main() -> Result<(), QuickFixError> { let callbacks = MyApplication; let app = Application::try_new(&callbacks)?; - let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new( + &settings, + &app, + &store_factory, + &log_factory, + ConnectionMode::SingleThreaded, + )?; println!(">> connection handler START"); acceptor.start()?; diff --git a/quickfix/examples/fix_getting_started.rs b/quickfix/examples/fix_getting_started.rs index 8642186..57de81f 100644 --- a/quickfix/examples/fix_getting_started.rs +++ b/quickfix/examples/fix_getting_started.rs @@ -31,7 +31,13 @@ fn main() -> Result<(), QuickFixError> { let callbacks = MyApplication; let app = Application::try_new(&callbacks)?; - let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; + let mut acceptor = Acceptor::try_new( + &settings, + &app, + &store_factory, + &log_factory, + ConnectionMode::SingleThreaded, + )?; println!(">> connection handler START"); acceptor.start()?; diff --git a/quickfix/examples/fix_repl/main.rs b/quickfix/examples/fix_repl/main.rs index 56698fa..378739d 100644 --- a/quickfix/examples/fix_repl/main.rs +++ b/quickfix/examples/fix_repl/main.rs @@ -2,7 +2,7 @@ use std::{env, process::exit}; use quickfix::{ Acceptor, Application, ConnectionHandler, FileMessageStoreFactory, Initiator, LogFactory, - QuickFixError, SessionSettings, StdLogger, + QuickFixError, ConnectionMode, SessionSettings, StdLogger, }; use crate::{command_exec::FixShell, fix_app::MyApplication}; @@ -34,12 +34,14 @@ fn main() -> Result<(), QuickFixError> { &app, &store_factory, &log_factory, + ConnectionMode::SingleThreaded, )?), "acceptor" => server_loop(Acceptor::try_new( &settings, &app, &store_factory, &log_factory, + ConnectionMode::SingleThreaded, )?), _ => { eprintln!("Invalid connection mode"); diff --git a/quickfix/src/acceptor.rs b/quickfix/src/acceptor.rs index 4559b59..4a0691e 100644 --- a/quickfix/src/acceptor.rs +++ b/quickfix/src/acceptor.rs @@ -8,8 +8,8 @@ use quickfix_ffi::{ use crate::{ utils::{ffi_code_to_bool, ffi_code_to_result}, - Application, ApplicationCallback, ConnectionHandler, FfiMessageStoreFactory, LogCallback, - LogFactory, QuickFixError, Session, SessionContainer, SessionId, SessionSettings, + Application, ApplicationCallback, ConnectionHandler, ConnectionMode, FfiMessageStoreFactory, + LogCallback, LogFactory, QuickFixError, Session, SessionContainer, SessionId, SessionSettings, }; /// Socket implementation of incoming connections handler. @@ -38,6 +38,7 @@ where application: &'a Application, store_factory: &'a S, log_factory: &'a LogFactory, + server_mode: ConnectionMode, ) -> Result { match unsafe { FixAcceptor_new( @@ -45,6 +46,7 @@ where store_factory.as_ffi_ptr(), settings.0, log_factory.0, + server_mode.is_single_threaded() as i8, ) } { Some(inner) => Ok(Self { diff --git a/quickfix/src/initiator.rs b/quickfix/src/initiator.rs index d8a548d..5b56d3e 100644 --- a/quickfix/src/initiator.rs +++ b/quickfix/src/initiator.rs @@ -8,8 +8,8 @@ use quickfix_ffi::{ use crate::{ utils::{ffi_code_to_bool, ffi_code_to_result}, - Application, ApplicationCallback, ConnectionHandler, FfiMessageStoreFactory, LogCallback, - LogFactory, QuickFixError, Session, SessionContainer, SessionId, SessionSettings, + Application, ApplicationCallback, ConnectionHandler, ConnectionMode, FfiMessageStoreFactory, + LogCallback, LogFactory, QuickFixError, Session, SessionContainer, SessionId, SessionSettings, }; /// Socket implementation of establishing connections handler. @@ -38,6 +38,7 @@ where application: &'a Application, store_factory: &'a S, log_factory: &'a LogFactory, + server_mode: ConnectionMode, ) -> Result { match unsafe { FixInitiator_new( @@ -45,6 +46,7 @@ where store_factory.as_ffi_ptr(), settings.0, log_factory.0, + server_mode.is_single_threaded() as i8, ) } { Some(inner) => Ok(Self { diff --git a/quickfix/src/lib.rs b/quickfix/src/lib.rs index 8fe8657..b29e1ac 100644 --- a/quickfix/src/lib.rs +++ b/quickfix/src/lib.rs @@ -81,7 +81,13 @@ let store_factory = MemoryMessageStoreFactory::new(); let log_factory = LogFactory::try_new(&StdLogger::Stdout)?; let app = Application::try_new(&MyApplication)?; -let mut acceptor = Acceptor::try_new(&settings, &app, &store_factory, &log_factory)?; +let mut acceptor = Acceptor::try_new( + &settings, + &app, + &store_factory, + &log_factory, + ConnectionMode::SingleThreaded, +)?; // Start session. acceptor.start()?; @@ -268,3 +274,23 @@ pub trait ForeignPropertySetter { /// Write foreign value into object. fn ffi_set(&mut self, key: CString, value: T) -> Result<(), QuickFixError>; } + +/// Underlying interface of FIX server to use. +/// +/// This enum may add in future version SSL version of server mode. +#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)] +#[non_exhaustive] +pub enum ConnectionMode { + /// Single threaded version of Acceptor and Initiator. + #[default] + SingleThreaded, + /// Multi threaded version of Acceptor and Initiator. + #[cfg(feature = "experimental-multi-thread-support")] + MultiThreaded, +} + +impl ConnectionMode { + fn is_single_threaded(self) -> bool { + matches!(self, ConnectionMode::SingleThreaded) + } +} diff --git a/quickfix/tests/test_send_receive.rs b/quickfix/tests/test_send_receive.rs index 425117a..018e0d0 100644 --- a/quickfix/tests/test_send_receive.rs +++ b/quickfix/tests/test_send_receive.rs @@ -37,12 +37,14 @@ fn test_full_fix_application() -> Result<(), QuickFixError> { &app_sender, &message_store_factory_sender, &log_factory, + ConnectionMode::default(), )?; let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, &log_factory, + ConnectionMode::default(), )?; // Check session have been configured @@ -151,13 +153,7 @@ fn test_full_fix_application() -> Result<(), QuickFixError> { assert!(!socket_receiver.is_logged_on().unwrap()); // Check counter - assert_eq!( - sender.admin_msg_count(), - MsgCounter { - sent: 3, /* ??? */ - recv: 2 - } - ); + assert_eq!(sender.admin_msg_count(), MsgCounter { sent: 2, recv: 2 }); assert_eq!(receiver.admin_msg_count(), MsgCounter { recv: 2, sent: 2 }); Ok(()) diff --git a/quickfix/tests/test_session.rs b/quickfix/tests/test_session.rs index f467ab7..913422a 100644 --- a/quickfix/tests/test_session.rs +++ b/quickfix/tests/test_session.rs @@ -33,12 +33,14 @@ fn test_session_login_logout() -> Result<(), QuickFixError> { &app_sender, &message_store_factory_sender, &log_factory, + ConnectionMode::default(), )?; let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, &log_factory, + ConnectionMode::default(), )?; // Check session have been configured diff --git a/quickfix/tests/test_socket.rs b/quickfix/tests/test_socket.rs index ef86b4a..87e9cb5 100644 --- a/quickfix/tests/test_socket.rs +++ b/quickfix/tests/test_socket.rs @@ -35,7 +35,14 @@ fn test_handler() { let logger = LogFactory::try_new(&StdLogger::Stdout).unwrap(); check_connection_handler( - Acceptor::try_new(&settings, &app, &message_store, &logger).unwrap(), + Acceptor::try_new( + &settings, + &app, + &message_store, + &logger, + ConnectionMode::default(), + ) + .unwrap(), ); } @@ -46,7 +53,14 @@ fn test_handler() { let logger = LogFactory::try_new(&StdLogger::Stdout).unwrap(); check_connection_handler( - Initiator::try_new(&settings, &app, &message_store, &logger).unwrap(), + Initiator::try_new( + &settings, + &app, + &message_store, + &logger, + ConnectionMode::default(), + ) + .unwrap(), ); } } diff --git a/quickfix/tests/utils/checker.rs b/quickfix/tests/utils/checker.rs index 3eb04e0..ceabf1c 100644 --- a/quickfix/tests/utils/checker.rs +++ b/quickfix/tests/utils/checker.rs @@ -40,12 +40,14 @@ pub fn run( &app_sender, &message_store_factory_sender, &log_factory, + ConnectionMode::default(), )?; let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, &log_factory, + ConnectionMode::default(), )?; // Start the app From 80f8ac17ab875ab1069e4930dc797ec1f6d175ca Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sat, 28 Jun 2025 15:27:27 +0200 Subject: [PATCH 5/8] =?UTF-8?q?style:=20=F0=9F=92=84=20rust-fmt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quickfix/examples/demo_config.rs | 6 +++--- quickfix/examples/fix_repl/main.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/quickfix/examples/demo_config.rs b/quickfix/examples/demo_config.rs index 3148460..2b8c156 100644 --- a/quickfix/examples/demo_config.rs +++ b/quickfix/examples/demo_config.rs @@ -1,9 +1,9 @@ use std::io::{stdin, Read}; use quickfix::{ - dictionary_item::*, Acceptor, Application, ApplicationCallback, ConnectionHandler, Dictionary, - LogFactory, MemoryMessageStoreFactory, QuickFixError, ConnectionMode, SessionId, SessionSettings, - StdLogger, + dictionary_item::*, Acceptor, Application, ApplicationCallback, ConnectionHandler, + ConnectionMode, Dictionary, LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, + SessionSettings, StdLogger, }; #[derive(Default)] diff --git a/quickfix/examples/fix_repl/main.rs b/quickfix/examples/fix_repl/main.rs index 378739d..7cc40b4 100644 --- a/quickfix/examples/fix_repl/main.rs +++ b/quickfix/examples/fix_repl/main.rs @@ -1,8 +1,8 @@ use std::{env, process::exit}; use quickfix::{ - Acceptor, Application, ConnectionHandler, FileMessageStoreFactory, Initiator, LogFactory, - QuickFixError, ConnectionMode, SessionSettings, StdLogger, + Acceptor, Application, ConnectionHandler, ConnectionMode, FileMessageStoreFactory, Initiator, + LogFactory, QuickFixError, SessionSettings, StdLogger, }; use crate::{command_exec::FixShell, fix_app::MyApplication}; From 732666a44baffdf84ea5deaecad36e9e2eb4681f Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sun, 29 Jun 2025 16:33:29 +0200 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Rename=20enum=20?= =?UTF-8?q?ConnectionMode=20to=20FixSocketServerKind?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++-- examples/coinbase-example/examples/cb-order-sender.rs | 2 +- examples/executor/src/main.rs | 2 +- examples/single-order-sender/src/main.rs | 2 +- quickfix/README.md | 4 +++- quickfix/examples/demo_config.rs | 4 ++-- quickfix/examples/fix_getting_started.rs | 2 +- quickfix/examples/fix_repl/main.rs | 6 +++--- quickfix/src/acceptor.rs | 4 ++-- quickfix/src/initiator.rs | 7 ++++--- quickfix/src/lib.rs | 10 +++++----- quickfix/tests/test_send_receive.rs | 4 ++-- quickfix/tests/test_session.rs | 4 ++-- quickfix/tests/test_socket.rs | 4 ++-- quickfix/tests/utils/checker.rs | 4 ++-- 15 files changed, 33 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 594cd95..6373e39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ To create socket acceptor and initiator you must change below code: + &app, + &store_factory, + &log_factory, -+ ConnectionMode::SingleThreaded, ++ FixSocketServerKind::SingleThreaded, + )?; - let mut initiator = SocketInitiator::try_new(&settings, &app, &message_store, &logger)?; @@ -24,6 +24,6 @@ To create socket acceptor and initiator you must change below code: + &app, + &message_store, + &logger, -+ ConnectionMode::default(), ++ FixSocketServerKind::default(), + )?; ``` diff --git a/examples/coinbase-example/examples/cb-order-sender.rs b/examples/coinbase-example/examples/cb-order-sender.rs index 78fc55b..f948d5b 100644 --- a/examples/coinbase-example/examples/cb-order-sender.rs +++ b/examples/coinbase-example/examples/cb-order-sender.rs @@ -165,7 +165,7 @@ fn main() -> anyhow::Result<()> { &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?; // Start the engine. diff --git a/examples/executor/src/main.rs b/examples/executor/src/main.rs index e096e65..9c364d5 100644 --- a/examples/executor/src/main.rs +++ b/examples/executor/src/main.rs @@ -153,7 +153,7 @@ fn main() -> Result<(), QuickFixError> { &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?; acceptor.start()?; diff --git a/examples/single-order-sender/src/main.rs b/examples/single-order-sender/src/main.rs index 41bf493..9182135 100644 --- a/examples/single-order-sender/src/main.rs +++ b/examples/single-order-sender/src/main.rs @@ -85,7 +85,7 @@ fn main() -> anyhow::Result<()> { &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?; // Start the engine. diff --git a/quickfix/README.md b/quickfix/README.md index 7abc18a..d151735 100644 --- a/quickfix/README.md +++ b/quickfix/README.md @@ -92,7 +92,7 @@ fn main() -> Result<(), QuickFixError> { &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?; acceptor.start()?; @@ -122,6 +122,8 @@ If some of your needs are missing: PR / feedbacks are welcomed ๐Ÿ˜! Crate is still in the [reviewing process](https://github.com/quickfix/quickfix/issues/533). Feel free to participate and share your point of view on this github issue. +For list of breaking changes between version, please check [CHANGELOG](./CHANGELOG.md). + **NOTE**: I am personally not using for now the generated message struct. I know they works fine thanks to unit tests and can be used in production code. Feedback on this part are welcomed ! diff --git a/quickfix/examples/demo_config.rs b/quickfix/examples/demo_config.rs index 2b8c156..6aacd5a 100644 --- a/quickfix/examples/demo_config.rs +++ b/quickfix/examples/demo_config.rs @@ -2,7 +2,7 @@ use std::io::{stdin, Read}; use quickfix::{ dictionary_item::*, Acceptor, Application, ApplicationCallback, ConnectionHandler, - ConnectionMode, Dictionary, LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, + FixSocketServerKind, Dictionary, LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, SessionSettings, StdLogger, }; @@ -58,7 +58,7 @@ fn main() -> Result<(), QuickFixError> { &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?; println!(">> connection handler START"); diff --git a/quickfix/examples/fix_getting_started.rs b/quickfix/examples/fix_getting_started.rs index 57de81f..863195e 100644 --- a/quickfix/examples/fix_getting_started.rs +++ b/quickfix/examples/fix_getting_started.rs @@ -36,7 +36,7 @@ fn main() -> Result<(), QuickFixError> { &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?; println!(">> connection handler START"); diff --git a/quickfix/examples/fix_repl/main.rs b/quickfix/examples/fix_repl/main.rs index 7cc40b4..3d051b4 100644 --- a/quickfix/examples/fix_repl/main.rs +++ b/quickfix/examples/fix_repl/main.rs @@ -1,7 +1,7 @@ use std::{env, process::exit}; use quickfix::{ - Acceptor, Application, ConnectionHandler, ConnectionMode, FileMessageStoreFactory, Initiator, + Acceptor, Application, ConnectionHandler, FixSocketServerKind, FileMessageStoreFactory, Initiator, LogFactory, QuickFixError, SessionSettings, StdLogger, }; @@ -34,14 +34,14 @@ fn main() -> Result<(), QuickFixError> { &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?), "acceptor" => server_loop(Acceptor::try_new( &settings, &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?), _ => { eprintln!("Invalid connection mode"); diff --git a/quickfix/src/acceptor.rs b/quickfix/src/acceptor.rs index 4a0691e..a7af2cb 100644 --- a/quickfix/src/acceptor.rs +++ b/quickfix/src/acceptor.rs @@ -8,7 +8,7 @@ use quickfix_ffi::{ use crate::{ utils::{ffi_code_to_bool, ffi_code_to_result}, - Application, ApplicationCallback, ConnectionHandler, ConnectionMode, FfiMessageStoreFactory, + Application, ApplicationCallback, ConnectionHandler, FixSocketServerKind, FfiMessageStoreFactory, LogCallback, LogFactory, QuickFixError, Session, SessionContainer, SessionId, SessionSettings, }; @@ -38,7 +38,7 @@ where application: &'a Application, store_factory: &'a S, log_factory: &'a LogFactory, - server_mode: ConnectionMode, + server_mode: FixSocketServerKind, ) -> Result { match unsafe { FixAcceptor_new( diff --git a/quickfix/src/initiator.rs b/quickfix/src/initiator.rs index 5b56d3e..57f300f 100644 --- a/quickfix/src/initiator.rs +++ b/quickfix/src/initiator.rs @@ -8,8 +8,9 @@ use quickfix_ffi::{ use crate::{ utils::{ffi_code_to_bool, ffi_code_to_result}, - Application, ApplicationCallback, ConnectionHandler, ConnectionMode, FfiMessageStoreFactory, - LogCallback, LogFactory, QuickFixError, Session, SessionContainer, SessionId, SessionSettings, + Application, ApplicationCallback, ConnectionHandler, FfiMessageStoreFactory, + FixSocketServerKind, LogCallback, LogFactory, QuickFixError, Session, SessionContainer, + SessionId, SessionSettings, }; /// Socket implementation of establishing connections handler. @@ -38,7 +39,7 @@ where application: &'a Application, store_factory: &'a S, log_factory: &'a LogFactory, - server_mode: ConnectionMode, + server_mode: FixSocketServerKind, ) -> Result { match unsafe { FixInitiator_new( diff --git a/quickfix/src/lib.rs b/quickfix/src/lib.rs index b29e1ac..d92540b 100644 --- a/quickfix/src/lib.rs +++ b/quickfix/src/lib.rs @@ -86,7 +86,7 @@ let mut acceptor = Acceptor::try_new( &app, &store_factory, &log_factory, - ConnectionMode::SingleThreaded, + FixSocketServerKind::SingleThreaded, )?; // Start session. @@ -275,12 +275,12 @@ pub trait ForeignPropertySetter { fn ffi_set(&mut self, key: CString, value: T) -> Result<(), QuickFixError>; } -/// Underlying interface of FIX server to use. +/// Underlying interface of FIX socket server to use. /// /// This enum may add in future version SSL version of server mode. #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)] #[non_exhaustive] -pub enum ConnectionMode { +pub enum FixSocketServerKind { /// Single threaded version of Acceptor and Initiator. #[default] SingleThreaded, @@ -289,8 +289,8 @@ pub enum ConnectionMode { MultiThreaded, } -impl ConnectionMode { +impl FixSocketServerKind { fn is_single_threaded(self) -> bool { - matches!(self, ConnectionMode::SingleThreaded) + matches!(self, FixSocketServerKind::SingleThreaded) } } diff --git a/quickfix/tests/test_send_receive.rs b/quickfix/tests/test_send_receive.rs index 018e0d0..2c6a6ca 100644 --- a/quickfix/tests/test_send_receive.rs +++ b/quickfix/tests/test_send_receive.rs @@ -37,14 +37,14 @@ fn test_full_fix_application() -> Result<(), QuickFixError> { &app_sender, &message_store_factory_sender, &log_factory, - ConnectionMode::default(), + FixSocketServerKind::default(), )?; let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, &log_factory, - ConnectionMode::default(), + FixSocketServerKind::default(), )?; // Check session have been configured diff --git a/quickfix/tests/test_session.rs b/quickfix/tests/test_session.rs index 913422a..dc42117 100644 --- a/quickfix/tests/test_session.rs +++ b/quickfix/tests/test_session.rs @@ -33,14 +33,14 @@ fn test_session_login_logout() -> Result<(), QuickFixError> { &app_sender, &message_store_factory_sender, &log_factory, - ConnectionMode::default(), + FixSocketServerKind::default(), )?; let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, &log_factory, - ConnectionMode::default(), + FixSocketServerKind::default(), )?; // Check session have been configured diff --git a/quickfix/tests/test_socket.rs b/quickfix/tests/test_socket.rs index 87e9cb5..54aa927 100644 --- a/quickfix/tests/test_socket.rs +++ b/quickfix/tests/test_socket.rs @@ -40,7 +40,7 @@ fn test_handler() { &app, &message_store, &logger, - ConnectionMode::default(), + FixSocketServerKind::default(), ) .unwrap(), ); @@ -58,7 +58,7 @@ fn test_handler() { &app, &message_store, &logger, - ConnectionMode::default(), + FixSocketServerKind::default(), ) .unwrap(), ); diff --git a/quickfix/tests/utils/checker.rs b/quickfix/tests/utils/checker.rs index ceabf1c..d0abac1 100644 --- a/quickfix/tests/utils/checker.rs +++ b/quickfix/tests/utils/checker.rs @@ -40,14 +40,14 @@ pub fn run( &app_sender, &message_store_factory_sender, &log_factory, - ConnectionMode::default(), + FixSocketServerKind::default(), )?; let mut socket_receiver = Acceptor::try_new( &settings_receiver, &app_receiver, &message_store_factory_receiver, &log_factory, - ConnectionMode::default(), + FixSocketServerKind::default(), )?; // Start the app From cb6d476a3b3b36ae55a5db694bb63f0ab59a14d9 Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sun, 29 Jun 2025 16:36:05 +0200 Subject: [PATCH 7/8] =?UTF-8?q?style:=20=F0=9F=92=84=20Remove=20some=20lif?= =?UTF-8?q?etime=20clippy=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quickfix-msg-gen/src/lib.rs | 2 +- quickfix/src/log_factory.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/quickfix-msg-gen/src/lib.rs b/quickfix-msg-gen/src/lib.rs index 0efd630..a414c37 100644 --- a/quickfix-msg-gen/src/lib.rs +++ b/quickfix-msg-gen/src/lib.rs @@ -98,7 +98,7 @@ fn generate_root(output: &mut String, begin_string: &str) { current_index: usize, }} - impl<'a, T, I> Iterator for GroupIterator<'a, T, I> {{ + impl Iterator for GroupIterator<'_, T, I> {{ type Item = I; fn next(&mut self) -> Option {{ diff --git a/quickfix/src/log_factory.rs b/quickfix/src/log_factory.rs index 9a01d2b..31c83c8 100644 --- a/quickfix/src/log_factory.rs +++ b/quickfix/src/log_factory.rs @@ -96,7 +96,7 @@ where } } -impl<'a, C: LogCallback> fmt::Debug for LogFactory<'a, C> { +impl fmt::Debug for LogFactory<'_, C> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("LogFactory").finish() } From cba08af7e9ea81482d260c7a5f7a1d57e11cb8c4 Mon Sep 17 00:00:00 2001 From: Arthur LE MOIGNE Date: Sun, 29 Jun 2025 16:45:50 +0200 Subject: [PATCH 8/8] =?UTF-8?q?style:=20=F0=9F=92=84=20rust=20fmt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quickfix/examples/demo_config.rs | 4 ++-- quickfix/examples/fix_repl/main.rs | 4 ++-- quickfix/src/acceptor.rs | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/quickfix/examples/demo_config.rs b/quickfix/examples/demo_config.rs index 6aacd5a..edef3b9 100644 --- a/quickfix/examples/demo_config.rs +++ b/quickfix/examples/demo_config.rs @@ -1,8 +1,8 @@ use std::io::{stdin, Read}; use quickfix::{ - dictionary_item::*, Acceptor, Application, ApplicationCallback, ConnectionHandler, - FixSocketServerKind, Dictionary, LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, + dictionary_item::*, Acceptor, Application, ApplicationCallback, ConnectionHandler, Dictionary, + FixSocketServerKind, LogFactory, MemoryMessageStoreFactory, QuickFixError, SessionId, SessionSettings, StdLogger, }; diff --git a/quickfix/examples/fix_repl/main.rs b/quickfix/examples/fix_repl/main.rs index 3d051b4..2bf8201 100644 --- a/quickfix/examples/fix_repl/main.rs +++ b/quickfix/examples/fix_repl/main.rs @@ -1,8 +1,8 @@ use std::{env, process::exit}; use quickfix::{ - Acceptor, Application, ConnectionHandler, FixSocketServerKind, FileMessageStoreFactory, Initiator, - LogFactory, QuickFixError, SessionSettings, StdLogger, + Acceptor, Application, ConnectionHandler, FileMessageStoreFactory, FixSocketServerKind, + Initiator, LogFactory, QuickFixError, SessionSettings, StdLogger, }; use crate::{command_exec::FixShell, fix_app::MyApplication}; diff --git a/quickfix/src/acceptor.rs b/quickfix/src/acceptor.rs index a7af2cb..5d1930e 100644 --- a/quickfix/src/acceptor.rs +++ b/quickfix/src/acceptor.rs @@ -8,8 +8,9 @@ use quickfix_ffi::{ use crate::{ utils::{ffi_code_to_bool, ffi_code_to_result}, - Application, ApplicationCallback, ConnectionHandler, FixSocketServerKind, FfiMessageStoreFactory, - LogCallback, LogFactory, QuickFixError, Session, SessionContainer, SessionId, SessionSettings, + Application, ApplicationCallback, ConnectionHandler, FfiMessageStoreFactory, + FixSocketServerKind, LogCallback, LogFactory, QuickFixError, Session, SessionContainer, + SessionId, SessionSettings, }; /// Socket implementation of incoming connections handler.