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; }
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; }
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); }
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 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; }
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); }
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; } }
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); }
public Message PeekById(MessageId id) { return queueManager.PeekById(queueName, id); }