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

Quickfix/Go resets sequence when using StartTime/EndTime #607

Open
florian-besser opened this issue Dec 28, 2023 · 5 comments
Open

Quickfix/Go resets sequence when using StartTime/EndTime #607

florian-besser opened this issue Dec 28, 2023 · 5 comments

Comments

@florian-besser
Copy link

I'm raising this issue here as I don't have access to https://groups.google.com/g/quickfixgo

We configure our QuickFix/Go sessions like so:

BeginString=FIX.4.4
# Removed several irrelevant items
StartTime=07:03:00
EndTime=07:00:00

This (to me, as per docs) implies ResetOnLogon=N, ResetOnLogout=N, ResetOnDisconnect=N meaning I expect no session resets to happen. This is indeed true for e.g. us restarting Quickfix/Go, but there is one exception.

Whenever we hit 7AM UTC we see Quickfix/Go disconnect (correctly), followed by reconnection attempts at 7:03AM (also correct), except these reconnection attempts now use the wrong sequence number.

Expected behavior:
Reconnection attempts and future messages should use the next sequence number from before the disconnect.

Example: Before the disconnect our last outgoing message has sequence id 123. The next message (i.e. the logon at 7:03) should use sequence id 124

Observed behavior:
Quickfix/Go resets the sequence, the next sequence id is always 1.

This leads to our counterparty complaining that the sequence number is wrong.

I currently believe this is due to the following code:

func (sm *stateMachine) CheckSessionTime(session *session, now time.Time) {
	if !session.SessionTime.IsInRange(now) {
		if sm.IsSessionTime() {
			session.log.OnEvent("Not in session")
		}

		sm.State.ShutdownNow(session)
		sm.setState(session, notSessionTime{})

		if sm.notifyOnInSessionTime == nil {
			sm.notifyOnInSessionTime = make(chan interface{})
		}
		return
	}

	if !sm.IsSessionTime() {
		session.log.OnEvent("In session")
		sm.notifyInSessionTime()
		sm.setState(session, latentState{})
	}

	if !session.SessionTime.IsInSameRange(session.store.CreationTime(), now) {
		session.log.OnEvent("Session reset")
		sm.State.ShutdownNow(session)
		if err := session.dropAndReset(); err != nil {
			session.logError(err)
		}
		sm.setState(session, latentState{})
	}
}

Specifically the last if statement. From the code I don't see a way for us to configure this behavior and the library will always reset the sequence.

@filinvadim
Copy link

AFAIK this is normal behavior in absence of StartDay and EndDay. Just set StartDay and EndDay in config

@florian-besser
Copy link
Author

Hi @filinvadim , see the top of my post: We are using both StartTime and EndTime in our config, and yet the resets still happen.

@filinvadim
Copy link

Please also add StartDay=Monday and EndDay=Friday for example

@florian-besser
Copy link
Author

I currently don't have access to this project anymore; will let you know if we go back to this library and whether that fixes the issue.
Looking at the last if from my original post I'm not convinced that adding start- and end-day will change the behavior of:

if !session.SessionTime.IsInSameRange(session.store.CreationTime(), now) {
		session.log.OnEvent("Session reset")
		sm.State.ShutdownNow(session)
		if err := session.dropAndReset(); err != nil {
			session.logError(err)
		}
		sm.setState(session, latentState{})
	}

@TatuMon
Copy link

TatuMon commented Aug 19, 2024

Please also add StartDay=Monday and EndDay=Friday for example

If you set this, StartTime and EndTime will be ignored. For day long sessions, you should use Weekdays, which is not documented.

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

No branches or pull requests

3 participants