Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quickfixj acceptor responds to Logon MsgSeqNum(34)=1 with Logon of MsgSeqNum= 2 instead of 1 at times #902

Open
singhnav-a opened this issue Oct 30, 2024 · 3 comments
Labels

Comments

@singhnav-a
Copy link

Describe the bug
Quickfixj acceptor responds to Logon MsgSeqNum(34)=1 with Logon of MsgSeqNum= 2 instead of 1 at times

This happens intermittently in our app, particularly in higher connect/disconnect cycles, its rare but still happens consistently over time.

To Reproduce
Normal Logon by a fix client, repeated connect and disconnect to reproduce the occurrence.

Expected behavior
Logon with 34=1, 141=Y should be responded with Logon of 34=1

system information:

  • OS: [Issue seen in both Redhat Linux, CentOS Linux]
  • Java version [JDK8]
  • QFJ Version [ 2.3.1]

Additional context

QFJ Events in case of occurrence of the issue

Accepting session FIX.4.4:DUMMY->BADCOMPID21 from /123.123.123.123
Acceptor heartbeat set to 30 seconds
Refreshing message/state store on Logon
Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
Received logon
Responding to Logon request

<THIS WAS TRYING TO BE SENT BUT WAS DROPPED, SEE some debugging analysis done - 8=FIX.4.4|9=65|35=0|34=1|49=DUMMY|52=20241029-14:16:44.726|56=BADCOMPID21|10=042|>

Logon sent to FIX Client
8=FIX.4.4|9=83|35=A|34=2|49=DUMMY|52=20241029-14:16:44.736|56=BADCOMPID21|98=0|108=30|141=Y|10=131|

Reason/Debugging analysis

Session.java (Lines 2620 to 2626), from Quickfixj 2.3.1 Source Code downlaoded.

            messageString = message.toString();
            persist(message.getHeader(), messageString, num);
            if (MsgType.LOGON.equals(msgType) || MsgType.LOGOUT.equals(msgType)
                    || MsgType.RESEND_REQUEST.equals(msgType)
                    || MsgType.SEQUENCE_RESET.equals(msgType) || isLoggedOn()) {
                result = send(messageString);

If there is a HB generated while the logon is being processed, it calls the persist method for Heartbeat but does not go in the if conditon as its not isLoggedOn() yet. Thus it increases the senderMessageSequence number in persist, but there is no message for 34=1 sent out.
When Logon 35=A is sent, the senderMessageSequence is now 2

What could be causing this Heartbeat to be generated as part of logon being done? Also is there any setting that could alleviate this.

QFJ Settings used for Acceptor currently

(DEFAULT): key=FileStorePath, value=/appl/APP/app/app/qfj/server
(DEFAULT): key=FileLogPath, value=/appl/APP/app/app/qfj/log
(DEFAULT): key=ConnectionType, value=acceptor
(SESSION): key=StartDay, value=Saturday
(SESSION): key=StartTime, value=14:00:00
(SESSION): key=EndDay, value=Saturday
(SESSION): key=EndTime, value=14:00:00
(SESSION): key=NonStopSession, value=Y
(SESSION): key=SenderCompID, value=*
(SESSION): key=SenderSubID, value=*
(SESSION): key=SenderLocationID, value=*
(SESSION): key=TargetCompID, value=*
(SESSION): key=TargetSubID, value=*
(SESSION): key=TargetLocationID, value=*
(DEFAULT): key=AcceptorTemplate, value=Y
(DEFAULT): key=UseDataDictionary, value=Y
(DEFAULT): key=AppDataDictionary, value=fix_dictionary/COMPANYAPP_FIX44.xml
(DEFAULT): key=TransportDataDictionary, value=fix_dictionary/****
(DEFAULT): key=DefaultApplVerID, value=${qfj.serverAdapter.properties.DEFAULT_APP_VER_ID}
(DEFAULT): key=DataDictionary, value=fix_dictionary/COMPANYAPP_FIX44.xml
(SESSION): key=BeginString, value=FIX.4.4
(DEFAULT): key=SocketAcceptPort, value=9880
(SESSION): key=ResetOnLogon, value=N
(SESSION): key=ResetOnLogout, value=N
(SESSION): key=ResetOnDisconnect, value=N
(SESSION): key=ResetOnError, value=N
(SESSION): key=DisconnectOnError, value=N
(DEFAULT): key=FileLogHeartbeats, value=Y
(DEFAULT): key=ValidateFieldsOutOfOrder, value=Y
(DEFAULT): key=ValidateUserDefinedFields, value=Y
(DEFAULT): key=ValidateFieldsHaveValues, value=Y
(DEFAULT): key=AllowUnknownMsgFields, value=Y
(DEFAULT): key=CheckCompID, value=Y
(DEFAULT): key=CheckLatency, value=Y
(DEFAULT): key=MaxLatency, value=120
(SESSION): key=RefreshOnLogon, value=Y
(DEFAULT): key=PersistMessages, value=N
(SESSION): key=SocketUseSSL, value=N
(SESSION): key=TimeZone, value=GMT
(SESSION): key=AllowedRemoteAddresses, value=

@singhnav-a singhnav-a added the bug label Oct 30, 2024
@chrjohn
Copy link
Member

chrjohn commented Nov 10, 2024

I don't understand fully what's going on here.

If there is a HB generated while the logon is being processed,

Why should a heartbeat be generated if there is no active session? Are you generating heartbeats in your user code?

I think this needs a unit test to reproduce since I cannot see where this heartbeat could come from.

@chrjohn
Copy link
Member

chrjohn commented Nov 12, 2024

Regarding the config: do you need RefreshOnLogon=Y? This is only helpful in acceptor failover scenarios.
Are all of your connections requesting to reset the sequence number on Logon? If yes, you probably won't need RefreshOnLogon, especially because you are not persisting messages (PersistMessages=N)

@singhnav-a
Copy link
Author

We were previously with RefreshOnLogon=N, but still had the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants