|
From: Christoph J. <chr...@ma...> - 2018-11-21 12:01:26
|
Hi Alex,
unfortunately I am out of ideas at the moment but there are two components which I cannot use to
reproduce the error. The first is Spring, the other one is Zing VM (according to your stack traces).
Maybe you can also test to not inject the config by Spring but to construct and pass it manually. I
don't know which initialization guarantees Spring has nor how its internal thread model works. To me
this looks like a problem of visibility. So just for testing you could also add "volatile" to all
variables to see if the problem goes away. ;)
Sorry for not being more helpful but to further analyse the issue we need a reproducer e.g. unit test.
Chris.
On 20/11/2018 19:44, Alex Wibowo wrote:
>
> I probably should also mention how the session settings look like.
> Roughly, it is like below (configured in Spring xml):
>
> <bean id="quickfixConfiguration" class="com.foobar.quickfix.QuickfixjConfiguration">
> <property name="defaultSettings">
> <util:map>
> <!-- Custom Properties -->
> <entry key="ResourceName" value="dapi"/>
> <entry key="AsynchronousLogging" value="N"/>
> <entry key="AsynchronousLoggerMaxPoolSize" value="1"/>
> <entry key="AsynchronousLoggerQueueCapacity" value="100"/>
> <entry key="AsynchronousLoggerThreadNamePrefix" value="QuickfixAsynchronousFileLogger-"/>
> <!-- End of custom properties -->
>
> <entry key="TimeZone" value="UTC"/>
> <entry key="StartDay" value="Sunday"/>
> <entry key="StartTime" value="7:00:00"/>
> <entry key="EndDay" value="Friday"/>
> <entry key="EndTime" value="17:00:00"/>
> <entry key="NonStopSession" value="N"/>
> <entry key="ConnectionType" value="acceptor"/>
> <entry key="HeartBtInt" value="30"/>
> <entry key="UseDataDictionary" value="Y"/>
> <entry key="ThreadModel" value="ThreadPerSession"/>
> <entry key="UseJmx" value="Y"/>
> <entry key="FileStorePath" value="/home/wibowoa/var/lib/myApp"/>
> <entry key="FileLogPath" value="logs/fixlog"/>
> <entry key="FileIncludeTimeStampForMessages" value="Y"/>
> <entry key="FileIncludeMilliseconds" value="Y"/>
> <entry key="CheckLatency" value="Y"/>
> <entry key="BeginString" value="FIX.4.2"/>
> <entry key="AcceptorTemplate" value="Y"/>
> <entry key="TargetCompID" value="*"/>
> </util:map>
> </property>
> <property name="sessionSettings">
> <util:map>
> <entry key="FIX.4.2:FOOBAR_PRICING->*">
> <util:map>
> <entry key="PersistMessages" value="N"/>
> <entry key="SocketAcceptPort" value="7565"/>
> <entry key="DataDictionary" value="fix/FIX42-DAPI-MD-2.4.xml"/>
> <entry key="ResetOnLogon" value="Y"/>
> <entry key="MaxLatency" value="120"/>
> </util:map>
> </entry>
> <entry key="FIX.4.2:FOOBAR_TRADING->*">
> <util:map>
> <entry key="PersistMessages" value="Y"/>
> <entry key="SocketAcceptPort" value="7566"/>
> <entry key="DataDictionary" value="fix/FIX42-DAPI-TR-2.4.xml"/>
> <entry key="ResetOnLogon" value="N"/>
> <entry key="MaxLatency" value="1"/>
> </util:map>
> </entry>
> </util:map>
> </property>
> </bean>
>
> then this gets loaded into SessionSettings:
>
> public final class QuickfixjConfiguration {
> private Map<Object, Object> defaultSettings;
> private Map<SessionID, Map<Object, Object>> sessionSettings;
>
>
> public void setDefaultSettings(final Map<Object, Object> defaultSettings) {
> this.defaultSettings = defaultSettings;
> }
>
> public Map<SessionID, Map<Object, Object>> getSessionSettings() {
> return sessionSettings;
> }
>
> public void setSessionSettings(final Map<SessionID, Map<Object, Object>> sessionSettings) {
> this.sessionSettings = sessionSettings;
> }
>
> public SessionSettings createSessionSettings() throws ConfigError {
> final SessionSettings settings = new SessionSettings();
> if(defaultSettings != null && !defaultSettings.isEmpty()) {
> settings.set(new Dictionary(null, defaultSettings));
> }
> if(sessionSettings != null && !sessionSettings.isEmpty()) {
> for (Map.Entry<SessionID, Map<Object, Object>> sessionSetting :
> sessionSettings.entrySet()) {
> settings.set(sessionSetting.getKey(), new Dictionary("session",
> sessionSetting.getValue()));
> }
> }
> return settings;
> }
>
> }
> ...
> QuickfixJConfiguration foobar =... (injected as spring)
> SessionSettings settings = foobar.createSessionSettings();
>
> final MessageFactory messageFactory = new DefaultMessageFactory();
> final LogFactory logFactory = ...
> final MessageStoreFactory messageStoreFactory = new CustomFileStoreFactory(settings);
> final Acceptor acceptor = new ThreadedSocketAcceptor(application, messageStoreFactory, settings,
> logFactory, messageFactory);
>
> for (final SessionID sessionID : (Iterable<SessionID>)(settings::sectionIterator)) {
> final int acceptPort = (int) settings.getLong(sessionID,
> Acceptor.SETTING_SOCKET_ACCEPT_PORT);
> if (settings.getBool(sessionID, Acceptor.SETTING_ACCEPTOR_TEMPLATE)) {
> final AcceptorSessionProvider
> dynamicAcceptorSessionProvider = new DynamicAcceptorSessionProvider(settings, sessionID,
> application, messageStoreFactory, logFactory, messageFactory);
> acceptor.setSessionProvider(new InetSocketAddress(acceptPort), dynamicAcceptorSessionProvider);
> }
> }
> ---------------------
>
> All of this was done during Spring context initialisation.
>
> Regards,
>
> Alex
--
Christoph John
Software Engineering
T +49 241 557080-28
chr...@ma...
MACD GmbH
Oppenhoffallee 103
52066 Aachen, Germany
www.macd.com
Amtsgericht Aachen: HRB 8151
Ust.-Id: DE 813021663
Geschäftsführer: George Macdonald
|