diff --git a/QuickFIXn/Session.cs b/QuickFIXn/Session.cs index 51c348046..f52a58bfd 100755 --- a/QuickFIXn/Session.cs +++ b/QuickFIXn/Session.cs @@ -1646,9 +1646,12 @@ protected void Persist(Message message, string messageString) if (PersistMessages) { SeqNumType msgSeqNum = message.Header.GetULong(Fields.Tags.MsgSeqNum); - _state.Set(msgSeqNum, messageString); + _state.SetAndIncrNextSenderMsgSeqNum(msgSeqNum, messageString); + } + else + { + _state.IncrNextSenderMsgSeqNum(); } - _state.IncrNextSenderMsgSeqNum(); } protected bool IsGoodTime(Message msg) diff --git a/QuickFIXn/SessionState.cs b/QuickFIXn/SessionState.cs index 38ce466d7..a8cd350fb 100755 --- a/QuickFIXn/SessionState.cs +++ b/QuickFIXn/SessionState.cs @@ -373,6 +373,11 @@ public void IncrNextTargetMsgSeqNum() lock (_sync) { MessageStore.IncrNextTargetMsgSeqNum(); } } + public bool SetAndIncrNextSenderMsgSeqNum(SeqNumType msgSeqNum, string msg) + { + lock (_sync) { return MessageStore.SetAndIncrNextSenderMsgSeqNum(msgSeqNum, msg); } + } + public DateTime? CreationTime { get diff --git a/QuickFIXn/Store/IMessageStore.cs b/QuickFIXn/Store/IMessageStore.cs index 0a77f3539..531a3e0d1 100755 --- a/QuickFIXn/Store/IMessageStore.cs +++ b/QuickFIXn/Store/IMessageStore.cs @@ -18,7 +18,7 @@ public interface IMessageStore : IDisposable void Get(SeqNumType startSeqNum, SeqNumType endSeqNum, List messages); /// - /// Adds a raw fix message to the store with the give sequence number + /// Adds a raw fix message to the store with the given sequence number /// /// the sequence number /// the raw FIX message string @@ -31,6 +31,24 @@ public interface IMessageStore : IDisposable void IncrNextSenderMsgSeqNum(); void IncrNextTargetMsgSeqNum(); + /// + /// The purpose of this method is to combine + /// and into one call, for use in situations + /// when these operations should be performed together. + /// The default implementation simply calls those two functions. + /// Certain custom IMessageStore implementations (e.g. DB-backed stores) + /// may need to override the default implementation to ensure that these two behaviors + /// are combined into a single atomic operation. + /// the sequence number + /// the raw FIX message string + /// true if successful, false otherwise + /// + bool SetAndIncrNextSenderMsgSeqNum(SeqNumType msgSeqNum, string msg) + { + bool result = Set(msgSeqNum, msg); + IncrNextSenderMsgSeqNum(); + return result; + } DateTime? CreationTime { get; } @@ -49,3 +67,4 @@ public interface IMessageStore : IDisposable /// void Refresh(); } + diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f0fb39712..3edeb9378 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -38,6 +38,7 @@ What's New * #949 - new settings RedactFieldsInLogs & RedactionLogText (gbirchmeier) * #983 - new MessageFactoryNotFound exception provides better feedback (gbirchmeier) * #1014 - deprecate DateTimeConverter.ParseToTimeOnly (gbirchmeier) +* #987 - new interface method IMessageStore.SetAndIncrNextSenderMsgSeqNum (asmeisne) ### v1.14.0 diff --git a/UnitTests/FileStoreTests.cs b/UnitTests/FileStoreTests.cs index 6264c4d74..58ab063c0 100755 --- a/UnitTests/FileStoreTests.cs +++ b/UnitTests/FileStoreTests.cs @@ -208,4 +208,30 @@ public void GetTest() Assert.That(msgs, Is.EqualTo(expected)); } + + [Test] + public void SetAndIncrNextSenderMsgSeqNumTest() + { + IMessageStore messageStore = _store ?? throw new InvalidProgramException(); + + messageStore.SetAndIncrNextSenderMsgSeqNum(1, "dude"); + messageStore.SetAndIncrNextSenderMsgSeqNum(2, "pude"); + messageStore.SetAndIncrNextSenderMsgSeqNum(3, "ok"); + messageStore.SetAndIncrNextSenderMsgSeqNum(4, "ohai"); + + var msgs = new List(); + _store.Get(2, 3, msgs); + var expected = new List() { "pude", "ok" }; + + Assert.That(msgs, Is.EqualTo(expected)); + Assert.That(_store.NextSenderMsgSeqNum, Is.EqualTo(5)); + + RebuildStore(); + + msgs = new List(); + _store.Get(2, 3, msgs); + + Assert.That(msgs, Is.EqualTo(expected)); + Assert.That(_store.NextSenderMsgSeqNum, Is.EqualTo(5)); + } } diff --git a/UnitTests/MemoryStoreTest.cs b/UnitTests/MemoryStoreTest.cs index 43d521dc9..1512dd0ad 100644 --- a/UnitTests/MemoryStoreTest.cs +++ b/UnitTests/MemoryStoreTest.cs @@ -24,4 +24,23 @@ public void GetTest() store.Get(5, 6, msgs); Assert.That(msgs, Is.Empty); } + + [Test] + public void SetAndIncrNextSenderMsgSeqNumTest() + { + IMessageStore store = new MemoryStore(); + store.SetAndIncrNextSenderMsgSeqNum(1, "dude"); + store.SetAndIncrNextSenderMsgSeqNum(2, "pude"); + store.SetAndIncrNextSenderMsgSeqNum(3, "ok"); + store.SetAndIncrNextSenderMsgSeqNum(4, "ohai"); + var msgs = new List(); + store.Get(2, 3, msgs); + var expected = new List() { "pude", "ok" }; + Assert.That(msgs, Is.EqualTo(expected)); + + msgs = new List(); + store.Get(5, 6, msgs); + Assert.That(msgs, Is.Empty); + Assert.That(store.NextSenderMsgSeqNum, Is.EqualTo(5)); + } }