How to use SocketOpPriority parameter
- 1 Overview
- 2 Values
- 2.1 EVEN
- 2.1.1 Business scenario
- 2.2 AGGRESSIVE
- 2.2.1.1 AGGRESSIVE_SEND
- 2.2.1.2 AGGRESSIVE_RECEIVE
- 2.2.1.3 AGGRESSIVE_SEND_AND_RECEIVE
- 2.2.1.4 AGGRESSIVE_SEND_ASYNC
- 2.2.1.5 AGGRESSIVE_RECEIVE_AND_DIRECT_SEND
- 2.2.2 Business scenario
- 2.3 DIRECT_SEND
- 2.3.1 Business scenario
- 2.1 EVEN
Overview
The use of SocketOpPriority session parameter is based on a variety of ways of doing network I/O (input/output):
synchronous non-blocking I/O with readiness notifications
synchronous non-blocking I/O with busy polling
synchronous blocking I/O
As well as various ways to perform an I/O operation:
a thread from a pool
a dedicated per session thread
the current thread (the one calling "Session::put")
Dedicated threads allow lower response time while using a pool provides higher throughput. So the optimal combination of "how to do I/O" and "what performs I/O (current thread/thread pool/dedicated thread)" choices depends on the application.
FIX Antenna allows to pick such a combination using non-blocking I/O on a per session basis and SocketOpPriority is the corresponding session parameter.
Valid values of SocketOpPriority parameter:
EVEN (default) - share worker thread among all sessions in the Engine;
AGGRESSIVE_SEND - uses dedicated per session thread to send outgoing messages;
AGGRESSIVE_RECEIVE - uses dedicated per session thread to receive incoming messages;
AGGRESSIVE_SEND_AND_RECEIVE - uses dedicated per session threads to send and receive messages;
AGGRESSIVE_SEND_ASYNC -uses dedicated per session thread to send all outgoing messages to the queue without trying to send them to the socket first.
DIRECT_SEND - uses the current thread for sending, if this would block, perform as "EVEN".
AGGRESSIVE_RECEIVE_AND_DIRECT_SEND - uses a dedicated thread per session for receiving messages and the current thread for sending. If sending would block, queue the message for a worker thread, combining AGGRESSIVE_RECEIVE with DIRECT_SEND.
Values
EVEN
Use thread pool for performing I/O for send and receive operation. The operations are distributed between the worker threads by a dispatcher thread which polls sockets and notifies worker threads when some socket is ready. In this mode FIX Antenna batches incoming/outgoing messages, i.e. several FIX messages can be processed in one send() system call. This is the default value.
Business scenario
It's recommended to use EVEN when there are many concurrent sessions ("many" means much more than the count of cores used), i.e. application demands a high throughput rather than a low response time. Allocating dedicated per session threads is not an option in such cases, so using a pool makes sense.
AGGRESSIVE
AGGRESSIVE_SEND
Tries to send the message from the current thread, if that fails (would block) delegates sending to a dedicated per session thread. Uses a combination of busy polling and readiness notifications. Intended for applications that need low response time (e.g. to send an order as soon as possible).
AGGRESSIVE_RECEIVE
Use a dedicated per session thread to handle receiving. It uses I/O with busy polling and switches to readiness notifications if no data has been received during a certain configurable time interval. Intended for applications that need low response time (e.g. to receive and react as soon as possible).
AGGRESSIVE_SEND_AND_RECEIVE
Use dedicated per session threads to send and receive messages;
AGGRESSIVE_SEND_ASYNC
FIX Engine uses a dedicated thread for a session that sends all outgoing messages to the queue without trying to send them to the socket first. This mode aims to reduce the time spent on the execution of the session:put method and reduce the impact of slow consumers on the application by parallelizing the socket operations by default.
AGGRESSIVE_RECEIVE_AND_DIRECT_SEND
FIX Engine leverages a dedicated thread for receiving incoming messages, constantly polling the socket to achieve minimal latency (similar to AGGRESSIVE_RECEIVE). For sending outgoing messages, the engine uses the current thread, and if the operation would block, the message is queued and handled by a worker thread, similar to DIRECT_SEND. This mode is designed to minimize message processing latency on the receiving side while avoiding blocking on the sending side, ensuring a balanced approach between low latency and stable throughput.
Business scenario
Aggressive strategies of I/O are recommended to use when minimum latency is needed. But it can reduce throughput.
DIRECT_SEND
Try sending from the current thread, if this would block, does the same thing as "EVEN", i.e. queues the message and performs the operation in a worker thread when the corresponding socket becomes ready. The dispatcher thread handles readiness notifications and notifies workers whenever some socket has data to send/receive.
Business scenario
It's recommended to use DIRECT_SEND when there are many concurrent sessions ("many" means much more than the count of cores used), but on the other hand, an application needs a low(er) response time rather than a high throughput.