Search code examples
javamultithreadingthread-safetyfix-protocolquickfixj

Is Session.sendToTarget() thread-safe?


I am trying to integrate QFJ into a single-threaded application. At first I was trying to utilize QFJ with my own TCP layer, but I haven't been able to work that out. Now I am just trying to integrate an initiator. Based on my research into QFJ, I would think the overall design should be as follows:

enter image description here

The application will no longer be single-threaded, since the QFJ initiator will create threads, so some synchronization is needed. Here I am using an SocketInitiator (I only handle a single FIX session), but I would expect a similar setup should I go for the threaded version later on.

There are 2 aspects to the integration of the initiator into my application:

  1. Receiving side (fromApp callback): I believe this is straightforward, I simply push messages to a thread-safe queue consumed by my MainProcessThread.
  2. Sending side: I'm struggling to find documentation on this front. How should I handle synchronization? Is it safe to call Session.sendToTarget() from the MainProcessThread? Or is there some synchronization I need to put in place?

Solution

  • As Michael already said, it is perfectly safe to call Session.sendToTarget() from multiple threads, even concurrently. But as far as I see it you only utilize one thread anyway (MainProcessThread).

    The relevant part of the Session class is in method sendRaw():

        private boolean sendRaw(Message message, int num) {
            // sequence number must be locked until application
            // callback returns since it may be effectively rolled
            // back if the callback fails.
            state.lockSenderMsgSeqNum();
            try {
            .... some logic here
            } finally {
                state.unlockSenderMsgSeqNum();
            }        
    

    Other points:

    Here I am using an SocketInitiator (I only handle a single FIX session), but I would expect a similar setup should I go for the threaded version later on.

    Will you always use only one Session? If yes, then there is no use in utilizing the ThreadedSocketInitiator since all it does is creating a thread per Session.

    The application will no longer be single threaded, since the QFJ initiator will create threads

    As already stated here Use own TCP layer implementation with QuickFIX/J you could try passing an ExecutorFactory. But this might not be applicable to your specific use case.