|
From: Alex W. <ale...@gm...> - 2018-11-20 18:24:11
|
Hi Christoph & Colin,
The SessionSettings is only constructed once, and it is on the same thread
as the ThreadedSocketAcceptor creation (they were created as part of Spring
context initialisation).
Would changing the “sections” of the SessionSettings to ConcurrentMap help
? I probably should mention that only a few of the 50 incoming connections
got the exception. As far as I know, the SessionSettings given at the start
is complete. Only then it is passed on to the acceptor. Again, this only
happened after we upgraded to 2.1.0 from 1.5.3.
Colin, I’m not sure about what you said about creating the DynamicSession
provider once only. If I looked at the sample code (on the QuickfixJ github
repo), it is doing the same thing.
Thank you again, guys
Regards
Alex
On Wed, 21 Nov 2018 at 2:57 am, Christoph John <chr...@ma...>
wrote:
> Hmm, in this case the problem seems to be in SessionSettings itself:
>
> public Properties getSessionProperties(SessionID sessionID, boolean
> includeDefaults)
> throws ConfigError {
> final Properties p = sections.get(sessionID);
>
> //////// here the ConfigError is thrown because there is no
> section for the specified SessionID
>
> if (p == null) {
> throw new ConfigError("Session not found");
> }
> if (includeDefaults) {
> final Properties mergedProperties = new Properties();
> mergedProperties.putAll(sections.get(DEFAULT_SESSION_ID));
> mergedProperties.putAll(p);
> return mergedProperties;
> } else {
> return p;
> }
> }
>
> So the question is why the SessionSettings are incompletely loaded. I take
> it that you pass the same SessionSettings object to each acceptor? Is that
> SessionSettings object constructed/loaded in the same thread as the
> Acceptor? One simple explanation could be that the "sections" HashMap on
> the SessionSettings object is non-volatile and could not be visible to all
> threads that access it concurrently.
>
> At least that is how it looks like from here.
>
> Chris.
>
>
>
> On 20/11/2018 06:09, Alex Wibowo wrote:
>
> Here is another variant of the failure. But I think the underlying cause
> is the same:
>
> org.quickfixj.QFJException: quickfix.ConfigError: Session not found
>
> at
> quickfix.mina.acceptor.DynamicAcceptorSessionProvider.getSession(DynamicAcceptorSessionProvider.java:153)
> ~[quickfixj-core-2.1.0.jar:2.1.0]
>
> at
> quickfix.mina.acceptor.AcceptorIoHandler.findQFSession(AcceptorIoHandler.java:118)
> ~[quickfixj-core-2.1.0.jar:2.1.0]
>
> at
> quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:129)
> ~[quickfixj-core-2.1.0.jar:2.1.0]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:997)
> ~[mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java:437)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:256)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:121)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:634)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1242)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1231)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683)
> [mina-core-2.0.19.jar:?]
>
> at
> org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
> [mina-core-2.0.19.jar:?]
>
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> [?:1.8.0_172]
>
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> [?:1.8.0_172]
>
> at java.lang.Thread.run(Thread.java:748) [?:1.8.0_172]
>
> Caused by: quickfix.ConfigError: Session not found
>
> at
> quickfix.SessionSettings.getSessionProperties(SessionSettings.java:165)
> ~[quickfixj-core-2.1.0.jar:2.1.0]
>
> at
> quickfix.SessionSettings.getSessionProperties(SessionSettings.java:186)
> ~[quickfixj-core-2.1.0.jar:2.1.0]
>
> at
> quickfix.mina.acceptor.DynamicAcceptorSessionProvider.getSession(DynamicAcceptorSessionProvider.java:140)
> ~[quickfixj-core-2.1.0.jar:2.1.0]
>
> ... 24 more
>
>
> I'm really puzzled. As initially the configuration has non empty default
> properties & session properties. (our session properties use wildcards by
> the way, something like: FIX.4.2:OUR_SESSION_MARKET_DATA->*).
>
>
> I played around with the DynamicAcceptorSessionProvider, providing an
> override of the getSession() method:
>
>
>
> @Override
>
> public synchronized Session getSession(final
> SessionID clientConnection,
>
> final
> SessionConnector sessionConnector) {
>
> try {
>
> return super.getSession(clientConnection,
> sessionConnector);
>
> } catch (Exception e) {
>
> LOGGER.info("Default session: {}",
> settings.getDefaultProperties());
>
> throw e;
>
> }
>
> }
>
>
> basically, catch the exception on failure, and inspect the default
> properties. The logged message shows empty default properties.
>
> By the way, I've tried using SocketAcceptor, without any success either.
>
>
>
>
> Regards,
>
>
> Alex
>
> On Tue, Nov 20, 2018 at 11:32 AM Alex Wibowo <ale...@gm...> wrote:
>
>>
>> Hi Christoph,
>>
>> I should also mention that we are using ThreadedSocketAcceptor. So, it
>> looks roughly like:
>>
>> 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);
>> }
>> }
>>
>> The example and the test included in the project is using SocketAcceptor
>> (instead of ThreadedSocketAcceptor).
>>
>>
>> Regards,
>>
>> Alex
>>
>
>
> --
> Best regards,
>
>
> Alex Wibowo
>
>
> --
> Christoph John
> Software Engineering
> T +49 241 557...@ma...
>
> MACD GmbHOppenhoffallee 103
> 52066 Aachen, Germany <https://maps.google.com/?q=Oppenhoffallee+103%0D%0A52066+Aachen,+Germany&entry=gmail&source=g>www.macd.com
>
> Amtsgericht Aachen: HRB 8151
> Ust.-Id: DE 813021663
> Geschäftsführer: George Macdonald
>
> --
Best regards,
Alex Wibowo
|