[QFJ-400] Make scheduledExecutorService non-static Created: 03/Feb/09  Updated: 16/Feb/09

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: None

Type: New Feature Priority: Default
Reporter: Mihai Sardarescu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hello all,

In order to start our FIX connector, we have a "start" call from our middleware (there could be more than one FIX connectors started at different times on the same JVM). On this call, a logger is paased to the connector and all the log of the FIX connector should be dumped to this logger. The log of the QuickfixJ session is easily routed. However, the log messages from Mina and of the QuickfixJ initiators are more difficult to route. We use InheritableThreadLocal to pass the logger to all threads started by our FIX connector.
We encountered a problem due to the fact that the QuickfixJ SessionConnector uses a static executor service for executing SessionTimerTask tasks. Could you please change this to non-static?
For more details, please refer to thread: http://sourceforge.net/mailarchive/message.php?msg_name=1714.65.220.39.123.1208198497.squirrel%40webmail3.hrnoc.net

We expect our application to go in production very soon (at most 2 month for now).

Thank you,
Mihai



 Comments   
Comment by Steve Bate [ 05/Feb/09 ]

Please remind me why you weren't able to write a SLF4J logger implementation that delegates to the thread local logger provided by the middleware product. All logging from all threads goes through SLF4J so it seems that this would route those messages through the logger you provided.

Comment by Mihai Sardarescu [ 05/Feb/09 ]

Hi Steve,

In order to start the FIX connector, I get a start call from the middleware. On this call, a logger is passed to my code and I shall redirect all log message written by quickfixj and mina to this logger.

To do that I have used an InheritableThreadLocal that holds the middleware logger object in order to pass it to all the created by quickfixj and mina code. The loggers created by the slf4j are just proxies to the current thread middleware logger. I can thus redirect the quickfixj and mina log messages to the middleware log.

This technique does not work in case a static executor (or a static thread) is used. For example:
1. The FIX connector is started using the middleware logger LOGGER1. When loading of the quickfixj library, the static executor is initialized and the the logger attached to it is LOGGER1. All log messages written on this logger will be directed to the LOGGER1.
2. A second instance of the FIXConnector is started in the same JVM using LOGGER2. As the static executor was already initialized, the log written by quickfixj on the static executor will be also routed to LOGGER1 (and not to LOGGER2 as expected). This leads to potentials problems - what if the first instance of the FIXConnector is stopped and the LOGGER1 is closed by the middleware (etc.)

Also, I do not see the benefit of using a static scheduledExecutorService for all the initiators (which also uses a daemon worker thread). Wouldn't it be better to use a non-static executor that can be shutdown once the initiator is stopped?

Regards,
Mihai

Comment by Steve Bate [ 06/Feb/09 ]

Hello Mihai,

As we discussed before, the purpose of the static (singleton) executor is to minimize the number of threads used by QFJ for it's own purposes. The executor is shared among all initiators and acceptors.

I'm still not understanding why using a custom SLF4J implementation didn't work for you. If the custom logger implementation delegates to the /current/ middleware logger then it doesn't matter when the logger client actually retrieved the SLF4J logger instance. Actually, you could do this even without SLF4J by just implementing the QFJ Log interface. Your custom Log would delegate to the middleware logger. The middleware callback would modify the logger delegate in your Log implementation and everything that uses the Log implementation would automatically be using the new middleware logger. If the middleware logger is thread-local then that could also be supported with this approach.

I'm probably missing something, but this is my understanding at this point based on the information I have. Feel free to clarify any key issues I'm not seeing. I want to understand why this can't be done in the way I describe before changing the QFJ internals to support it.

Thanks,

Steve

Comment by Mihai Sardarescu [ 16/Feb/09 ]

Hi Steve,

The middleware provides a different logger object for each FIX connector. As I have one and only one QFJ session per connector, I have implemented a special QFJ logger that routes the log of one QFJ session to the middleware logger - this works fine and the log messages are routed to the correct logger.
However, I am missing the mina log and the low-level log of QFJ (the log that is written using slf4j). In fact, each FIX connector has its own initiator - the initiator is started upon the initialization of the connector and is stopped once the connector is destroyed. The problem is that once an initiator writes log messages from the static thread, there is no way to find out the which connector this initiator corresponds in order to route the log message to the correct logger.

To make it more clear: let's suppose I have two concurrent FIX connectors running in the same JVM having:

  • LOGGER1, LOGGER2 - the middleware loggers
  • INITIATOR1, INITIATOR2 - the initiators.
    INITIATOR1 logs something using the slf4j logger: log.debug("MESSAGE1") from the static thread THREAD1.
    INITIATOR2 logs something using the slf4j logger: log.debug("MESSAGE2") from the static thread THREAD1.
    There is no way to decide if the MESSAGE1 should be routed to LOGGER1 or LOGGER2 (the same applies for MESSAGE2). If the thread was non-static, then using inheritable thread locals could allow me to route the message to the right logger.

Thanks,
Mihai

Generated at Fri May 03 23:35:46 UTC 2024 using JIRA 7.5.2#75007-sha1:9f5725bb824792b3230a5d8716f0c13e296a3cae.