Пример #1
0
 internal static TMessage ReadMessageWithId <TMessage>(this EsentTable table, MessageBookmark bookmark, string queueName) where TMessage : PersistentMessage, new()
 {
     return(ReadMessage <TMessage>(table, bookmark, queueName, x =>
     {
         x.Id = table.GetMessageId();
     }));
 }
Пример #2
0
        internal static TMessage ReadMessageWithId <TMessage>(this EsentTable table, MessageBookmark bookmark,
                                                              string queueName, Action <TMessage> action) where TMessage : PersistentMessage, new()
        {
            var message = table.ReadMessageWithId <TMessage>(bookmark, queueName);

            action(message);
            return(message);
        }
Пример #3
0
 public MessageBookmark Insert(Action insertBlock)
 {
     using (var update = new Update(_session, _table, JET_prep.Insert))
     {
         insertBlock();
         var bookMark = new MessageBookmark();
         update.Save(bookMark.Bookmark, bookMark.Size, out bookMark.Size);
         return(bookMark);
     }
 }
Пример #4
0
        public void SetMessageStatus(MessageBookmark bookmark, MessageStatus status)
        {
            _messages.MoveTo(bookmark);
            var id = _messages.GetMessageId();

            _messages.Update(() => _messages.ForColumnType <IntColumn>().Set("status", (int)status));

            _logger.Debug("Changing message {0} status to {1} on {2}",
                          id, status, _queueName);
        }
Пример #5
0
 public MessageBookmark Update(Action updateBlock)
 {
     using (var update = new Update(_session, _table, JET_prep.Replace))
     {
         var bookmark = new MessageBookmark();
         updateBlock();
         update.Save(bookmark.Bookmark, bookmark.Size, out bookmark.Size);
         return(bookmark);
     }
 }
Пример #6
0
        public void SetMessageStatus(MessageBookmark bookmark, MessageStatus status, string subqueue)
        {
            _messages.MoveTo(bookmark);
            var id = _messages.GetMessageId();

            _messages.Update(() =>
            {
                _messages.ForColumnType <IntColumn>().Set("status", (int)status);
                _messages.ForColumnType <StringColumn>().Set("subqueue", subqueue);
            });
            _logger.Debug("Changing message {0} status to {1} on queue '{2}' and set subqueue to '{3}'",
                          id, status, _queueName, subqueue);
        }
Пример #7
0
        private void PurgeOutgoingHistory()
        {
            // Outgoing messages are still stored in the history in case the sender
            // needs to revert, so there will still be messages to purge even when
            // the QueueManagerConfiguration has disabled outgoing history.
            //
            // To make this batchable:
            // 1: Move to the end of the history (to the newest messages) and seek
            //    backword by NumberOfMessagesToKeepInOutgoingHistory.
            // 2: Save a bookmark of the current position.
            // 3: Delete from the beginning of the table (oldest messages) in batches until
            //    a) we reach the bookmark or b) we hit OldestMessageInOutgoingHistory.

            MessageBookmark purgeLimit             = null;
            int             numberOfMessagesToKeep = _configuration.NumberOfMessagesToKeepInOutgoingHistory;

            if (numberOfMessagesToKeep > 0 && _configuration.EnableOutgoingMessageHistory)
            {
                Global(actions =>
                {
                    purgeLimit = actions.GetSentMessageBookmarkAtPosition(numberOfMessagesToKeep);
                });

                if (purgeLimit == null)
                {
                    return;
                }
            }

            bool foundMessages = false;

            do
            {
                foundMessages = false;
                Global(actions =>
                {
                    IEnumerable <PersistentMessageToSend> sentMessages = actions.GetSentMessages(batchSize: 250)
                                                                         .TakeWhile(x => (purgeLimit == null || !x.Bookmark.Equals(purgeLimit)) &&
                                                                                    (!_configuration.EnableOutgoingMessageHistory || (DateTime.Now - x.SentAt) > _configuration.OldestMessageInOutgoingHistory));

                    foreach (var sentMessage in sentMessages)
                    {
                        foundMessages = true;
                        _logger.Debug("Purging sent message {0} to {1}/{2}/{3}", sentMessage.Id, sentMessage.Endpoint,
                                      sentMessage.Queue, sentMessage.SubQueue);
                        actions.DeleteMessageToSendHistoric(sentMessage.Bookmark);
                    }
                });
            } while (foundMessages);
        }
Пример #8
0
        internal static TMessage ReadMessage <TMessage>(this EsentTable table, MessageBookmark bookmark, string queueName, Action <TMessage> action) where TMessage : PersistentMessage, new()
        {
            var message = new TMessage
            {
                Bookmark = bookmark,
                Status   = (MessageStatus)table.ForColumnType <IntColumn>().Get("status"),
                Headers  = HttpUtility.ParseQueryString(table.ForColumnType <StringColumn>().Get("headers")),
                Queue    = queueName,
                SentAt   = table.ForColumnType <DateTimeColumn>().Get("timestamp"),
                Data     = table.ForColumnType <BytesColumn>().Get("data"),
            };

            action(message);
            return(message);
        }
Пример #9
0
        private void PurgeProcessedMessagesInQueue(string queue)
        {
            // To make this batchable:
            // 1: Move to the end of the history (to the newest messages) and seek
            //    backword by NumberOfMessagesToKeepInProcessedHistory.
            // 2: Save a bookmark of the current position.
            // 3: Delete from the beginning of the table (oldest messages) in batches until
            //    a) we reach the bookmark or b) we hit OldestMessageInProcessedHistory.
            MessageBookmark purgeLimit             = null;
            int             numberOfMessagesToKeep = _configuration.NumberOfMessagesToKeepInProcessedHistory;

            if (numberOfMessagesToKeep > 0)
            {
                Global(actions =>
                {
                    var queueActions = actions.GetQueue(queue);
                    purgeLimit       = queueActions.GetMessageHistoryBookmarkAtPosition(numberOfMessagesToKeep);
                });

                if (purgeLimit == null)
                {
                    return;
                }
            }

            bool foundMessages = false;

            do
            {
                foundMessages = false;
                Global(actions =>
                {
                    var queueActions = actions.GetQueue(queue);
                    var messages     = queueActions.GetAllProcessedMessages(batchSize: 250)
                                       .TakeWhile(x => (purgeLimit == null || !x.Bookmark.Equals(purgeLimit)) &&
                                                  (DateTime.Now - x.SentAt) > _configuration.OldestMessageInProcessedHistory);

                    foreach (var message in messages)
                    {
                        foundMessages = true;
                        _logger.Debug("Purging message {0} from queue {1}/{2}", message.Id, message.Queue, message.SubQueue);
                        queueActions.DeleteHistoric(message.Bookmark);
                    }
                });
            } while (foundMessages);
        }
Пример #10
0
        public MessageBookmark MarkOutgoingMessageAsSuccessfullySent(MessageBookmark bookmark)
        {
            outgoing.MoveTo(bookmark);
            var newBookmark = outgoingHistory.Insert(() =>
            {
                foreach (var column in outgoing.ColumnNames)
                {
                    var bytes = outgoing.ForColumnType <BytesColumn>().Get(column);
                    outgoingHistory.ForColumnType <BytesColumn>().Set(column, bytes);
                }
                outgoingHistory.ForColumnType <IntColumn>().Set("send_status", (int)OutgoingMessageStatus.Sent);
            });
            var msgId = outgoing.ForColumnType <GuidColumn>().Get("msg_id");

            outgoing.Delete();
            logger.Debug("Successfully sent output message {0}", msgId);
            return(newBookmark);
        }
Пример #11
0
        public void MoveToHistory(MessageBookmark bookmark)
        {
            _messages.MoveTo(bookmark);
            var id = _messages.GetMessageId();

            _messageHistory.Insert(() =>
            {
                _messages.ColumnNames.Each(x =>
                {
                    var columnBytes = _messages.ForColumnType <BytesColumn>().Get(x);
                    _messageHistory.ForColumnType <BytesColumn>().Set(x, columnBytes);
                });
                _messageHistory.ForColumnType <DateTimeColumn>().Set("moved_to_history_at", DateTime.Now);
            });
            _messages.Delete();
            _logger.Debug("Moving message {0} on queue {1} to history",
                          id, _queueName);
        }
Пример #12
0
        public void RegisterUpdateToReverse(Guid txId, MessageBookmark bookmark, MessageStatus statusToRestore, string subQueue)
        {
            var actualBookmark = bookmark.Bookmark.Take(bookmark.Size).ToArray();
            var enumerator     = txs.GetEnumerator(new BookmarkIndex(bookmark.Size, actualBookmark));

            if (enumerator.MoveNext())
            {
                txs.Delete();
            }

            txs.Insert(() =>
            {
                txs.ForColumnType <GuidColumn>().Set("tx_id", txId);
                txs.ForColumnType <IntColumn>().Set("bookmark_size", bookmark.Size);
                txs.ForColumnType <BytesColumn>().Set("bookmark_data", actualBookmark);
                txs.ForColumnType <IntColumn>().Set("value_to_restore", (int)statusToRestore);
                txs.ForColumnType <StringColumn>().Set("queue", bookmark.QueueName);
                txs.ForColumnType <StringColumn>().Set("subqueue", subQueue);
            });
        }
Пример #13
0
        public void ReverseAllFrom(Guid transactionId)
        {
            var enumerator = txs.GetEnumerator(new GuidIndex(transactionId, "by_tx_id"));

            while (enumerator.MoveNext())
            {
                try
                {
                    var oldStatus = (MessageStatus)txs.ForColumnType <IntColumn>().Get("value_to_restore");
                    var queue     = txs.ForColumnType <StringColumn>().Get("queue");
                    var subqueue  = txs.ForColumnType <StringColumn>().Get("subqueue");

                    var bookmark = new MessageBookmark
                    {
                        QueueName = queue,
                        Bookmark  = txs.ForColumnType <BytesColumn>().Get("bookmark_data"),
                        Size      = txs.ForColumnType <IntColumn>().Get("bookmark_size")
                    };
                    var actions   = GetQueue(queue);
                    var newStatus = actions.GetMessageStatus(bookmark);
                    switch (newStatus)
                    {
                    case MessageStatus.SubqueueChanged:
                        actions.SetMessageStatus(bookmark, MessageStatus.ReadyToDeliver, subqueue);
                        break;

                    case MessageStatus.EnqueueWait:
                        actions.Delete(bookmark);
                        break;

                    default:
                        actions.SetMessageStatus(bookmark, oldStatus);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    logger.Error("Failed to reverse a transaction", ex);
                }
            }
        }
Пример #14
0
        public void MarkOutgoingMessageAsFailedTransmission(MessageBookmark bookmark, bool queueDoesNotExistsInDestination)
        {
            outgoing.MoveTo(bookmark);
            var numOfRetries = outgoing.ForColumnType <IntColumn>().Get("number_of_retries");
            var msgId        = outgoing.ForColumnType <GuidColumn>().Get("msg_id");

            if (numOfRetries < 100 && queueDoesNotExistsInDestination == false)
            {
                outgoing.Update(() =>
                {
                    outgoing.ForColumnType <IntColumn>().Set("send_status", (int)OutgoingMessageStatus.Ready);
                    outgoing.ForColumnType <DateTimeColumn>().Set("time_to_send", DateTime.Now.AddSeconds(numOfRetries * numOfRetries));
                    outgoing.ForColumnType <IntColumn>().Set("number_of_retries", numOfRetries + 1);
                    logger.Debug("Marking outgoing message {0} as failed with retries: {1}", msgId, numOfRetries);
                });
            }
            else
            {
                MoveFailedMessageToOutgoingHistory(numOfRetries, msgId);
            }
        }
Пример #15
0
        public void RemoveReversalsMoveCompletedMessagesAndFinishSubQueueMove(Guid transactionId)
        {
            var enumerator = txs.GetEnumerator(new GuidIndex(transactionId, "by_tx_id"));

            while (enumerator.MoveNext())
            {
                var queue = txs.ForColumnType <StringColumn>().Get("queue");

                var actions = GetQueue(queue);

                var bookmark = new MessageBookmark
                {
                    Bookmark  = txs.ForColumnType <BytesColumn>().Get("bookmark_data"),
                    QueueName = queue,
                    Size      = txs.ForColumnType <IntColumn>().Get("bookmark_size")
                };

                switch (actions.GetMessageStatus(bookmark))
                {
                case MessageStatus.SubqueueChanged:
                case MessageStatus.EnqueueWait:
                    actions.SetMessageStatus(bookmark, MessageStatus.ReadyToDeliver);
                    break;

                default:
                    if (configuration.EnableProcessedMessageHistory)
                    {
                        actions.MoveToHistory(bookmark);
                    }
                    else
                    {
                        actions.Delete(bookmark);
                    }
                    break;
                }

                txs.Delete();
            }
        }
Пример #16
0
 public MessageStatus GetMessageStatus(MessageBookmark bookmark)
 {
     _messages.MoveTo(bookmark);
     return((MessageStatus)_messages.ForColumnType <IntColumn>().Get("status"));
 }
Пример #17
0
 public void Delete(MessageBookmark bookmark)
 {
     _messages.MoveTo(bookmark);
     _messages.Delete();
 }
Пример #18
0
 public void Discard(MessageBookmark bookmark)
 {
     Delete(bookmark);
 }
Пример #19
0
 public void DeleteMessageToSendHistoric(MessageBookmark bookmark)
 {
     outgoingHistory.MoveTo(bookmark);
     outgoingHistory.Delete();
 }
Пример #20
0
 public void DeleteHistoric(MessageBookmark bookmark)
 {
     _messageHistory.MoveTo(bookmark);
     _messageHistory.Delete();
 }
Пример #21
0
 public void MoveTo(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(_session, _table, bookmark.Bookmark, bookmark.Size);
 }