private void TryReceive() { _trace.TraceVerbose("Trying receive"); if (mutex.WaitOne(interval)) { _trace.TraceVerbose("Not locked out"); try { using (var session = _sessionFactory.OpenStatelessSession()) { var messagesItems = session.Query <TMessageType>() .OrderBy(i => i.PayloadId) .Where(i => i.PayloadId > _lastPayloadId); Queried(); if (messagesItems.Any()) { _trace.TraceVerbose("found messages"); } foreach (var messageItem in messagesItems) { var id = messageItem.PayloadId; var scaleoutMessage = FNHPayload.FromBytes(messageItem); _trace.TraceVerbose("{0}SqlReceiver last payload ID={1}, new payload ID={2}", _tracePrefix, _lastPayloadId, id); if (id > _lastPayloadId + 1) { _trace.TraceError( "{0}Missed message(s) from database. Expected payload ID {1} but got {2}.", _tracePrefix, _lastPayloadId + 1, id); } else if (id <= _lastPayloadId) { _trace.TraceInformation( "{0}Duplicate message(s) or payload ID reset from database. Last payload ID {1}, this payload ID {2}", _tracePrefix, _lastPayloadId, id); } _lastPayloadId = id; _trace.TraceVerbose("{0}Payload {1} containing {2} message(s) received", _tracePrefix, id, scaleoutMessage.Messages.Count); foreach (var message in scaleoutMessage.Messages) { if (message.Value.Array != null) { var valueArray = message.Value.Array; _trace.TraceVerbose(System.Text.Encoding.UTF8.GetString(valueArray)); } } Received((ulong)id, scaleoutMessage); } } } catch (Exception ex) { Faulted(ex); } finally { mutex.ReleaseMutex(); } } else { _trace.TraceVerbose("Receive is locked out"); } }
private int InsertMessage(IList <Message> messages) { try { _trace.TraceVerbose("inserting"); int result; using (var session = _sessionFactory.OpenSession()) { long newPayloadId; using (var tx = session.BeginTransaction(IsolationLevel.RepeatableRead)) { var messageId = session.Query <TIdType>().FirstOrDefault(); if (messageId == null) { messageId = new TIdType { PayloadId = 1, RowId = 1 }; session.Save(messageId); } else { messageId.PayloadId++; session.Save(messageId); } newPayloadId = messageId.PayloadId; session.Save(new TMessageType { Payload = FNHPayload.ToBytes(messages), PayloadId = newPayloadId }); tx.Commit(); } result = 1; var maxTableSize = 10000; var blockSize = 2500; if (newPayloadId % blockSize == 0) { using (var tx = session.BeginTransaction(IsolationLevel.ReadCommitted)) { var queryable = session.Query <TMessageType>(); var aggregates = queryable .Select(m => new { Count = queryable.Count(), Min = queryable.Min(i => i.PayloadId) }) .First(); var rowCount = aggregates.Count; var minPayloadId = aggregates.Min; if (rowCount > maxTableSize) { var overMaxBy = rowCount - maxTableSize; var endPayloadId = minPayloadId + blockSize - overMaxBy; var sql = string.Format("delete from `{0}` where {1} between :min and :max", typeof(TMessageType).Name, nameof(MessagesItemBase.PayloadId)); result = session.CreateQuery(sql) .SetParameter("min", minPayloadId) .SetParameter("max", endPayloadId) .ExecuteUpdate(); } tx.Commit(); } } } return(result); } catch (Exception ex) { _trace.TraceError("Issue with send", ex); throw; } }