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");
            }
        }
Example #2
0
        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;
            }
        }