Beispiel #1
0
        public IEnumerable <PersistentMessageToSend> GetMessagesToSend()
        {
            Api.MoveBeforeFirst(session, outgoing);

            while (Api.TryMoveNext(session, outgoing))
            {
                var address = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["address"]);
                var port    = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["port"]).Value;

                var bookmark = new MessageBookmark();
                Api.JetGetBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                yield return(new PersistentMessageToSend
                {
                    Id = new MessageId
                    {
                        SourceInstanceId = instanceId,
                        MessageIdentifier = new Guid(Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]))
                    },
                    OutgoingStatus = (OutgoingMessageStatus)Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"]).Value,
                    Endpoint = new Endpoint(address, port),
                    Queue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["queue"], Encoding.Unicode),
                    SubQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["subqueue"], Encoding.Unicode),
                    SentAt = DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["sent_at"]).Value),
                    Data = Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["data"]),
                    Bookmark = bookmark
                });
            }
        }
Beispiel #2
0
        public Guid RegisterToSend(Endpoint destination, string queue, string subQueue, MessagePayload payload, Guid transactionId)
        {
            var bookmark = new MessageBookmark();
            var msgId    = GuidCombGenerator.Generate();

            using (var update = new Update(session, outgoing, JET_prep.Insert))
            {
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"], msgId.ToByteArray());
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["tx_id"], transactionId.ToByteArray());
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["address"], destination.Host, Encoding.Unicode);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["port"], destination.Port);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["time_to_send"], DateTime.Now.ToOADate());
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["sent_at"], DateTime.Now.ToOADate());
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"], (int)OutgoingMessageStatus.NotReady);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["queue"], queue, Encoding.Unicode);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["subqueue"], subQueue, Encoding.Unicode);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["headers"], payload.Headers.ToQueryString(),
                              Encoding.Unicode);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["data"], payload.Data);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"], 1);
                Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["size_of_data"], payload.Data.Length);

                update.Save(bookmark.Bookmark, bookmark.Size, out bookmark.Size);
            }
            Api.JetGotoBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size);
            logger.DebugFormat("Created output message '{0}' for 'rhino.queues://{1}:{2}/{3}/{4}' as NotReady",
                               msgId,
                               destination.Host,
                               destination.Port,
                               queue,
                               subQueue
                               );
            return(msgId);
        }
Beispiel #3
0
        public void MarkOutgoingMessageAsFailedTransmission(MessageBookmark bookmark, bool queueDoesNotExistsInDestination)
        {
            Api.JetGotoBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size);
            var numOfRetries = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"]).Value;
            var msgId        = new Guid(Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]));

            if (numOfRetries < 100 && queueDoesNotExistsInDestination == false)
            {
                using (var update = new Update(session, outgoing, JET_prep.Replace))
                {
                    var timeToSend = DateTime.Now.AddSeconds(numOfRetries * numOfRetries);


                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"], (int)OutgoingMessageStatus.Ready);
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["time_to_send"],
                                  timeToSend.ToOADate());
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"],
                                  numOfRetries + 1);

                    logger.DebugFormat("Marking outgoing message {0} as failed with retries: {1}",
                                       msgId, numOfRetries);

                    update.Save();
                }
            }
            else
            {
                MoveFailedMessageToOutgoingHistory(numOfRetries, msgId);
            }
        }
Beispiel #4
0
        public void RegisterUpdateToReverse(Guid txId, MessageBookmark bookmark, MessageStatus statusToRestore, string subQueue)
        {
            Api.JetSetCurrentIndex(session, txs, "by_bookmark");

            var actualBookmark = bookmark.Bookmark.Take(bookmark.Size).ToArray();

            Api.MakeKey(session, txs, bookmark.Size, MakeKeyGrbit.NewKey);
            Api.MakeKey(session, txs, actualBookmark, MakeKeyGrbit.None);

            if (Api.TrySeek(session, txs, SeekGrbit.SeekEQ))
            {
                Api.JetDelete(session, txs);
            }

            using (var update = new Update(session, txs, JET_prep.Insert))
            {
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["tx_id"], txId.ToByteArray());
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["bookmark_size"], bookmark.Size);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["bookmark_data"], actualBookmark);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["value_to_restore"], (int)statusToRestore);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["queue"], bookmark.QueueName, Encoding.Unicode);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["subqueue"], subQueue, Encoding.Unicode);

                update.Save();
            }
        }
Beispiel #5
0
        public void RemoveReversalsMoveCompletedMessagesAndFinishSubQueueMove(Guid transactionId)
        {
            Api.JetSetCurrentIndex(session, txs, "by_tx_id");
            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);

            if (Api.TrySeek(session, txs, SeekGrbit.SeekEQ) == false)
            {
                return;
            }
            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);
            try
            {
                Api.JetSetIndexRange(session, txs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                {
                    throw;
                }
                return;
            }

            do
            {
                var queue        = Api.RetrieveColumnAsString(session, txs, ColumnsInformation.TxsColumns["queue"], Encoding.Unicode);
                var bookmarkData = Api.RetrieveColumn(session, txs, ColumnsInformation.TxsColumns["bookmark_data"]);
                var bookmarkSize = Api.RetrieveColumnAsInt32(session, txs, ColumnsInformation.TxsColumns["bookmark_size"]).Value;

                var actions = GetQueue(queue);

                var bookmark = new MessageBookmark
                {
                    Bookmark  = bookmarkData,
                    QueueName = queue,
                    Size      = bookmarkSize
                };

                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;
                }

                Api.JetDelete(session, txs);
            } while (Api.TryMoveNext(session, txs));
        }
Beispiel #6
0
 public IEnumerable <HistoryMessage> GetAllProcessedMessages()
 {
     Api.MoveBeforeFirst(session, msgsHistory);
     while (Api.TryMoveNext(session, msgsHistory))
     {
         var bookmark = new MessageBookmark {
             QueueName = queueName
         };
         Api.JetGetBookmark(session, msgsHistory, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
         var headersAsQueryString = Api.RetrieveColumnAsString(session, msgsHistory,
                                                               msgsHistoryColumns["headers"]);
         yield return(new HistoryMessage
         {
             Bookmark = bookmark,
             Headers = HttpUtility.ParseQueryString(headersAsQueryString),
             Queue = queueName,
             MovedToHistoryAt =
                 DateTime.FromOADate(
                     Api.RetrieveColumnAsDouble(session, msgsHistory, msgsHistoryColumns["moved_to_history_at"]).
                     Value),
             Status =
                 (MessageStatus)
                 Api.RetrieveColumnAsInt32(session, msgsHistory, msgsHistoryColumns["status"]).Value,
             SentAt =
                 DateTime.FromOADate(
                     Api.RetrieveColumnAsDouble(session, msgsHistory, msgsHistoryColumns["timestamp"]).Value),
             Data = Api.RetrieveColumn(session, msgsHistory, msgsHistoryColumns["data"]),
             Id = new MessageId
             {
                 MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgsHistory, msgsHistoryColumns["msg_id"])),
                 SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgsHistory, msgsHistoryColumns["instance_id"]))
             }
         });
     }
 }
Beispiel #7
0
        public IEnumerable<PersistentMessageToSend> GetMessagesToSend()
        {
            Api.MoveBeforeFirst(session, outgoing);

            while (Api.TryMoveNext(session, outgoing))
            {
                var address = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["address"]);
                var port = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["port"]).Value;

                var bookmark = new MessageBookmark();
                Api.JetGetBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                yield return new PersistentMessageToSend
                {
                    Id = new MessageId
                    {
                        SourceInstanceId = instanceId,
                        MessageIdentifier = new Guid(Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]))
                    },
                    OutgoingStatus = (OutgoingMessageStatus)Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"]).Value,
                    Endpoint = new Endpoint(address, port),
                    Queue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["queue"], Encoding.Unicode),
                    SubQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["subqueue"], Encoding.Unicode),
                    Priority = Api.RetrieveColumnAsInt16(session, outgoing, ColumnsInformation.OutgoingColumns["priority"]).Value,
                    SentAt = DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["sent_at"]).Value),
                    Data = Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["data"]),
                    Bookmark = bookmark
                };
            }
        }
Beispiel #8
0
        public PersistentMessage PeekById(MessageId id)
        {
            Api.JetSetCurrentIndex(session, msgs, "by_id");
            Api.MakeKey(session, msgs, id.SourceInstanceId.ToByteArray(), MakeKeyGrbit.NewKey);
            Api.MakeKey(session, msgs, id.MessageIdentifier, MakeKeyGrbit.None);

            if (Api.TrySeek(session, msgs, SeekGrbit.SeekEQ) == false)
            {
                return(null);
            }

            Api.MakeKey(session, msgs, id.SourceInstanceId.ToByteArray(), MakeKeyGrbit.NewKey);
            Api.MakeKey(session, msgs, id.MessageIdentifier, MakeKeyGrbit.None);
            try
            {
                Api.JetSetIndexRange(session, msgs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                {
                    throw;
                }
                return(null);
            }

            do
            {
                var bookmark = new MessageBookmark();
                Api.JetGetBookmark(session, msgs, bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                var headersAsQueryString = Api.RetrieveColumnAsString(session, msgs, msgsColumns["headers"]);
                var subqueue             = Api.RetrieveColumnAsString(session, msgs, msgsColumns["subqueue"]);

                var status = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value;

                if (status != MessageStatus.ReadyToDeliver)
                {
                    continue;
                }

                return(new PersistentMessage
                {
                    Bookmark = bookmark,
                    Headers = HttpUtility.ParseQueryString(headersAsQueryString),
                    Queue = queueName,
                    SentAt =
                        DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, msgs, msgsColumns["timestamp"]).Value),
                    Data = Api.RetrieveColumn(session, msgs, msgsColumns["data"]),
                    Id = id,
                    SubQueue = subqueue,
                    Status = status
                });
            } while (Api.TryMoveNext(session, msgs));

            return(null);
        }
Beispiel #9
0
        public void ReverseAllFrom(Guid transactionId)
        {
            Api.JetSetCurrentIndex(session, txs, "by_tx_id");
            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);

            if (Api.TrySeek(session, txs, SeekGrbit.SeekEQ) == false)
            {
                return;
            }

            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);
            try
            {
                Api.JetSetIndexRange(session, txs, SetIndexRangeGrbit.RangeUpperLimit | SetIndexRangeGrbit.RangeInclusive);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                {
                    throw;
                }
                return;
            }

            do
            {
                var bytes     = Api.RetrieveColumn(session, txs, ColumnsInformation.TxsColumns["bookmark_data"]);
                var size      = Api.RetrieveColumnAsInt32(session, txs, ColumnsInformation.TxsColumns["bookmark_size"]).Value;
                var oldStatus = (MessageStatus)Api.RetrieveColumnAsInt32(session, txs, ColumnsInformation.TxsColumns["value_to_restore"]).Value;
                var queue     = Api.RetrieveColumnAsString(session, txs, ColumnsInformation.TxsColumns["queue"]);
                var subqueue  = Api.RetrieveColumnAsString(session, txs, ColumnsInformation.TxsColumns["subqueue"]);

                var bookmark = new MessageBookmark
                {
                    QueueName = queue,
                    Bookmark  = bytes,
                    Size      = 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;
                }
            } while (Api.TryMoveNext(session, txs));
        }
Beispiel #10
0
 public IEnumerable <PersistentMessage> GetAllMessages(string subQueue)
 {
     Api.JetSetCurrentIndex(session, msgs, "by_sub_queue");
     Api.MakeKey(session, msgs, subQueue, Encoding.Unicode, MakeKeyGrbit.NewKey);
     if (Api.TrySeek(session, msgs, SeekGrbit.SeekGE) == false)
     {
         yield break;
     }
     Api.MakeKey(session, msgs, subQueue, Encoding.Unicode, MakeKeyGrbit.NewKey | MakeKeyGrbit.FullColumnEndLimit);
     try
     {
         Api.JetSetIndexRange(session, msgs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
     }
     catch (EsentErrorException e)
     {
         if (e.Error != JET_err.NoCurrentRecord)
         {
             throw;
         }
         yield break;
     }
     do
     {
         var bookmark = new MessageBookmark {
             QueueName = queueName
         };
         Api.JetGetBookmark(session, msgs, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
         var headersAsQueryString = Api.RetrieveColumnAsString(session, msgs, msgsColumns["headers"]);
         yield return(new PersistentMessage
         {
             Bookmark = bookmark,
             Headers = HttpUtility.ParseQueryString(headersAsQueryString),
             Queue = queueName,
             Status = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value,
             SentAt =
                 DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, msgs, msgsColumns["timestamp"]).Value),
             Data = Api.RetrieveColumn(session, msgs, msgsColumns["data"]),
             SubQueue = subQueue,
             Id = new MessageId
             {
                 MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                 SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
             }
         });
     } while (Api.TryMoveNext(session, msgs));
 }
Beispiel #11
0
        public void SetMessageStatus(MessageBookmark bookmark, MessageStatus status, string subqueue)
        {
            Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);
            var id = new MessageId
            {
                MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                SourceInstanceId  = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
            };

            using (var update = new Update(session, msgs, JET_prep.Replace))
            {
                Api.SetColumn(session, msgs, msgsColumns["status"], (int)status);
                Api.SetColumn(session, msgs, msgsColumns["subqueue"], subqueue, Encoding.Unicode);
                update.Save();
            }
            logger.DebugFormat("Changing message {0} status to {1} on queue '{2}' and set subqueue to '{3}'",
                               id, status, queueName, subqueue);
        }
Beispiel #12
0
        public MessageBookmark GetSentMessageBookmarkAtPosition(int positionFromNewestSentMessage)
        {
            Api.MoveAfterLast(session, outgoingHistory);
            try
            {
                Api.JetMove(session, outgoingHistory, -positionFromNewestSentMessage, MoveGrbit.None);
            }
            catch (EsentErrorException e)
            {
                if (e.Error == JET_err.NoCurrentRecord)
                {
                    return(null);
                }
                throw;
            }

            var bookmark = new MessageBookmark();

            Api.JetGetBookmark(session, outgoingHistory, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
            return(bookmark);
        }
Beispiel #13
0
        public MessageBookmark Enqueue(Message message)
        {
            var bm = new MessageBookmark {
                QueueName = queueName
            };

            using (var updateMsgs = new Update(session, msgs, JET_prep.Insert))
            {
                var messageStatus     = MessageStatus.InTransit;
                var persistentMessage = message as PersistentMessage;
                if (persistentMessage != null)
                {
                    messageStatus = persistentMessage.Status;
                }

                Api.SetColumn(session, msgs, msgsColumns["timestamp"], message.SentAt.ToOADate());
                Api.SetColumn(session, msgs, msgsColumns["data"], message.Data);
                Api.SetColumn(session, msgs, msgsColumns["instance_id"], message.Id.SourceInstanceId.ToByteArray());
                Api.SetColumn(session, msgs, msgsColumns["msg_id"], message.Id.MessageIdentifier.ToByteArray());
                Api.SetColumn(session, msgs, msgsColumns["subqueue"], message.SubQueue, Encoding.Unicode);
                Api.SetColumn(session, msgs, msgsColumns["headers"], message.Headers.ToQueryString(), Encoding.Unicode);
                Api.SetColumn(session, msgs, msgsColumns["status"], (int)messageStatus);

                updateMsgs.Save(bm.Bookmark, bm.Size, out bm.Size);
            }
            if (string.IsNullOrEmpty(message.SubQueue) == false &&
                Subqueues.Contains(message.SubQueue) == false)
            {
                actions.AddSubqueueTo(queueName, message.SubQueue);
                subqueues = subqueues.Union(new[] { message.SubQueue }).ToArray();
            }

            logger.DebugFormat("Enqueuing msg to '{0}' with subqueue: '{1}'. Id: {2}", queueName,
                               message.SubQueue,
                               message.Id);
            changeNumberOfMessages(1);
            return(bm);
        }
Beispiel #14
0
        public MessageBookmark MarkOutgoingMessageAsSuccessfullySent(MessageBookmark bookmark)
        {
            Api.JetGotoBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size);
            var newBookmark = new MessageBookmark();

            using (var update = new Update(session, outgoingHistory, JET_prep.Insert))
            {
                foreach (var column in ColumnsInformation.OutgoingColumns.Keys)
                {
                    var bytes = Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns[column]);
                    Api.SetColumn(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns[column], bytes);
                }
                Api.SetColumn(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns["send_status"],
                              (int)OutgoingMessageStatus.Sent);

                update.Save(newBookmark.Bookmark, newBookmark.Size, out newBookmark.Size);
            }
            var msgId = new Guid(Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]));

            Api.JetDelete(session, outgoing);
            logger.DebugFormat("Successfully sent output message {0}", msgId);
            return(newBookmark);
        }
Beispiel #15
0
        public MessageBookmark MoveTo(string subQueue, PersistentMessage message)
        {
            Api.JetGotoBookmark(session, msgs, message.Bookmark.Bookmark, message.Bookmark.Size);
            var id = new MessageId
            {
                MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                SourceInstanceId  = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
            };

            using (var update = new Update(session, msgs, JET_prep.Replace))
            {
                Api.SetColumn(session, msgs, msgsColumns["status"], (int)MessageStatus.SubqueueChanged);
                Api.SetColumn(session, msgs, msgsColumns["subqueue"], subQueue, Encoding.Unicode);

                var bookmark = new MessageBookmark {
                    QueueName = queueName
                };
                update.Save(bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                logger.DebugFormat("Moving message {0} to subqueue {1}",
                                   id, queueName);
                return(bookmark);
            }
        }
Beispiel #16
0
        public void MoveToHistory(MessageBookmark bookmark)
        {
            Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);
            var id = new MessageId
            {
                MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                SourceInstanceId  = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
            };

            using (var update = new Update(session, msgsHistory, JET_prep.Insert))
            {
                foreach (var column in msgsColumns.Keys)
                {
                    Api.SetColumn(session, msgsHistory, msgsHistoryColumns[column],
                                  Api.RetrieveColumn(session, msgs, msgsColumns[column]));
                }
                Api.SetColumn(session, msgsHistory, msgsHistoryColumns["moved_to_history_at"],
                              DateTime.Now.ToOADate());
                update.Save();
            }
            Api.JetDelete(session, msgs);
            logger.DebugFormat("Moving message {0} on queue {1} to history",
                               id, queueName);
        }
Beispiel #17
0
        public void RegisterUpdateToReverse(Guid txId, MessageBookmark bookmark, MessageStatus statusToRestore, string subQueue)
        {
            using (var update = new Update(session, txs, JET_prep.Insert))
            {
                Api.SetColumn(session, txs, txsColumns["tx_id"], txId.ToByteArray());
                Api.SetColumn(session, txs, txsColumns["bookmark_size"], bookmark.Size);
                Api.SetColumn(session, txs, txsColumns["bookmark_data"], bookmark.Bookmark.Take(bookmark.Size).ToArray());
                Api.SetColumn(session, txs, txsColumns["value_to_restore"], (int)statusToRestore);
                Api.SetColumn(session, txs, txsColumns["queue"], bookmark.QueueName, Encoding.Unicode);
                Api.SetColumn(session, txs, txsColumns["subqueue"], subQueue, Encoding.Unicode);

                update.Save();
            }
        }
Beispiel #18
0
        public Guid RegisterToSend(Endpoint destination, string queue, string subQueue, MessagePayload payload, Guid transactionId)
        {
            var bookmark = new MessageBookmark();
            var msgId = GuidCombGenerator.Generate();
            using (var update = new Update(session, outgoing, JET_prep.Insert))
            {
                Api.SetColumn(session, outgoing, outgoingColumns["msg_id"], msgId.ToByteArray());
                Api.SetColumn(session, outgoing, outgoingColumns["tx_id"], transactionId.ToByteArray());
                Api.SetColumn(session, outgoing, outgoingColumns["address"], destination.Host, Encoding.Unicode);
                Api.SetColumn(session, outgoing, outgoingColumns["port"], destination.Port);
                Api.SetColumn(session, outgoing, outgoingColumns["time_to_send"], DateTime.Now.ToOADate());
                Api.SetColumn(session, outgoing, outgoingColumns["sent_at"], DateTime.Now.ToOADate());
                Api.SetColumn(session, outgoing, outgoingColumns["send_status"], (int)OutgoingMessageStatus.NotReady);
                Api.SetColumn(session, outgoing, outgoingColumns["queue"], queue, Encoding.Unicode);
                Api.SetColumn(session, outgoing, outgoingColumns["subqueue"], subQueue, Encoding.Unicode);
                Api.SetColumn(session, outgoing, outgoingColumns["headers"], payload.Headers.ToQueryString(),
                              Encoding.Unicode);
                Api.SetColumn(session, outgoing, outgoingColumns["data"], payload.Data);
                Api.SetColumn(session, outgoing, outgoingColumns["number_of_retries"], 1);
                Api.SetColumn(session, outgoing, outgoingColumns["size_of_data"], payload.Data.Length);

                update.Save(bookmark.Bookmark, bookmark.Size, out bookmark.Size);
            }
            Api.JetGotoBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size);
            logger.DebugFormat("Created output message '{0}' for 'rhino.queues://{1}:{2}/{3}/{4}' as NotReady",
                msgId,
                destination.Host,
                destination.Port,
                queue,
                subQueue
                );
            return msgId;
        }
Beispiel #19
0
        public PersistentMessage Dequeue(string subqueue)
        {
            Api.JetSetCurrentIndex(session, msgs, "by_sub_queue");
            Api.MakeKey(session, msgs, subqueue, Encoding.Unicode, MakeKeyGrbit.NewKey);

            if (Api.TrySeek(session, msgs, SeekGrbit.SeekGE) == false)
                return null;

            Api.MakeKey(session, msgs, subqueue, Encoding.Unicode, MakeKeyGrbit.NewKey | MakeKeyGrbit.FullColumnEndLimit);
            try
            {
                Api.JetSetIndexRange(session, msgs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                    throw;
                return null;
            }

            do
            {
                var id = new MessageId
                {
                    MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                    SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
                };

                var status = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value;

                logger.DebugFormat("Scanning incoming message {2} on '{0}/{1}' with status {3}",
                    queueName, subqueue, id, status);

                if (status != MessageStatus.ReadyToDeliver)
                    continue;

                try
                {
                    using (var update = new Update(session, msgs, JET_prep.Replace))
                    {
                        Api.SetColumn(session, msgs, msgsColumns["status"], (int)MessageStatus.Processing);
                        update.Save();
                    }
                }
                catch (EsentErrorException e)
                {
                    logger.DebugFormat("Write conflict on '{0}/{1}' for {2}, skipping message",
                                       queueName, subqueue, id);
                    if (e.Error == JET_err.WriteConflict)
                        continue;
                    throw;
                }
                var bookmark = new MessageBookmark { QueueName = queueName };
                Api.JetGetBookmark(session, msgs, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
                changeNumberOfMessages(-1);

                logger.DebugFormat("Dequeuing message {2} from '{0}/{1}'",
                                   queueName, subqueue, id);

                var headersAsQueryString = Api.RetrieveColumnAsString(session, msgs, msgsColumns["headers"]);

                var message = new PersistentMessage
                {
                    Bookmark = bookmark,
                    Headers = HttpUtility.ParseQueryString(headersAsQueryString),
                    Queue = queueName,
                    SentAt = DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, msgs, msgsColumns["timestamp"]).Value),
                    Data = Api.RetrieveColumn(session, msgs, msgsColumns["data"]),
                    Id = id,
                    SubQueue = subqueue,
                    Status = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value
                };
                return message;
            } while (Api.TryMoveNext(session, msgs));

            return null;
        }
Beispiel #20
0
        public MessageBookmark MarkOutgoingMessageAsSuccessfullySent(MessageBookmark bookmark)
        {
            Api.JetGotoBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size);
            var newBookmark = new MessageBookmark();
            using (var update = new Update(session, outgoingHistory, JET_prep.Insert))
            {
                foreach (var column in ColumnsInformation.OutgoingColumns.Keys)
                {
                    var bytes = Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns[column]);
                    Api.SetColumn(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns[column], bytes);
                }
                Api.SetColumn(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns["send_status"],
                              (int)OutgoingMessageStatus.Sent);

                update.Save(newBookmark.Bookmark, newBookmark.Size, out newBookmark.Size);
            }
            var msgId = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]).Value;
            Api.JetDelete(session, outgoing);
            logger.DebugFormat("Successfully sent output message {0}", msgId);
            return newBookmark;
        }
Beispiel #21
0
        public IList<PersistentMessage> GetMessagesToSendAndMarkThemAsInFlight(int maxNumberOfMessage, int maxSizeOfMessagesInTotal, out Endpoint endPoint)
        {
            Api.MoveBeforeFirst(session, outgoing);

            endPoint = null;
            string queue = null;
            var messages = new List<PersistentMessage>();

            while (Api.TryMoveNext(session, outgoing))
            {
                var msgId = new Guid(Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]));
                var value = (OutgoingMessageStatus)Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"]).Value;
                var timeAsDate = Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["time_to_send"]).Value;
                var time = DateTime.FromOADate(timeAsDate);

                logger.DebugFormat("Scanning message {0} with status {1} to be sent at {2}", msgId, value, time);
                if (value != OutgoingMessageStatus.Ready)
                    continue;

                // Check if the message has expired, and move it to the outgoing history.
                var deliverBy = Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["deliver_by"]);
                if (deliverBy != null)
                {
                    var deliverByTime = DateTime.FromOADate(deliverBy.Value);
                    if (deliverByTime < DateTime.Now)
                    {
                        logger.InfoFormat("Outgoing message {0} was not succesfully sent by its delivery time limit {1}", msgId, deliverByTime);
                        var numOfRetries = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"]).Value;
                        MoveFailedMessageToOutgoingHistory(numOfRetries, msgId);
                        continue;
                    }
                }

                var maxAttempts = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["max_attempts"]);
                if (maxAttempts != null)
                {
                    var numOfRetries = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"]).Value;
                    if (numOfRetries > maxAttempts)
                    {
                        logger.InfoFormat("Outgoing message {0} has reached its max attempts of {1}", msgId, maxAttempts);
                        MoveFailedMessageToOutgoingHistory(numOfRetries, msgId);
                        continue;
                    }
                }

                if (time > DateTime.Now)
                    continue;

                var rowEndpoint = new Endpoint(
                    Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["address"]),
                    Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["port"]).Value
                    );

                if (endPoint == null)
                    endPoint = rowEndpoint;

                if (endPoint.Equals(rowEndpoint) == false)
                    continue;

                var rowQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["queue"], Encoding.Unicode);

                if (queue == null)
                    queue = rowQueue;

                if(queue != rowQueue)
                    continue;

                var bookmark = new MessageBookmark();
                Api.JetGetBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                logger.DebugFormat("Adding message {0} to returned messages", msgId);
                var headerAsQueryString = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["headers"],Encoding.Unicode);
                messages.Add(new PersistentMessage
                {
                    Id = new MessageId
                    {
                        SourceInstanceId = instanceId,
                        MessageIdentifier = msgId
                    },
                    Headers = HttpUtility.ParseQueryString(headerAsQueryString),
                    Queue = rowQueue,
                    SubQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["subqueue"], Encoding.Unicode),
                    SentAt = DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["sent_at"]).Value),
                    Data = Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["data"]),
                    Bookmark = bookmark
                });

                using (var update = new Update(session, outgoing, JET_prep.Replace))
                {
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"],
                                  (int)OutgoingMessageStatus.InFlight);
                    update.Save();
                }

                logger.DebugFormat("Marking output message {0} as InFlight", msgId);

                if (maxNumberOfMessage < messages.Count)
                    break;
                if (maxSizeOfMessagesInTotal < messages.Sum(x => x.Data.Length))
                    break;
            }
            return messages;
        }
Beispiel #22
0
 public void DeleteMessageToSendHistoric(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, outgoingHistory, bookmark.Bookmark, bookmark.Size);
     Api.JetDelete(session, outgoingHistory);
 }
Beispiel #23
0
        public IList <PersistentMessage> GetMessagesToSendAndMarkThemAsInFlight(int maxNumberOfMessage, int maxSizeOfMessagesInTotal, out Endpoint endPoint)
        {
            Api.MoveBeforeFirst(session, outgoing);

            endPoint = null;
            string queue    = null;
            var    messages = new List <PersistentMessage>();

            while (Api.TryMoveNext(session, outgoing))
            {
                var msgId      = new Guid(Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]));
                var value      = (OutgoingMessageStatus)Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"]).Value;
                var timeAsDate = Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["time_to_send"]).Value;
                var time       = DateTime.FromOADate(timeAsDate);

                logger.DebugFormat("Scanning message {0} with status {1} to be sent at {2}", msgId, value, time);
                if (value != OutgoingMessageStatus.Ready)
                {
                    continue;
                }

                // Check if the message has expired, and move it to the outgoing history.
                var deliverBy = Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["deliver_by"]);
                if (deliverBy != null)
                {
                    var deliverByTime = DateTime.FromOADate(deliverBy.Value);
                    if (deliverByTime < DateTime.Now)
                    {
                        logger.InfoFormat("Outgoing message {0} was not succesfully sent by its delivery time limit {1}", msgId, deliverByTime);
                        var numOfRetries = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"]).Value;
                        MoveFailedMessageToOutgoingHistory(numOfRetries, msgId);
                        continue;
                    }
                }

                var maxAttempts = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["max_attempts"]);
                if (maxAttempts != null)
                {
                    var numOfRetries = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"]).Value;
                    if (numOfRetries > maxAttempts)
                    {
                        logger.InfoFormat("Outgoing message {0} has reached its max attempts of {1}", msgId, maxAttempts);
                        MoveFailedMessageToOutgoingHistory(numOfRetries, msgId);
                        continue;
                    }
                }

                if (time > DateTime.Now)
                {
                    continue;
                }

                var rowEndpoint = new Endpoint(
                    Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["address"]),
                    Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["port"]).Value
                    );

                if (endPoint == null)
                {
                    endPoint = rowEndpoint;
                }

                if (endPoint.Equals(rowEndpoint) == false)
                {
                    continue;
                }

                var rowQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["queue"], Encoding.Unicode);

                if (queue == null)
                {
                    queue = rowQueue;
                }

                if (queue != rowQueue)
                {
                    continue;
                }

                var bookmark = new MessageBookmark();
                Api.JetGetBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                logger.DebugFormat("Adding message {0} to returned messages", msgId);
                var headerAsQueryString = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["headers"], Encoding.Unicode);
                messages.Add(new PersistentMessage
                {
                    Id = new MessageId
                    {
                        SourceInstanceId  = instanceId,
                        MessageIdentifier = msgId
                    },
                    Headers  = HttpUtility.ParseQueryString(headerAsQueryString),
                    Queue    = rowQueue,
                    SubQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["subqueue"], Encoding.Unicode),
                    SentAt   = DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["sent_at"]).Value),
                    Data     = Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["data"]),
                    Bookmark = bookmark
                });

                using (var update = new Update(session, outgoing, JET_prep.Replace))
                {
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"],
                                  (int)OutgoingMessageStatus.InFlight);
                    update.Save();
                }

                logger.DebugFormat("Marking output message {0} as InFlight", msgId);

                if (maxNumberOfMessage < messages.Count)
                {
                    break;
                }
                if (maxSizeOfMessagesInTotal < messages.Sum(x => x.Data.Length))
                {
                    break;
                }
            }
            return(messages);
        }
Beispiel #24
0
 public void MoveToHistory(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);
     var id = new MessageId
     {
         MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
         SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
     };
     using (var update = new Update(session, msgsHistory, JET_prep.Insert))
     {
         foreach (var column in msgsColumns.Keys)
         {
             Api.SetColumn(session, msgsHistory, msgsHistoryColumns[column],
                           Api.RetrieveColumn(session, msgs, msgsColumns[column]));
         }
         Api.SetColumn(session, msgsHistory, msgsHistoryColumns["moved_to_history_at"],
             DateTime.Now.ToOADate());
         update.Save();
     }
     Api.JetDelete(session, msgs);
     logger.DebugFormat("Moving message {0} on queue {1} to history",
                        id, queueName);
 }
Beispiel #25
0
        public void MarkOutgoingMessageAsFailedTransmission(MessageBookmark bookmark, bool queueDoesNotExistsInDestination)
        {
            Api.JetGotoBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size);
            var numOfRetries = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"]).Value;
            var msgId = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]).Value;

            if (numOfRetries < 100 && queueDoesNotExistsInDestination == false)
            {
                using (var update = new Update(session, outgoing, JET_prep.Replace))
                {
                    var timeToSend = DateTime.Now.AddSeconds(numOfRetries * numOfRetries);

                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"], (int)OutgoingMessageStatus.Ready);
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["time_to_send"],
                                  timeToSend.ToOADate());
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"],
                                  numOfRetries + 1);

                    logger.DebugFormat("Marking outgoing message {0} as failed with retries: {1}",
                                       msgId, numOfRetries);

                    update.Save();
                }
            }
            else
            {
                using (var update = new Update(session, outgoingHistory, JET_prep.Insert))
                {
                    foreach (var column in ColumnsInformation.OutgoingColumns.Keys)
                    {
                        Api.SetColumn(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns[column],
                            Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns[column])
                            );
                    }
                    Api.SetColumn(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns["send_status"],
                        (int)OutgoingMessageStatus.Failed);

                    logger.DebugFormat("Marking outgoing message {0} as permenantly failed after {1} retries",
                                       msgId, numOfRetries);

                    update.Save();
                }
                Api.JetDelete(session, outgoing);
            }
        }
Beispiel #26
0
 public void DeleteHistoric(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, msgsHistory, bookmark.Bookmark, bookmark.Size);
     Api.JetDelete(session, msgsHistory);
 }
Beispiel #27
0
 public MessageStatus GetMessageStatus(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);
     return((MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value);
 }
Beispiel #28
0
        public MessageBookmark Enqueue(Message message)
        {
            var bm = new MessageBookmark { QueueName = queueName };
            using (var updateMsgs = new Update(session, msgs, JET_prep.Insert))
            {
                var messageStatus = MessageStatus.InTransit;
                var persistentMessage = message as PersistentMessage;
                if (persistentMessage != null)
                    messageStatus = persistentMessage.Status;

                Api.SetColumn(session, msgs, msgsColumns["timestamp"], message.SentAt.ToOADate());
                Api.SetColumn(session, msgs, msgsColumns["data"], message.Data);
                Api.SetColumn(session, msgs, msgsColumns["instance_id"], message.Id.SourceInstanceId.ToByteArray());
                Api.SetColumn(session, msgs, msgsColumns["msg_id"], message.Id.MessageIdentifier.ToByteArray());
                Api.SetColumn(session, msgs, msgsColumns["subqueue"], message.SubQueue, Encoding.Unicode);
                Api.SetColumn(session, msgs, msgsColumns["headers"], message.Headers.ToQueryString(), Encoding.Unicode);
                Api.SetColumn(session, msgs, msgsColumns["status"], (int)messageStatus);

                updateMsgs.Save(bm.Bookmark, bm.Size, out bm.Size);
            }
            if (string.IsNullOrEmpty(message.SubQueue) == false &&
                Subqueues.Contains(message.SubQueue) == false)
            {
                actions.AddSubqueueTo(queueName, message.SubQueue);
                subqueues = subqueues.Union(new[] { message.SubQueue }).ToArray();
            }

            logger.DebugFormat("Enqueuing msg to '{0}' with subqueue: '{1}'. Id: {2}", queueName,
                message.SubQueue,
                message.Id);
            changeNumberOfMessages(1);
            return bm;
        }
Beispiel #29
0
        public IList<PersistentMessage> GetMessagesToSendAndMarkThemAsInFlight(int maxNumberOfMessage, int maxSizeOfMessagesInTotal, out Endpoint endPoint)
        {
            Api.MoveBeforeFirst(session, outgoing);

            endPoint = null;
            string queue = null;
            var messages = new List<PersistentMessage>();

            while (Api.TryMoveNext(session, outgoing))
            {

                var msgId = new Guid(Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]));
                var value = (OutgoingMessageStatus)Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"]).Value;
                var timeAsDate = Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["time_to_send"]).Value;
                var time = DateTime.FromOADate(timeAsDate);

                logger.DebugFormat("Scanning message {0} with status {1} to be sent at {2}", msgId, value, time);
                if (value != OutgoingMessageStatus.Ready)
                    continue;

                if (time > DateTime.Now)
                    continue;

                var rowEndpoint = new Endpoint(
                    Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["address"]),
                    Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["port"]).Value
                    );

                if (endPoint == null)
                    endPoint = rowEndpoint;

                if (endPoint.Equals(rowEndpoint) == false)
                    continue;

                var rowQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["queue"], Encoding.Unicode);

                if (queue == null)
                    queue = rowQueue;

                if(queue != rowQueue)
                    continue;

                logger.DebugFormat("Adding message {0} to returned messages", msgId);

                var bookmark = new MessageBookmark();
                Api.JetGetBookmark(session, outgoing, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
                var headerAsQueryString = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["headers"],Encoding.Unicode);
                messages.Add(new PersistentMessage
                {
                    Id = new MessageId
                    {
                        SourceInstanceId = instanceId,
                        MessageIdentifier = msgId
                    },
                    Headers = HttpUtility.ParseQueryString(headerAsQueryString),
                    Queue = rowQueue,
                    SubQueue = Api.RetrieveColumnAsString(session, outgoing, ColumnsInformation.OutgoingColumns["subqueue"], Encoding.Unicode),
                    Priority = Api.RetrieveColumnAsInt16(session, outgoing, ColumnsInformation.OutgoingColumns["priority"]).Value,
                    SentAt = DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, outgoing, ColumnsInformation.OutgoingColumns["sent_at"]).Value),
                    Data = Api.RetrieveColumn(session, outgoing, ColumnsInformation.OutgoingColumns["data"]),
                    Bookmark = bookmark
                });

                using (var update = new Update(session, outgoing, JET_prep.Replace))
                {
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"],
                                  (int)OutgoingMessageStatus.InFlight);
                    update.Save();
                }

                logger.DebugFormat("Marking output message {0} as InFlight", msgId);

                if (maxNumberOfMessage < messages.Count)
                    break;
                if (maxSizeOfMessagesInTotal < messages.Sum(x => x.Data.Length))
                    break;
            }
            return messages;
        }
Beispiel #30
0
        public void RemoveReversalsMoveCompletedMessagesAndFinishSubQueueMove(Guid transactionId)
        {
            Api.JetSetCurrentIndex(session, txs, "by_tx_id");
            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);

            if (Api.TrySeek(session, txs, SeekGrbit.SeekEQ) == false)
                return;
            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);
            try
            {
                Api.JetSetIndexRange(session, txs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                    throw;
                return;
            }

            do
            {
                var queue = Api.RetrieveColumnAsString(session, txs, txsColumns["queue"], Encoding.Unicode);
                var bookmarkData = Api.RetrieveColumn(session, txs, txsColumns["bookmark_data"]);
                var bookmarkSize = Api.RetrieveColumnAsInt32(session, txs, txsColumns["bookmark_size"]).Value;

                var actions = GetQueue(queue);

                var bookmark = new MessageBookmark
                {
                    Bookmark = bookmarkData,
                    QueueName = queue,
                    Size = bookmarkSize
                };

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

                Api.JetDelete(session, txs);
            } while (Api.TryMoveNext(session, txs));
        }
Beispiel #31
0
        public PersistentMessage PeekById(MessageId id)
        {
            Api.JetSetCurrentIndex(session, msgs, "by_id");
            Api.MakeKey(session, msgs, id.SourceInstanceId.ToByteArray(), MakeKeyGrbit.NewKey);
            Api.MakeKey(session, msgs, id.MessageIdentifier, MakeKeyGrbit.None);

            if (Api.TrySeek(session, msgs, SeekGrbit.SeekEQ) == false)
                return null;

            Api.MakeKey(session, msgs, id.SourceInstanceId.ToByteArray(), MakeKeyGrbit.NewKey);
            Api.MakeKey(session, msgs, id.MessageIdentifier, MakeKeyGrbit.None);
            try
            {
                Api.JetSetIndexRange(session, msgs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                    throw;
                return null;
            }

            do
            {
                var bookmark = new MessageBookmark();
                Api.JetGetBookmark(session, msgs, bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                var headersAsQueryString = Api.RetrieveColumnAsString(session, msgs, msgsColumns["headers"]);
                var subqueue = Api.RetrieveColumnAsString(session, msgs, msgsColumns["subqueue"]);

                var status = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value;

                if (status != MessageStatus.ReadyToDeliver)
                    continue;

                return new PersistentMessage
                {
                    Bookmark = bookmark,
                    Headers = HttpUtility.ParseQueryString(headersAsQueryString),
                    Queue = queueName,
                    SentAt =
                        DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, msgs, msgsColumns["timestamp"]).Value),
                    Data = Api.RetrieveColumn(session, msgs, msgsColumns["data"]),
                    Id = id,
                    SubQueue = subqueue,
                    Status = status
                };
            } while (Api.TryMoveNext(session, msgs));

            return null;
        }
Beispiel #32
0
        public void ReverseAllFrom(Guid transactionId)
        {
            Api.JetSetCurrentIndex(session, txs, "by_tx_id");
            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);

            if (Api.TrySeek(session, txs, SeekGrbit.SeekEQ) == false)
                return;

            Api.MakeKey(session, txs, transactionId.ToByteArray(), MakeKeyGrbit.NewKey);
            try
            {
                Api.JetSetIndexRange(session, txs, SetIndexRangeGrbit.RangeUpperLimit | SetIndexRangeGrbit.RangeInclusive);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                    throw;
                return;
            }

            do
            {
                var bytes = Api.RetrieveColumn(session, txs, txsColumns["bookmark_data"]);
                var size = Api.RetrieveColumnAsInt32(session, txs, txsColumns["bookmark_size"]).Value;
                var oldStatus = (MessageStatus)Api.RetrieveColumnAsInt32(session, txs, txsColumns["value_to_restore"]).Value;
                var queue = Api.RetrieveColumnAsString(session, txs, txsColumns["queue"]);
                var subqueue = Api.RetrieveColumnAsString(session, txs, txsColumns["subqueue"]);

                var bookmark = new MessageBookmark
                {
                    QueueName = queue,
                    Bookmark = bytes,
                    Size = 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;
                }
            } while (Api.TryMoveNext(session, txs));
        }
Beispiel #33
0
        public void SetMessageStatus(MessageBookmark bookmark, MessageStatus status)
        {
            Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);

            var id = new MessageId
            {
                MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
            };

            using (var update = new Update(session, msgs, JET_prep.Replace))
            {
                Api.SetColumn(session, msgs, msgsColumns["status"], (int)status);
                update.Save();
            }

            logger.DebugFormat("Changing message {0} status to {1} on {2}",
                               id, status, queueName);
        }
Beispiel #34
0
 public void DeleteMessageToSendHistoric(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, outgoingHistory, bookmark.Bookmark, bookmark.Size);
     Api.JetDelete(session, outgoingHistory);
 }
Beispiel #35
0
 public void Delete(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);
     Api.JetDelete(session, msgs);
 }
        public void RegisterUpdateToReverse(Guid txId, MessageBookmark bookmark, MessageStatus statusToRestore, string subQueue)
        {
            Api.JetSetCurrentIndex(session, txs, "by_bookmark");

            var actualBookmark = bookmark.Bookmark.Take(bookmark.Size).ToArray();

            Api.MakeKey(session, txs, bookmark.Size, MakeKeyGrbit.NewKey);
            Api.MakeKey(session, txs, actualBookmark, MakeKeyGrbit.None);

            if(Api.TrySeek(session, txs, SeekGrbit.SeekEQ))
            {
                Api.JetDelete(session, txs);
            }

            using (var update = new Update(session, txs, JET_prep.Insert))
            {
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["tx_id"], txId.ToByteArray());
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["bookmark_size"], bookmark.Size);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["bookmark_data"], actualBookmark);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["value_to_restore"], (int)statusToRestore);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["queue"], bookmark.QueueName, Encoding.Unicode);
                Api.SetColumn(session, txs, ColumnsInformation.TxsColumns["subqueue"], subQueue, Encoding.Unicode);

                update.Save();
            }
        }
Beispiel #37
0
 public void DeleteHistoric(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, msgsHistory, bookmark.Bookmark, bookmark.Size);
     Api.JetDelete(session, msgsHistory);
 }
Beispiel #38
0
 public IEnumerable<PersistentMessage> GetAllMessages(string subQueue)
 {
     Api.JetSetCurrentIndex(session, msgs, "by_sub_queue");
     Api.MakeKey(session, msgs, subQueue, Encoding.Unicode, MakeKeyGrbit.NewKey);
     if (Api.TrySeek(session, msgs, SeekGrbit.SeekGE) == false)
         yield break;
     Api.MakeKey(session, msgs, subQueue, Encoding.Unicode, MakeKeyGrbit.NewKey | MakeKeyGrbit.FullColumnEndLimit);
     try
     {
         Api.JetSetIndexRange(session, msgs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
     }
     catch (EsentErrorException e)
     {
         if (e.Error != JET_err.NoCurrentRecord)
             throw;
         yield break;
     }
     do
     {
         var bookmark = new MessageBookmark { QueueName = queueName };
         Api.JetGetBookmark(session, msgs, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
         var headersAsQueryString = Api.RetrieveColumnAsString(session, msgs, msgsColumns["headers"]);
         yield return new PersistentMessage
         {
             Bookmark = bookmark,
             Headers = HttpUtility.ParseQueryString(headersAsQueryString),
             Queue = queueName,
             Status = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value,
             SentAt =
                 DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, msgs, msgsColumns["timestamp"]).Value),
             Data = Api.RetrieveColumn(session, msgs, msgsColumns["data"]),
             SubQueue = subQueue,
             Id = new MessageId
             {
                 MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                 SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
             }
         };
     } while (Api.TryMoveNext(session, msgs));
 }
Beispiel #39
0
        public void RevertBackToSend(MessageBookmark[] bookmarks)
        {
            foreach (var bookmark in bookmarks)
            {
                Api.JetGotoBookmark(session, outgoingHistory, bookmark.Bookmark, bookmark.Size);
                var msgId = Api.RetrieveColumnAsInt32(session, outgoing, ColumnsInformation.OutgoingColumns["msg_id"]).Value;

                using(var update = new  Update(session, outgoing, JET_prep.Insert))
                {
                    foreach (var column in ColumnsInformation.OutgoingColumns.Keys)
                    {
                        Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns[column],
                            Api.RetrieveColumn(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns[column])
                            );
                    }
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["send_status"],
                        (int)OutgoingMessageStatus.Ready);
                    Api.SetColumn(session, outgoing, ColumnsInformation.OutgoingColumns["number_of_retries"],
                        Api.RetrieveColumnAsInt32(session, outgoingHistory, ColumnsInformation.OutgoingHistoryColumns["number_of_retries"]).Value + 1
                           );

                    logger.DebugFormat("Reverting output message {0} back to Ready mode", msgId);

                    update.Save();
                }
            }
        }
Beispiel #40
0
 public IEnumerable<HistoryMessage> GetAllProcessedMessages()
 {
     Api.MoveBeforeFirst(session, msgsHistory);
     while (Api.TryMoveNext(session, msgsHistory))
     {
         var bookmark = new MessageBookmark { QueueName = queueName };
         Api.JetGetBookmark(session, msgsHistory, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
         var headersAsQueryString = Api.RetrieveColumnAsString(session, msgsHistory,
                                                               msgsHistoryColumns["headers"]);
         yield return new HistoryMessage
         {
             Bookmark = bookmark,
             Headers = HttpUtility.ParseQueryString(headersAsQueryString),
             Queue = queueName,
             MovedToHistoryAt =
                 DateTime.FromOADate(
                 Api.RetrieveColumnAsDouble(session, msgsHistory, msgsHistoryColumns["moved_to_history_at"]).
                     Value),
             Status =
                 (MessageStatus)
                 Api.RetrieveColumnAsInt32(session, msgsHistory, msgsHistoryColumns["status"]).Value,
             SentAt =
                 DateTime.FromOADate(
                 Api.RetrieveColumnAsDouble(session, msgsHistory, msgsHistoryColumns["timestamp"]).Value),
             Data = Api.RetrieveColumn(session, msgsHistory, msgsHistoryColumns["data"]),
             Id = new MessageId
             {
                 MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgsHistory, msgsHistoryColumns["msg_id"])),
                 SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgsHistory, msgsHistoryColumns["instance_id"]))
             }
         };
     }
 }
Beispiel #41
0
 public MessageStatus GetMessageStatus(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);
     return (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value;
 }
Beispiel #42
0
 public void Delete(MessageBookmark bookmark)
 {
     Api.JetGotoBookmark(session, msgs, bookmark.Bookmark, bookmark.Size);
     Api.JetDelete(session, msgs);
 }
Beispiel #43
0
        public MessageBookmark MoveTo(string subQueue, PersistentMessage message)
        {
            Api.JetGotoBookmark(session, msgs, message.Bookmark.Bookmark, message.Bookmark.Size);
            var id = new MessageId
            {
                MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                SourceInstanceId = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
            };
            using (var update = new Update(session, msgs, JET_prep.Replace))
            {
                Api.SetColumn(session, msgs, msgsColumns["status"], (int)MessageStatus.SubqueueChanged);
                Api.SetColumn(session, msgs, msgsColumns["subqueue"], subQueue, Encoding.Unicode);

                var bookmark = new MessageBookmark { QueueName = queueName };
                update.Save(bookmark.Bookmark, bookmark.Size, out bookmark.Size);

                logger.DebugFormat("Moving message {0} to subqueue {1}",
                               id, queueName);
                return bookmark;
            }
        }
Beispiel #44
0
        public PersistentMessage Dequeue(string subqueue)
        {
            Api.JetSetCurrentIndex(session, msgs, "by_sub_queue");
            Api.MakeKey(session, msgs, subqueue, Encoding.Unicode, MakeKeyGrbit.NewKey);

            if (Api.TrySeek(session, msgs, SeekGrbit.SeekGE) == false)
            {
                return(null);
            }

            Api.MakeKey(session, msgs, subqueue, Encoding.Unicode, MakeKeyGrbit.NewKey | MakeKeyGrbit.FullColumnEndLimit);
            try
            {
                Api.JetSetIndexRange(session, msgs, SetIndexRangeGrbit.RangeInclusive | SetIndexRangeGrbit.RangeUpperLimit);
            }
            catch (EsentErrorException e)
            {
                if (e.Error != JET_err.NoCurrentRecord)
                {
                    throw;
                }
                return(null);
            }

            do
            {
                var id = new MessageId
                {
                    MessageIdentifier = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["msg_id"])),
                    SourceInstanceId  = new Guid(Api.RetrieveColumn(session, msgs, msgsColumns["instance_id"]))
                };

                var status = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value;

                logger.DebugFormat("Scanning incoming message {2} on '{0}/{1}' with status {3}",
                                   queueName, subqueue, id, status);

                if (status != MessageStatus.ReadyToDeliver)
                {
                    continue;
                }

                try
                {
                    using (var update = new Update(session, msgs, JET_prep.Replace))
                    {
                        Api.SetColumn(session, msgs, msgsColumns["status"], (int)MessageStatus.Processing);
                        update.Save();
                    }
                }
                catch (EsentErrorException e)
                {
                    logger.DebugFormat("Write conflict on '{0}/{1}' for {2}, skipping message",
                                       queueName, subqueue, id);
                    if (e.Error == JET_err.WriteConflict)
                    {
                        continue;
                    }
                    throw;
                }
                var bookmark = new MessageBookmark {
                    QueueName = queueName
                };
                Api.JetGetBookmark(session, msgs, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
                changeNumberOfMessages(-1);

                logger.DebugFormat("Dequeuing message {2} from '{0}/{1}'",
                                   queueName, subqueue, id);

                var headersAsQueryString = Api.RetrieveColumnAsString(session, msgs, msgsColumns["headers"]);

                var message = new PersistentMessage
                {
                    Bookmark = bookmark,
                    Headers  = HttpUtility.ParseQueryString(headersAsQueryString),
                    Queue    = queueName,
                    SentAt   = DateTime.FromOADate(Api.RetrieveColumnAsDouble(session, msgs, msgsColumns["timestamp"]).Value),
                    Data     = Api.RetrieveColumn(session, msgs, msgsColumns["data"]),
                    Id       = id,
                    SubQueue = subqueue,
                    Status   = (MessageStatus)Api.RetrieveColumnAsInt32(session, msgs, msgsColumns["status"]).Value
                };
                return(message);
            } while (Api.TryMoveNext(session, msgs));

            return(null);
        }
        public MessageBookmark GetSentMessageBookmarkAtPosition(int positionFromNewestSentMessage)
        {
            Api.MoveAfterLast(session, outgoingHistory);
            try
            {
                Api.JetMove(session, outgoingHistory, -positionFromNewestSentMessage, MoveGrbit.None);
            }
            catch (EsentErrorException e)
            {
                if (e.Error == JET_err.NoCurrentRecord)
                    return null;
                throw;
            }

            var bookmark = new MessageBookmark();
            Api.JetGetBookmark(session, outgoingHistory, bookmark.Bookmark, bookmark.Size, out bookmark.Size);
            return bookmark;
        }