public MessageId Send(Uri uri, MessagePayload payload)
        {
            if (waitingForAllMessagesToBeSent)
                throw new CannotSendWhileWaitingForAllMessagesToBeSentException("Currently waiting for all messages to be sent, so we cannot send. You probably have a race condition in your application.");

            EnsureEnslistment();
            var parts = uri.AbsolutePath.Substring(1).Split('/');
            var queue = parts[0];
            string subqueue = null;
            if (parts.Length > 1)
            {
                subqueue = string.Join("/", parts.Skip(1).ToArray());
            }

            Guid msgId = Guid.Empty;

            var port = uri.Port;
            if (port == -1)
                port = 2200;
            var destination = new Endpoint(uri.Host, port);

            queueStorage.Global(actions =>
            {
                msgId = actions.RegisterToSend(destination, queue,
                                               subqueue, payload, Enlistment.Id);

                actions.Commit();
            });

            var messageId = new MessageId
                                {
                                    SourceInstanceId = queueStorage.Id,
                                    MessageIdentifier = msgId
                                };
            var message = new Message
            {
                Id = messageId,
                Data = payload.Data,
                Headers = payload.Headers,
                Queue = queue,
                SubQueue = subqueue
            };

            OnMessageQueuedForSend(new MessageEventArgs(destination, message));

            return messageId;
        }
Beispiel #2
0
        public void MarkReceived(MessageId id)
        {
            using(var update = new Update(session, recveivedMsgs, JET_prep.Insert))
            {
                Api.SetColumn(session, recveivedMsgs, recveivedMsgsColumns["instance_id"], id.SourceInstanceId.ToByteArray());
                Api.SetColumn(session, recveivedMsgs, recveivedMsgsColumns["msg_id"], id.MessageIdentifier.ToByteArray());

                update.Save();
            }
        }
        public PersistentMessage PeekById(string queueName, MessageId id)
        {
            PersistentMessage message = null;
            queueStorage.Global(actions =>
            {
                var queue = actions.GetQueue(queueName);

                message = queue.PeekById(id);

                actions.Commit();
            });
            return message;
        }
Beispiel #4
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 #5
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 #6
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 #7
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 #8
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 #9
0
 public bool Equals(MessageId other)
 {
     if (ReferenceEquals(null, other)) return false;
     if (ReferenceEquals(this, other)) return true;
     return other.SourceInstanceId.Equals(SourceInstanceId) && other.MessageIdentifier.Equals(MessageIdentifier);
 }
Beispiel #10
0
 public Message PeekById(MessageId id)
 {
     return queueManager.PeekById(queueName, id);
 }