protected void Persist(Message message, string messageString) { if (this.PersistMessages) { int msgSeqNum = message.Header.GetInt(Fields.Tags.MsgSeqNum); state_.Set(msgSeqNum, messageString); } state_.IncrNextSenderMsgSeqNum(); }
public void ThreadSafeSetAndGet() { //Set up store if (System.IO.Directory.Exists("store")) { System.IO.Directory.Delete("store", true); } SessionID sessionId = new SessionID("FIX.4.2", "SENDERCOMP", "TARGETCOMP"); Dictionary config = new Dictionary(); config.SetString(SessionSettings.CONNECTION_TYPE, "initiator"); config.SetString(SessionSettings.FILE_STORE_PATH, "store"); SessionSettings settings = new SessionSettings(); settings.Set(sessionId, config); FileStoreFactory factory = new FileStoreFactory(settings); FileStore store = (FileStore)factory.Create(sessionId); NullLog log = new NullLog(); //Set up sessionstate SessionState state = new SessionState(log, 1) {MessageStore = store}; Hashtable errorsTable = Hashtable.Synchronized(new Hashtable());//used in more than 1 thread at a time Hashtable setTable = new Hashtable(1000);//only used in 1 thread at a time Hashtable getTable = new Hashtable(1000);//only used in 1 thread at a time //Synchronously populate 1000 messages for (int i = 1; i < 1000; i++) { string msg = "msg" + i; state.Set(i, msg); setTable[i] = msg; } //Simulate background sending of messages that populate into the store AutoResetEvent setEvent = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(delegate(object stateObject) { AutoResetEvent internalSetEvent = (AutoResetEvent)((object[])stateObject)[0]; SessionState internalState = (SessionState)((object[])stateObject)[1]; for (int i = 1001; i < 2000; i++) { try { internalState.Set(i, "msg" + i); } catch (System.IO.IOException ex) { errorsTable[ex.Message] = ex; } } internalSetEvent.Set(); } , new object[] { setEvent, state }); //Simulate background reading of messages from the store - like is done in a resend request answer AutoResetEvent getEvent = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(delegate(object stateObject){ AutoResetEvent internalGetEvent = (AutoResetEvent)((object[])stateObject)[0]; SessionState internalState = (SessionState)((object[])stateObject)[1]; for (int i = 1; i < 1000; i++) { try { List<string> lst = new List<string>(1); internalState.Get(i, i, lst); if (lst.Count == 0) { getTable[i] = "nothing read"; } else { getTable[i] = lst[0]; } } catch (System.IO.IOException ex) { errorsTable[ex.Message] = ex; } } internalGetEvent.Set(); } , new object[]{getEvent, state}); //wait till done and assert results Assert.True(setEvent.WaitOne(10000), "Get or Set hung/timed out during concurrent usage"); Assert.True(getEvent.WaitOne(10000), "Get or Set hung/timed out during concurrent usage"); Assert.AreEqual(setTable, getTable, "Garbled data read in concurrent set and get (like between resendrequest and send)"); Assert.AreEqual(errorsTable.Count, 0, "IOException occured in concurrent set and get (like between resendrequest and send)"); //Tear down filestore state.Dispose(); store.Dispose(); }