Skip to content

Commit 8c26237

Browse files
authored
Merge pull request #455 from michaelwilner/fqual
Expose configuration options for useful overrides
2 parents fc8e0d5 + 95390a2 commit 8c26237

File tree

7 files changed

+117
-12
lines changed

7 files changed

+117
-12
lines changed

config/configuration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const (
4747
LogoutTimeout string = "LogoutTimeout"
4848
LogonTimeout string = "LogonTimeout"
4949
HeartBtInt string = "HeartBtInt"
50+
HeartBtIntOverride string = "HeartBtIntOverride"
5051
FileLogPath string = "FileLogPath"
5152
FileStorePath string = "FileStorePath"
5253
SQLStoreDriver string = "SQLStoreDriver"

config/doc.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,15 @@ Defaults to 10
244244
245245
HeartBtInt
246246
247-
Heartbeat interval in seconds. Only used for initiators. Value must be positive integer.
247+
Heartbeat interval in seconds. Only used for initiators (unless HeartBtIntOverride is Y). Value must be positive integer.
248+
249+
HeartBtIntOverride
250+
251+
If set to Y, will use the HeartBtInt interval rather than what the initiator dictates. Only used for acceptors. Valid Values:
252+
Y
253+
N
254+
255+
Defaults to N.
248256
249257
SocketConnectPort
250258

internal/session_settings.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type SessionSettings struct {
99
ResetOnLogout bool
1010
ResetOnDisconnect bool
1111
HeartBtInt time.Duration
12+
HeartBtIntOverride bool
1213
SessionTime *TimeRange
1314
InitiateLogon bool
1415
ResendRequestChunkSize int

logon_state_test.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ func (s *LogonStateTestSuite) TestFixMsgInLogon() {
7676
s.MockApp.On("FromAdmin").Return(nil)
7777
s.MockApp.On("OnLogon")
7878
s.MockApp.On("ToAdmin")
79+
s.Zero(s.session.HeartBtInt)
7980
s.fixMsgIn(s.session, logon)
8081

8182
s.MockApp.AssertExpectations(s.T())
8283

8384
s.State(inSession{})
84-
s.Equal(32*time.Second, s.session.HeartBtInt)
85+
s.Equal(32*time.Second, s.session.HeartBtInt) //should be written from logon message
86+
s.False(s.session.HeartBtIntOverride)
8587

8688
s.LastToAdminMessageSent()
8789
s.MessageType(string(msgTypeLogon), s.MockApp.lastToAdmin)
@@ -91,6 +93,35 @@ func (s *LogonStateTestSuite) TestFixMsgInLogon() {
9193
s.NextSenderMsgSeqNum(3)
9294
}
9395

96+
func (s *LogonStateTestSuite) TestFixMsgInLogonHeartBtIntOverride() {
97+
s.IncrNextSenderMsgSeqNum()
98+
s.MessageFactory.seqNum = 1
99+
s.IncrNextTargetMsgSeqNum()
100+
101+
logon := s.Logon()
102+
logon.Body.SetField(tagHeartBtInt, FIXInt(32))
103+
104+
s.MockApp.On("FromAdmin").Return(nil)
105+
s.MockApp.On("OnLogon")
106+
s.MockApp.On("ToAdmin")
107+
s.session.HeartBtIntOverride = true
108+
s.session.HeartBtInt = time.Second
109+
s.fixMsgIn(s.session, logon)
110+
111+
s.MockApp.AssertExpectations(s.T())
112+
113+
s.State(inSession{})
114+
s.Equal(time.Second, s.session.HeartBtInt) //should not have changed
115+
s.True(s.session.HeartBtIntOverride)
116+
117+
s.LastToAdminMessageSent()
118+
s.MessageType(string(msgTypeLogon), s.MockApp.lastToAdmin)
119+
s.FieldEquals(tagHeartBtInt, 1, s.MockApp.lastToAdmin.Body)
120+
121+
s.NextTargetMsgSeqNum(3)
122+
s.NextSenderMsgSeqNum(3)
123+
}
124+
94125
func (s *LogonStateTestSuite) TestFixMsgInLogonEnableLastMsgSeqNumProcessed() {
95126
s.session.EnableLastMsgSeqNumProcessed = true
96127

session.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -441,9 +441,11 @@ func (s *session) handleLogon(msg *Message) error {
441441
}
442442

443443
if !s.InitiateLogon {
444-
var heartBtInt FIXInt
445-
if err := msg.Body.GetField(tagHeartBtInt, &heartBtInt); err == nil {
446-
s.HeartBtInt = time.Duration(heartBtInt) * time.Second
444+
if !s.HeartBtIntOverride {
445+
var heartBtInt FIXInt
446+
if err := msg.Body.GetField(tagHeartBtInt, &heartBtInt); err == nil {
447+
s.HeartBtInt = time.Duration(heartBtInt) * time.Second
448+
}
447449
}
448450

449451
s.log.OnEvent("Responding to logon request")

session_factory.go

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ func (f sessionFactory) newSession(
286286
if err = f.buildInitiatorSettings(s, settings); err != nil {
287287
return
288288
}
289+
} else if err = f.buildAcceptorSettings(s, settings); err != nil {
290+
return
289291
}
290292

291293
if s.log, err = logFactory.CreateSessionLog(s.sessionID); err != nil {
@@ -303,19 +305,20 @@ func (f sessionFactory) newSession(
303305
return
304306
}
305307

308+
func (f sessionFactory) buildAcceptorSettings(session *session, settings *SessionSettings) error {
309+
if err := f.buildHeartBtIntSettings(session, settings, false); err != nil {
310+
return err
311+
}
312+
return nil
313+
}
314+
306315
func (f sessionFactory) buildInitiatorSettings(session *session, settings *SessionSettings) error {
307316
session.InitiateLogon = true
308317

309-
heartBtInt, err := settings.IntSetting(config.HeartBtInt)
310-
if err != nil {
318+
if err := f.buildHeartBtIntSettings(session, settings, true); err != nil {
311319
return err
312320
}
313321

314-
if heartBtInt <= 0 {
315-
return errors.New("Heartbeat must be greater than zero")
316-
}
317-
session.HeartBtInt = time.Duration(heartBtInt) * time.Second
318-
319322
session.ReconnectInterval = 30 * time.Second
320323
if settings.HasSetting(config.ReconnectInterval) {
321324

@@ -394,3 +397,23 @@ func (f sessionFactory) configureSocketConnectAddress(session *session, settings
394397
i++
395398
}
396399
}
400+
401+
func (f sessionFactory) buildHeartBtIntSettings(session *session, settings *SessionSettings, mustProvide bool) (err error) {
402+
if settings.HasSetting(config.HeartBtIntOverride) {
403+
if session.HeartBtIntOverride, err = settings.BoolSetting(config.HeartBtIntOverride); err != nil {
404+
return
405+
}
406+
}
407+
408+
if session.HeartBtIntOverride || mustProvide {
409+
var heartBtInt int
410+
if heartBtInt, err = settings.IntSetting(config.HeartBtInt); err != nil {
411+
return
412+
} else if heartBtInt <= 0 {
413+
err = errors.New("Heartbeat must be greater than zero")
414+
return
415+
}
416+
session.HeartBtInt = time.Duration(heartBtInt) * time.Second
417+
}
418+
return
419+
}

session_factory_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func (s *SessionFactorySuite) TestDefaults() {
5151
s.Equal(Millis, session.timestampPrecision)
5252
s.Equal(120*time.Second, session.MaxLatency)
5353
s.False(session.DisableMessagePersist)
54+
s.False(session.HeartBtIntOverride)
5455
}
5556

5657
func (s *SessionFactorySuite) TestResetOnLogon() {
@@ -358,9 +359,47 @@ func (s *SessionFactorySuite) TestNewSessionBuildInitiators() {
358359
s.Equal("127.0.0.1:5000", session.SocketConnectAddress[0])
359360
}
360361

362+
func (s *SessionFactorySuite) TestNewSessionBuildAcceptors() {
363+
s.sessionFactory.BuildInitiators = false
364+
s.SessionSettings.Set(config.HeartBtInt, "34")
365+
366+
session, err := s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App)
367+
s.Nil(err)
368+
s.False(session.InitiateLogon)
369+
s.Zero(session.HeartBtInt)
370+
s.False(session.HeartBtIntOverride)
371+
372+
s.SessionSettings.Set(config.HeartBtIntOverride, "Y")
373+
session, err = s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App)
374+
s.Nil(err)
375+
s.False(session.InitiateLogon)
376+
s.Equal(34*time.Second, session.HeartBtInt)
377+
s.True(session.HeartBtIntOverride)
378+
}
379+
361380
func (s *SessionFactorySuite) TestNewSessionBuildInitiatorsValidHeartBtInt() {
362381
s.sessionFactory.BuildInitiators = true
363382

383+
_, err := s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App)
384+
s.NotNil(err, "HeartBtInt should be required for acceptors with override defined")
385+
386+
s.SessionSettings.Set(config.HeartBtInt, "not a number")
387+
_, err = s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App)
388+
s.NotNil(err, "HeartBtInt must be a number")
389+
390+
s.SessionSettings.Set(config.HeartBtInt, "0")
391+
_, err = s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App)
392+
s.NotNil(err, "HeartBtInt must be greater than zero")
393+
394+
s.SessionSettings.Set(config.HeartBtInt, "-20")
395+
_, err = s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App)
396+
s.NotNil(err, "HeartBtInt must be greater than zero")
397+
}
398+
399+
func (s *SessionFactorySuite) TestNewSessionBuildAcceptorsValidHeartBtInt() {
400+
s.sessionFactory.BuildInitiators = false
401+
402+
s.SessionSettings.Set(config.HeartBtIntOverride, "Y")
364403
_, err := s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App)
365404
s.NotNil(err, "HeartBtInt should be required for initiators")
366405

0 commit comments

Comments
 (0)