예제 #1
0
파일: Topic.cs 프로젝트: sls1j/Gruppo
 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;
     }
 }
예제 #2
0
파일: Topic.cs 프로젝트: sls1j/Gruppo
        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;
            }
        }
예제 #3
0
파일: Topic.cs 프로젝트: sls1j/Gruppo
        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;
            }
        }
예제 #4
0
        public void Peek(string topicName, long offset, out GruppoMessage message)
        {
            message = null;
            Topic topic = GetTopic(topicName);

            if (topic != null)
            {
                topic.Peek(offset, out message);
            }
        }
예제 #5
0
        public void Consume(string topicName, string group, out GruppoMessage message)
        {
            message = null;

            Topic topic = GetTopic(topicName);

            if (topic != null)
            {
                topic.Consume(group, out message);
            }
        }
예제 #6
0
파일: Topic.cs 프로젝트: sls1j/Gruppo
        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);
            }
        }
예제 #7
0
파일: Topic.cs 프로젝트: sls1j/Gruppo
        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);
        }
예제 #8
0
        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);
            }
        }