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 void EnqueueDirectlyTo(string queue, string subqueue, MessagePayload payload) { EnsureEnslistment(); var message = new PersistentMessage { Data = payload.Data, Headers = payload.Headers, Id = new MessageId { SourceInstanceId = queueStorage.Id, MessageIdentifier = GuidCombGenerator.Generate() }, Queue = queue, SentAt = DateTime.Now, SubQueue = subqueue, Status = MessageStatus.EnqueueWait }; queueStorage.Global(actions => { var queueActions = actions.GetQueue(queue); var bookmark = queueActions.Enqueue(message); actions.RegisterUpdateToReverse(Enlistment.Id, bookmark, MessageStatus.EnqueueWait, subqueue); actions.Commit(); }); OnMessageQueuedForReceive(message); lock (newMessageArrivedLock) { Monitor.PulseAll(newMessageArrivedLock); } }
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; } }