public void Consume(long offset, out GruppoMessage message) { if (_guard.EnterExecute()) { try { using (var index = _fileSystem.OpenIndexReader()) using (var messageReader = _fileSystem.OpenMessageFileReader(offset)) { index.BaseStream.Seek((offset) * sizeof(Int64), SeekOrigin.Begin); long beginOffset = index.ReadInt64(); messageReader.BaseStream.Seek(beginOffset, SeekOrigin.Begin); message = ReadMessage(messageReader, offset, true); } } finally { _guard.ExitExecute(); } } else { message = null; } }
public void Peek(long offset, out GruppoMessage message) { if (_guard.EnterExecute()) { try { using (var index = _fileSystem.OpenIndexReader()) using (var messageReader = _fileSystem.OpenMessageFileReader(offset)) { long position = offset * sizeof(long); if (position > index.BaseStream.Length) { message = null; return; } index.BaseStream.Position = position; long messagePosition = index.ReadInt64(); messageReader.BaseStream.Position = messagePosition; message = ReadMessage(messageReader, offset, false); } } finally { _guard.ExitExecute(); } } else { message = null; } }
public void Consume(string groupName, out GruppoMessage message) { if (_guard.EnterExecute()) { try { Group group; lock (_groupConsumers) { if (!_groupConsumers.TryGetValue(groupName, out group)) { group = CreateGroup(groupName); _groupConsumers.Add(groupName, group); } } lock (group) { // is there a message to read? if (group.IndexReader.BaseStream.Position < group.IndexReader.BaseStream.Length) { // advance the index reader -- this is an atomic way of knowing if we have finished reading a message // writing the index takes one step, writing the message takes several steps and we shouldn't try to read // a message until it's completely written. The index is the last thing written so wait on it. long messagePosition = group.IndexReader.ReadInt64(); // if the offset is zero then a new message file has been reached get it if (messagePosition == 0) { group.MessageReader.Dispose(); group.MessageReader = _fileSystem.OpenMessageFileReader(group.Offset); } // read the message message = ReadMessage(group.MessageReader, group.Offset, true); group.Offset++; // write group index out group.GroupIndexWriter.BaseStream.Position = 0; group.GroupIndexWriter.Write(group.Offset); } else { message = null; } } } finally { _guard.ExitExecute(); } } else { message = null; } }
public void Peek(string topicName, long offset, out GruppoMessage message) { message = null; Topic topic = GetTopic(topicName); if (topic != null) { topic.Peek(offset, out message); } }
public void Consume(string topicName, string group, out GruppoMessage message) { message = null; Topic topic = GetTopic(topicName); if (topic != null) { topic.Consume(group, out message); } }
public bool Produce(GruppoMessage message, out long offset, out DateTime timestamp) { if (_guard.EnterExecute()) { try { lock (this) { // write out the message to the message stream timestamp = DateTime.UtcNow; long beginOffset = _produceMessageWriter.BaseStream.Position; _produceMessageWriter.Write(timestamp.Ticks); _produceMessageWriter.Write(message.Meta ?? string.Empty); if (message.Body == null) { _produceMessageWriter.Write((int)0); } else { _produceMessageWriter.Write(message.Body.Length); _produceMessageWriter.Write(message.Body); } _produceMessageWriter.Flush(); offset = _produceOffset++; // write message start position to the index _produceIndexWriter.Write(beginOffset); _produceIndexWriter.Flush(); } // check to see if the file needs to be rolled if (_produceOffset % _fileSystem.MessageSplitSize == 0) { CreateProduceWriters(); } return(true); } finally { _guard.ExitExecute(); } } else { offset = -1; timestamp = DateTime.MinValue; return(false); } }
private static GruppoMessage ReadMessage(BinaryReader messageReader, long offset, bool readBody) { GruppoMessage message = new GruppoMessage(); message.Offset = offset; message.Timestamp = new DateTime(messageReader.ReadInt64()); message.Meta = messageReader.ReadString(); int length = messageReader.ReadInt32(); if (readBody) { message.Body = messageReader.ReadBytes(length); } return(message); }
public void Produce(string topicName, string meta, byte[] body, out long offset, out DateTime timestamp) { Topic topic = GetTopic(topicName); if (topic == null) { CreateTopic(topicName); topic = GetTopic(topicName); } { GruppoMessage message = new GruppoMessage() { Meta = meta, Body = body }; topic.Produce(message, out offset, out timestamp); } }