Skip to content

Commit cec0770

Browse files
committed
update conditional and add UT for multiple days after reset time was set
1 parent f83e8a8 commit cec0770

File tree

5 files changed

+143
-13
lines changed

5 files changed

+143
-13
lines changed

internal/session_settings.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ type SessionSettings struct {
2121
TimeZone *time.Location
2222
ResetSeqTime time.Time
2323
EnableResetSeqTime bool
24-
LastCheckedResetSeqTime time.Time
2524

2625
// Required on logon for FIX.T.1 messages.
2726
DefaultApplVerID string

session.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ type session struct {
6262
transportDataDictionary *datadictionary.DataDictionary
6363
appDataDictionary *datadictionary.DataDictionary
6464

65-
timestampPrecision TimestampPrecision
65+
timestampPrecision TimestampPrecision
66+
lastCheckedResetSeqTime time.Time
6667
}
6768

6869
func (s *session) logError(err error) {

session_factory.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,6 @@ func (f sessionFactory) newSession(
388388
}
389389
s.EnableResetSeqTime = true
390390
s.ResetSeqTime = seqTime
391-
s.LastCheckedResetSeqTime = seqTime
392391
} else {
393392
s.EnableResetSeqTime = false
394393
}

session_state.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,27 @@ func (sm *stateMachine) CheckSessionTime(session *session, now time.Time) {
156156
}
157157

158158
func (sm *stateMachine) CheckResetTime(session *session, now time.Time) {
159-
if session.EnableResetSeqTime {
160-
// If we have crossed the reset time boundary in between checks, we send the reset
161-
if session.LastCheckedResetSeqTime.Before(session.ResetSeqTime) && now.After(session.ResetSeqTime) && session.stateMachine.State.IsConnected() {
162-
session.sendLogonInReplyTo(true, nil)
163-
}
164-
session.LastCheckedResetSeqTime = now
159+
// If the reset time is not enabled, we do nothing.
160+
if !session.EnableResetSeqTime {
161+
return
162+
}
163+
// If the last checked reset seq time is not set or we are not connected, we do nothing.
164+
if session.lastCheckedResetSeqTime.IsZero() || !session.stateMachine.State.IsConnected() {
165+
session.lastCheckedResetSeqTime = now
166+
return
165167
}
168+
169+
// Get the reset time for today
170+
nowInTimeZone := now.In(session.ResetSeqTime.Location())
171+
resetSeqTimeToday := time.Date(nowInTimeZone.Year(), nowInTimeZone.Month(), nowInTimeZone.Day(), session.ResetSeqTime.Hour(), session.ResetSeqTime.Minute(), session.ResetSeqTime.Second(), session.ResetSeqTime.Nanosecond(), session.ResetSeqTime.Location())
172+
173+
// If we have crossed the reset time boundary in between checks or we are at the reset time, we send the reset
174+
if session.lastCheckedResetSeqTime.Before(resetSeqTimeToday) && !now.Before(resetSeqTimeToday) {
175+
session.sendLogonInReplyTo(true, nil)
176+
}
177+
178+
// Update the last checked reset seq time to now
179+
session.lastCheckedResetSeqTime = now
166180
}
167181

168182
func (sm *stateMachine) setState(session *session, nextState sessionState) {

session_test.go

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ func (s *SessionSuite) TestSeqNumResetTimeAfterElapse() {
10771077
s.NextSenderMsgSeqNum(2)
10781078
s.NextTargetMsgSeqNum(2)
10791079

1080-
s.session.LastCheckedResetSeqTime = before
1080+
s.session.lastCheckedResetSeqTime = before
10811081
s.session.CheckResetTime(s.session, after)
10821082
s.NextSenderMsgSeqNum(2)
10831083
s.NextTargetMsgSeqNum(1)
@@ -1107,7 +1107,7 @@ func (s *SessionSuite) TestSeqNumResetTimeNotAfterDisconnect() {
11071107
s.Disconnected()
11081108
s.Stopped()
11091109

1110-
s.session.LastCheckedResetSeqTime = before
1110+
s.session.lastCheckedResetSeqTime = before
11111111
s.session.CheckResetTime(s.session, after)
11121112
s.NextSenderMsgSeqNum(2)
11131113
s.NextTargetMsgSeqNum(2)
@@ -1169,7 +1169,7 @@ func (s *SessionSuite) TestSeqNumResetTimeAfterElapse_LocalTZ() {
11691169
s.NextSenderMsgSeqNum(2)
11701170
s.NextTargetMsgSeqNum(2)
11711171

1172-
s.session.LastCheckedResetSeqTime = before
1172+
s.session.lastCheckedResetSeqTime = before
11731173
s.session.CheckResetTime(s.session, after)
11741174
s.NextSenderMsgSeqNum(2)
11751175
s.NextTargetMsgSeqNum(1)
@@ -1204,8 +1204,125 @@ func (s *SessionSuite) TestSeqNumResetTimeNotAfterDisconnect_LocalTZ() {
12041204
s.Disconnected()
12051205
s.Stopped()
12061206

1207-
s.session.LastCheckedResetSeqTime = before
1207+
s.session.lastCheckedResetSeqTime = before
12081208
s.session.CheckResetTime(s.session, after)
12091209
s.NextSenderMsgSeqNum(2)
12101210
s.NextTargetMsgSeqNum(2)
12111211
}
1212+
1213+
func (s *SessionSuite) TestSeqNumResetTimeAfterElapse_MultipleDaysLater() {
1214+
s.session.State = logonState{}
1215+
1216+
// Example Dates:
1217+
// ResetTime = 2025-06-08 10:15:30
1218+
// Before = 2025-07-10 10:15:29
1219+
// After = 2025-07-10 10:15:32
1220+
resetTime := time.Now()
1221+
before := resetTime.AddDate(0, 1, 2).Add(time.Second * -1)
1222+
after := resetTime.AddDate(0, 1, 2).Add(time.Second * 2)
1223+
1224+
s.session.ResetSeqTime = resetTime
1225+
s.session.EnableResetSeqTime = true
1226+
1227+
s.NextSenderMsgSeqNum(1)
1228+
s.NextTargetMsgSeqNum(1)
1229+
s.IncrNextTargetMsgSeqNum()
1230+
s.IncrNextSenderMsgSeqNum()
1231+
s.NextSenderMsgSeqNum(2)
1232+
s.NextTargetMsgSeqNum(2)
1233+
1234+
s.MockApp.On("ToAdmin")
1235+
s.session.CheckResetTime(s.session, before)
1236+
s.NextSenderMsgSeqNum(2)
1237+
s.NextTargetMsgSeqNum(2)
1238+
1239+
s.session.lastCheckedResetSeqTime = before
1240+
s.session.CheckResetTime(s.session, after)
1241+
s.NextSenderMsgSeqNum(2)
1242+
s.NextTargetMsgSeqNum(1)
1243+
}
1244+
1245+
func (s *SessionSuite) TestSeqNumResetTimeAtExactTime() {
1246+
s.session.State = logonState{}
1247+
resetTime := time.Now()
1248+
before := resetTime.Add(time.Second * -1)
1249+
1250+
s.session.ResetSeqTime = resetTime
1251+
s.session.EnableResetSeqTime = true
1252+
1253+
s.NextSenderMsgSeqNum(1)
1254+
s.NextTargetMsgSeqNum(1)
1255+
s.IncrNextTargetMsgSeqNum()
1256+
s.IncrNextSenderMsgSeqNum()
1257+
s.NextSenderMsgSeqNum(2)
1258+
s.NextTargetMsgSeqNum(2)
1259+
1260+
// We are before the reset time, so we should not reset the seq numbers
1261+
s.MockApp.On("ToAdmin")
1262+
s.session.CheckResetTime(s.session, before)
1263+
s.NextSenderMsgSeqNum(2)
1264+
s.NextTargetMsgSeqNum(2)
1265+
1266+
// We check the reset time exactly at the configured time, so we reset
1267+
s.session.lastCheckedResetSeqTime = before
1268+
s.session.CheckResetTime(s.session, resetTime)
1269+
s.NextSenderMsgSeqNum(2)
1270+
s.NextTargetMsgSeqNum(1)
1271+
}
1272+
1273+
func (s *SessionSuite) TestSeqNumResetTimePreviousCheck() {
1274+
s.session.State = logonState{}
1275+
resetTime := time.Now()
1276+
before := resetTime.Add(time.Second * -1)
1277+
after := resetTime.Add(time.Second * 1)
1278+
1279+
s.session.ResetSeqTime = resetTime
1280+
s.session.EnableResetSeqTime = true
1281+
1282+
s.NextSenderMsgSeqNum(1)
1283+
s.NextTargetMsgSeqNum(1)
1284+
s.IncrNextTargetMsgSeqNum()
1285+
s.IncrNextSenderMsgSeqNum()
1286+
s.NextSenderMsgSeqNum(2)
1287+
s.NextTargetMsgSeqNum(2)
1288+
1289+
// We are before the reset time, so we should not reset the seq numbers
1290+
s.MockApp.On("ToAdmin")
1291+
s.session.CheckResetTime(s.session, before)
1292+
s.NextSenderMsgSeqNum(2)
1293+
s.NextTargetMsgSeqNum(2)
1294+
1295+
// We just checked the reset time at the configured time, so we do not reset the seq num for the next check
1296+
s.session.lastCheckedResetSeqTime = resetTime
1297+
s.session.CheckResetTime(s.session, after)
1298+
s.NextSenderMsgSeqNum(2)
1299+
s.NextTargetMsgSeqNum(2)
1300+
}
1301+
1302+
func (s *SessionSuite) TestSeqNumResetTime_NanoSeconds() {
1303+
s.session.State = logonState{}
1304+
resetTime := time.Now()
1305+
// Nanoseconds are not used in the resetSeqTime, but are referenced in the comparison of before/after
1306+
before := resetTime.Add(time.Nanosecond * -1)
1307+
after := resetTime.Add(time.Nanosecond * 1)
1308+
1309+
s.session.ResetSeqTime = resetTime
1310+
s.session.EnableResetSeqTime = true
1311+
1312+
s.NextSenderMsgSeqNum(1)
1313+
s.NextTargetMsgSeqNum(1)
1314+
s.IncrNextTargetMsgSeqNum()
1315+
s.IncrNextSenderMsgSeqNum()
1316+
s.NextSenderMsgSeqNum(2)
1317+
s.NextTargetMsgSeqNum(2)
1318+
1319+
s.MockApp.On("ToAdmin")
1320+
s.session.CheckResetTime(s.session, before)
1321+
s.NextSenderMsgSeqNum(2)
1322+
s.NextTargetMsgSeqNum(2)
1323+
1324+
s.session.lastCheckedResetSeqTime = before
1325+
s.session.CheckResetTime(s.session, after)
1326+
s.NextSenderMsgSeqNum(2)
1327+
s.NextTargetMsgSeqNum(1)
1328+
}

0 commit comments

Comments
 (0)